@autorender/sdk-core 0.1.21 → 0.1.22

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants/defaults.ts","../src/client/api-client.ts","../src/utils/helpers.ts","../src/core/uploader-controller.ts","../src/widget/styles.ts","../src/widget/uploader-element.ts","../src/viewtag/device.ts","../src/viewtag/format-detection.ts","../src/viewtag/transform.ts","../src/viewtag/url-builder.ts","../src/viewtag/responsive.ts","../src/viewtag/create-ar.ts"],"sourcesContent":["import { AutorenderApiClient } from './client/api-client';\nimport { UploaderController } from './core/uploader-controller';\nimport type { ControllerOptions } from './core/uploader-controller';\nimport { DEFAULT_THEME, DEFAULT_SOURCES, DEFAULT_ASSET_DELIVERY_BASE_URL } from './constants/defaults';\nimport type {\n CreateUploaderOptions,\n UploaderInstance,\n ThemeOptions,\n UploadSourceOption,\n} from './types';\nimport { AutorenderUploaderElement } from './widget/uploader-element';\n\ntype ThemeName = 'light' | 'dark' | 'system';\n\nconst SOURCE_ALIAS_MAP: Record<string, string> = {\n local: 'device',\n device: 'device',\n fromdevice: 'device',\n camera: 'camera',\n facebook: 'facebook',\n fb: 'facebook',\n insta: 'facebook',\n instagram: 'facebook',\n gdrive: 'google-drive',\n googledrive: 'google-drive',\n google: 'google-drive',\n googledisk: 'google-drive',\n 'google-drive': 'google-drive',\n};\n\nfunction ensureCustomElement() {\n if (\n typeof globalThis === 'undefined' ||\n typeof globalThis.customElements === 'undefined'\n ) {\n return;\n }\n if (!globalThis.customElements.get(AutorenderUploaderElement.tagName)) {\n globalThis.customElements.define(\n AutorenderUploaderElement.tagName,\n AutorenderUploaderElement\n );\n }\n}\n\nfunction resolveTarget(target: string | HTMLElement): HTMLElement {\n if (typeof target === 'string') {\n const element = document.querySelector<HTMLElement>(target);\n if (!element) {\n throw new Error(`Target element \"${target}\" not found`);\n }\n return element;\n }\n return target;\n}\n\nfunction resolveContainer(container?: string | HTMLElement): HTMLElement | null {\n if (!container) return null;\n if (typeof container === 'string') {\n const element = document.querySelector<HTMLElement>(container);\n if (!element) {\n throw new Error(`Container element \"${container}\" not found`);\n }\n return element;\n }\n return container;\n}\n\nfunction resolveThemePreset(theme?: ThemeName): ThemeOptions {\n const base = {\n borderRadius: DEFAULT_THEME.borderRadius,\n dropzoneBackground: DEFAULT_THEME.dropzoneBackground,\n dropzoneBorder: DEFAULT_THEME.dropzoneBorder,\n };\n\n switch (theme) {\n case 'dark':\n return {\n appearance: 'dark',\n ...base,\n };\n case 'system':\n return {\n appearance: 'system',\n ...base,\n };\n default:\n return {\n appearance: 'light',\n ...base,\n };\n }\n}\n\nfunction resolveSourcesConfig(input?: string | string[]): UploadSourceOption[] {\n if (input === undefined || input === null) {\n return [];\n }\n\n const provided = Array.isArray(input)\n ? input\n : input\n .split(',')\n .map(entry => entry.trim())\n .filter(Boolean);\n\n if (provided.length === 0) {\n return [];\n }\n\n const resolved: UploadSourceOption[] = [];\n const seen = new Set<string>();\n\n for (const entry of provided) {\n const normalized = entry.toLowerCase().replace(/[\\s_-]+/g, '');\n const mappedId = SOURCE_ALIAS_MAP[normalized] ?? normalized;\n if (seen.has(mappedId)) continue;\n const match = DEFAULT_SOURCES.find(option => option.id === mappedId);\n if (match) {\n resolved.push(match);\n seen.add(mappedId);\n }\n }\n\n return resolved;\n}\n\nfunction normalizeOptions(\n options: Partial<CreateUploaderOptions>,\n applyDefaults = false\n): Partial<ControllerOptions> {\n const {\n type,\n theme,\n sources,\n classNames,\n labels,\n fileLayout,\n showGridFileName,\n apiKey: _apiKey,\n target: _target,\n ...rest\n } = options;\n\n const normalized: any = { ...rest };\n\n if (type !== undefined) {\n normalized.type = type === 'button' ? 'button' : 'inline';\n } else if (applyDefaults) {\n normalized.type = 'inline';\n }\n\n if (theme !== undefined) {\n normalized.theme = resolveThemePreset(theme);\n } else if (applyDefaults) {\n normalized.theme = resolveThemePreset('light');\n }\n\n if (options.palette !== undefined) {\n normalized.palette = options.palette;\n } else if (applyDefaults) {\n normalized.palette = 'at-blue';\n }\n\n if (sources !== undefined) {\n normalized.sources = resolveSourcesConfig(sources);\n } else if ('sources' in options) {\n // Explicitly undefined - means no sources (all disabled)\n normalized.sources = [];\n } else if (applyDefaults) {\n normalized.sources = [];\n }\n\n if (classNames !== undefined) {\n normalized.classNames = classNames;\n }\n\n if (labels !== undefined) {\n normalized.labels = labels;\n }\n\n if (fileLayout !== undefined) {\n normalized.fileLayout = fileLayout;\n } else if (applyDefaults) {\n normalized.fileLayout = 'list';\n }\n\n if (showGridFileName !== undefined) {\n normalized.showGridFileName = showGridFileName;\n } else if (applyDefaults) {\n normalized.showGridFileName = true;\n }\n\n if (options.assetDeliveryBaseUrl !== undefined) {\n normalized.assetDeliveryBaseUrl = options.assetDeliveryBaseUrl;\n } else if (applyDefaults) {\n normalized.assetDeliveryBaseUrl = DEFAULT_ASSET_DELIVERY_BASE_URL;\n }\n\n return normalized;\n}\n\nexport function createUploader(options: CreateUploaderOptions): UploaderInstance {\n // If container is provided, use it as the target so the entire widget renders inside it\n const container = resolveContainer(options.container);\n const defaultTarget = resolveTarget(options.target);\n const resolvedTarget = container || defaultTarget;\n \n ensureCustomElement();\n\n const widget = document.createElement(\n AutorenderUploaderElement.tagName\n ) as AutorenderUploaderElement;\n\n // Clear target and mount widget\n resolvedTarget.innerHTML = '';\n resolvedTarget.appendChild(widget);\n\n const client = new AutorenderApiClient({\n apiKey: options.apiKey,\n environment: options.environment,\n });\n\n const controllerOptions = normalizeOptions(options, true) as ControllerOptions;\n \n // Only set container in options if it's different from target (for portal logic)\n // If container is the same as target, we don't need portal\n if (container && container !== resolvedTarget) {\n controllerOptions.container = container;\n } else {\n // Clear container option if it's the same as target\n controllerOptions.container = undefined;\n }\n\n const controller = new UploaderController(\n client,\n widget,\n controllerOptions\n );\n\n widget.setController(controller, controllerOptions);\n\n return {\n openFileDialog: () => widget.openFileDialog(),\n startUpload: () => controller.uploadAll(),\n reset: () => controller.reset(),\n destroy: () => {\n controller.cancel();\n controller.reset();\n widget.remove();\n },\n updateOptions: (partialOptions: Partial<CreateUploaderOptions>) => {\n const normalized = normalizeOptions(partialOptions, false);\n controller.setOptions(normalized);\n widget.updateOptions(normalized);\n },\n getState: () => controller.getState(),\n };\n}\n\nexport * from './types';\nexport function registerAutorenderUploaderElement() {\n ensureCustomElement();\n}\n\n// ViewTag SDK exports\nexport { createAR } from './viewtag/create-ar';\nexport { detectBestFormat, getBestFormatSync, resetFormatCache } from './viewtag/format-detection';\nexport type {\n CreateARConfig,\n ARInstance,\n TransformOptions,\n ResponsiveOptions,\n ResponsiveAttributes,\n LayerOptions,\n LayerEnhancementOptions\n} from './viewtag/types';\n\n","import type { IconSet, LabelSet, ThemeOptions, UploadSourceOption } from '../types';\n\nexport type Environment = 'prod' | 'dev';\n\nexport function getBaseUrl(environment: Environment = 'prod'): string {\n switch (environment) {\n case 'dev':\n return 'https://upload-dev.autorender.io/api/v1';\n case 'prod':\n default:\n return 'https://upload.autorender.io/api/v1';\n }\n}\n\nexport const DEFAULT_BASE_URL = getBaseUrl('prod');\n\nexport const DEFAULT_ASSET_DELIVERY_BASE_URL = 'https://dev.autorender.io';\n\n\nexport const DEFAULT_LABELS: Required<LabelSet> = {\n title: 'Upload files',\n description: 'Drag & drop files or click to browse.',\n selectButton: 'Upload files',\n selectFolderButton: 'Upload folder',\n uploadButton: 'Upload',\n uploading: 'Uploading...',\n uploadComplete: 'All files uploaded successfully.',\n uploadFailed: 'Unable to upload files. Please try again.',\n retry: 'Retry',\n remove: 'Remove',\n addMore: 'Add more',\n done: 'Done',\n clear: 'Clear',\n cancel: 'Cancel',\n dropzoneTitle: 'Drop files here',\n duplicateFileExists: 'The following file already exists in this folder:',\n duplicateFilesExist: 'The following files already exist in this folder:',\n duplicateFileError: 'File already exists in this folder.',\n invalidApiKey: 'Invalid API key. Please verify your credentials and try again.',\n};\n\nexport const DEFAULT_ICONS: Required<IconSet> = {\n upload: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M12 16a1 1 0 0 1-1-1V7.41l-2.3 2.3a1 1 0 1 1-1.4-1.42l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.42L13 7.41V15a1 1 0 0 1-1 1Z\" />\n <path d=\"M5 20a3 3 0 0 1-3-3v-1a1 1 0 0 1 2 0v1a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-1a1 1 0 1 1 2 0v1a3 3 0 0 1-3 3Z\" />\n </svg>\n `,\n success: `\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M9.5 17a1 1 0 0 1-.7-.29l-3.5-3.5a1 1 0 1 1 1.4-1.42l2.8 2.79 7.1-7.09a1 1 0 0 1 1.4 1.42l-7.8 7.79a1 1 0 0 1-.7.3Z\" fill=\"currentColor\" />\n </svg>\n `,\n error: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" >\n <path d=\"m12 13.41 3.29 3.3a1 1 0 0 0 1.42-1.42L13.41 12l3.3-3.29a1 1 0 0 0-1.42-1.42L12 10.59l-3.29-3.3a1 1 0 1 0-1.42 1.42L10.59 12l-3.3 3.29a1 1 0 0 0 1.42 1.42L12 13.41Z\" />\n </svg>\n `,\n remove: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M9 5.25C9 4.55964 9.55964 4 10.25 4H13.75C14.4404 4 15 4.55964 15 5.25V7H9V5.25Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n />\n <path\n d=\"M5 7H19\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <rect\n x=\"6.5\"\n y=\"7\"\n width=\"11\"\n height=\"12.5\"\n rx=\"2\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n />\n <path\n d=\"M10 11.5V16\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M14 11.5V16\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n `,\n close: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M13.41 12 18 7.41 16.59 6 12 10.59 7.41 6 6 7.41 10.59 12 6 16.59 7.41 18 12 13.41 16.59 18 18 16.59 13.41 12Z\" />\n </svg>\n `,\n};\n\nexport const DEFAULT_SOURCES: UploadSourceOption[] = [\n {\n id: 'device',\n label: 'From device',\n kind: 'device',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M9.5 4h5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n `,\n },\n {\n id: 'camera',\n label: 'Camera',\n kind: 'camera',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 7h2l1-2h8l1 2h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\" />\n <circle cx=\"12\" cy=\"13\" r=\"3.25\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n `,\n },\n {\n id: 'facebook',\n label: 'Facebook',\n kind: 'facebook',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M13 8h2V6h-2a3 3 0 0 0-3 3v1H8v2h2v6h2v-6h2v-2h-2V9a1 1 0 0 1 1-1Z\" fill=\"currentColor\" />\n </svg>\n `,\n },\n {\n id: 'google-drive',\n label: 'Google Drive',\n kind: 'google-drive',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6.5 18.5h11l3-5-5-8h-6l-5 8 2 3\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\" />\n <path d=\"M8 13.5h8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n `,\n },\n];\n\nexport const DEFAULT_THEME: Required<\n Pick<ThemeOptions, 'appearance' | 'borderRadius' | 'dropzoneBackground' | 'dropzoneBorder'>\n> = {\n appearance: 'light',\n borderRadius: 8,\n dropzoneBackground: 'var(--ar-color-muted)',\n dropzoneBorder: 'var(--ar-color-border)',\n};\n\n","import { getBaseUrl } from '../constants/defaults';\nimport type { AppRunnerResponse, UploadSettings, Environment } from '../types';\n\ninterface UploadFileParams {\n file: File;\n folderPath?: string;\n relativePath?: string;\n settings?: UploadSettings;\n}\n\ninterface GenerateTokenRequest {\n file_name?: string;\n folder?: string;\n tags?: string[];\n transform?: string;\n max_file_size?: number;\n allow_override?: {\n folder?: boolean;\n tags?: boolean;\n transform?: boolean;\n };\n metadata?: Record<string, unknown>;\n custom_id?: string;\n random_prefix?: boolean;\n ttl_seconds?: number;\n}\n\ninterface GenerateTokenResponse {\n token: string;\n}\n\ninterface NewUploadResponse {\n id: string;\n workspace_id: string;\n name: string;\n path: string;\n url: string;\n width?: number;\n height?: number;\n size: number;\n format?: string;\n mime_type?: string;\n hash?: string;\n tags?: string[];\n metadata?: Record<string, unknown> | null;\n custom_id?: string | null;\n is_private?: boolean;\n is_duplicate?: boolean;\n created_at: string;\n upload_source?: string;\n folder_no?: string | null;\n file_no?: string;\n}\n\nexport class AutorenderApiClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(opts: { apiKey: string; baseUrl?: string; environment?: Environment }) {\n if (!opts.apiKey) {\n throw new Error('apiKey is required');\n }\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl || getBaseUrl(opts.environment || 'prod')).replace(/\\/+$/, '');\n }\n\n private async generateToken(params: UploadFileParams): Promise<string> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n\n xhr.onerror = () => {\n reject(new Error(`Failed to generate token: ${xhr.statusText}`));\n };\n\n xhr.onload = () => {\n try {\n if (xhr.status < 200 || xhr.status >= 300) {\n const errorText = xhr.responseText || xhr.statusText;\n reject(new Error(`Failed to generate token: ${errorText}`));\n return;\n }\n const response = JSON.parse(xhr.responseText) as GenerateTokenResponse;\n if (!response.token) {\n reject(new Error('Token not found in response'));\n return;\n }\n resolve(response.token);\n } catch (error) {\n reject(new Error('Failed to parse token response'));\n }\n };\n\n // Build folder path - combine folderPath and relativePath if both exist\n let folder = params.folderPath || '';\n if (params.relativePath) {\n folder = folder ? `${folder}/${params.relativePath}` : params.relativePath;\n }\n // Ensure folder ends with / if provided\n if (folder && !folder.endsWith('/')) {\n folder += '/';\n }\n\n const tokenRequest: GenerateTokenRequest = {\n file_name: params.file.name,\n ...(folder && { folder }),\n ...(params.settings?.tags && { tags: params.settings.tags }),\n ...(params.settings?.pretransformations && { transform: params.settings.pretransformations }),\n max_file_size: params.file.size,\n allow_override: {\n folder: true,\n tags: true,\n transform: true,\n },\n random_prefix: !params.settings?.is_unique_suffix_name,\n };\n\n const endpoint = `${this.baseUrl}/generate-token`;\n xhr.open('POST', endpoint);\n xhr.setRequestHeader('Authorization', `Bearer ${this.apiKey}`);\n xhr.setRequestHeader('Content-Type', 'application/json');\n xhr.setRequestHeader('accept', 'application/json');\n xhr.send(JSON.stringify(tokenRequest));\n });\n }\n\n uploadFile(\n params: UploadFileParams,\n onProgress?: (progress: number) => void,\n signal?: AbortSignal\n ): Promise<AppRunnerResponse> {\n return new Promise(async (resolve, reject) => {\n // Check for abort signal before starting\n if (signal?.aborted) {\n reject(new DOMException('Upload aborted', 'AbortError'));\n return;\n }\n\n try {\n // Step 1: Generate token\n const token = await this.generateToken(params);\n\n // Check for abort signal after token generation\n if (signal?.aborted) {\n reject(new DOMException('Upload aborted', 'AbortError'));\n return;\n }\n\n // Step 2: Upload file with token\n const xhr = new XMLHttpRequest();\n\n if (signal) {\n signal.addEventListener('abort', () => {\n xhr.abort();\n reject(new DOMException('Upload aborted', 'AbortError'));\n });\n }\n\n let lastProgress = 0;\n xhr.upload.onprogress = event => {\n if (event.lengthComputable && onProgress) {\n const progress = Math.round((event.loaded / event.total) * 100);\n lastProgress = progress;\n onProgress(progress);\n } else if (onProgress && event.loaded > 0) {\n // Fallback: estimate progress based on loaded bytes if length isn't computable\n // Use a conservative estimate to show some progress\n const estimatedProgress = Math.min(95, Math.round((event.loaded / (event.loaded + 1000000)) * 100));\n if (estimatedProgress > lastProgress) {\n lastProgress = estimatedProgress;\n onProgress(estimatedProgress);\n }\n }\n };\n\n xhr.onerror = () => {\n reject(new Error(`Upload failed: ${xhr.statusText}`));\n };\n\n xhr.onload = () => {\n try {\n if (xhr.status < 200 || xhr.status >= 300) {\n const errorText = xhr.responseText || xhr.statusText;\n reject(new Error(`Upload failed: ${errorText}`));\n return;\n }\n const newResponse = JSON.parse(xhr.responseText) as NewUploadResponse;\n \n // Transform new API response to AppRunnerResponse format\n const response: AppRunnerResponse = {\n success: true,\n file_no: newResponse.file_no || newResponse.id,\n name: newResponse.name,\n url: newResponse.url,\n file_size: newResponse.size,\n format: newResponse.format,\n width: newResponse.width,\n height: newResponse.height,\n created_at: newResponse.created_at,\n path: newResponse.path,\n workspace_no: newResponse.workspace_id,\n isDuplicate: newResponse.is_duplicate || false,\n };\n \n resolve(response);\n } catch (error) {\n reject(new Error('Failed to parse response'));\n }\n };\n\n const endpoint = `${this.baseUrl}/uploads/${token}`;\n xhr.open('POST', endpoint);\n xhr.setRequestHeader('accept', 'application/json');\n // Use detected mimeType or fallback to application/octet-stream\n const mimeType = params.file.type || 'application/octet-stream';\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.send(params.file);\n } catch (error) {\n reject(error);\n }\n });\n }\n}\n\nexport {}\n\n","export function generateId(): string {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID();\n }\n\n return 'id-' + Math.random().toString(36).slice(2, 11);\n}\n\nexport function chunkArray<T>(items: T[], chunkSize: number): T[][] {\n if (chunkSize <= 0) {\n return [items];\n }\n\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += chunkSize) {\n chunks.push(items.slice(i, i + chunkSize));\n }\n return chunks;\n}\n\nexport function clamp(value: number, min = 0, max = 1) {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function formatBytes(bytes: number) {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const num = bytes / Math.pow(k, i);\n return `${num.toFixed(num > 10 ? 0 : 1)} ${sizes[i]}`;\n}\n\nexport function createElement<T extends keyof HTMLElementTagNameMap>(\n tag: T,\n className?: string,\n textContent?: string\n): HTMLElementTagNameMap[T] {\n const element = document.createElement(tag);\n if (className) element.className = className;\n if (textContent) element.textContent = textContent;\n return element;\n}\n\nexport function resolveIcon(renderer: string | HTMLElement | (() => string | HTMLElement)) {\n if (typeof renderer === 'function') {\n return resolveIcon(renderer());\n }\n if (typeof renderer === 'string') {\n const template = document.createElement('template');\n template.innerHTML = renderer.trim();\n return template.content.firstElementChild as HTMLElement | null;\n }\n return renderer ? (renderer.cloneNode(true) as HTMLElement) : null;\n}\n\nexport function toCssVars(theme: {\n appearance?: 'light' | 'dark' | 'system';\n accentColor?: string;\n borderRadius?: number;\n fontFamily?: string;\n dropzoneBackground?: string;\n dropzoneBorder?: string;\n}) {\n const variables: Record<string, string> = {};\n if (theme.accentColor) {\n variables['--ar-accent'] = theme.accentColor;\n }\n if (theme.borderRadius !== undefined) {\n variables['--ar-radius'] = `${theme.borderRadius}px`;\n }\n if (theme.fontFamily) {\n variables['--ar-font-family'] = theme.fontFamily;\n }\n if (theme.dropzoneBackground) {\n variables['--ar-dropzone-bg'] = theme.dropzoneBackground;\n }\n if (theme.dropzoneBorder) {\n variables['--ar-dropzone-border'] = theme.dropzoneBorder;\n }\n return variables;\n}\n\nexport function applyCssVariables(\n element: HTMLElement,\n variables: Record<string, string>\n) {\n Object.entries(variables).forEach(([key, value]) => {\n element.style.setProperty(key, value);\n });\n}\n\nexport function getRelativeFolderPath(\n basePath: string | undefined,\n relativePath: string | undefined\n) {\n if (!relativePath) return undefined;\n\n const parts = relativePath\n .split('/')\n .map(segment => segment.trim())\n .filter(segment => segment && segment !== '.');\n\n if (parts.length <= 1) {\n return undefined;\n }\n\n const folderSegments = parts.slice(0, -1);\n\n if (basePath) {\n const baseSegments = basePath\n .split('/')\n .map(segment => segment.trim())\n .filter(segment => segment && segment !== '.');\n\n let offset = 0;\n while (\n offset < baseSegments.length &&\n offset < folderSegments.length &&\n folderSegments[offset] === baseSegments[offset]\n ) {\n offset += 1;\n }\n\n return offset < folderSegments.length\n ? folderSegments.slice(offset).join('/')\n : undefined;\n }\n\n return folderSegments.length ? folderSegments.join('/') : undefined;\n}\n\nexport function calculateBatchProgress(items: { progress: number }[]) {\n if (items.length === 0) return 0;\n const total = items.reduce((acc, item) => acc + item.progress, 0);\n return Math.round(total / items.length);\n}\n\nconst S3_URL_PATTERN = /^s3:\\/\\/([^/]+)\\/(.+)$/i;\n\nexport function sanitizeBaseUrl(baseUrl?: string): string | undefined {\n if (!baseUrl) return undefined;\n const trimmed = baseUrl.trim();\n if (!trimmed) return undefined;\n return trimmed.replace(/\\/+$/, '');\n}\n\nexport function extractWorkspaceFromUrl(url?: string): string | undefined {\n if (!url) return undefined;\n const s3Match = S3_URL_PATTERN.exec(url);\n if (s3Match) {\n return s3Match[1];\n }\n try {\n const parsed = new URL(url);\n const firstSegment = parsed.pathname.replace(/^\\/+/, '').split('/')[0];\n return firstSegment || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function extractPathFromUrl(url?: string): string | undefined {\n if (!url) return undefined;\n const s3Match = S3_URL_PATTERN.exec(url);\n if (s3Match) {\n return s3Match[2];\n }\n try {\n const parsed = new URL(url);\n const [, ...rest] = parsed.pathname.replace(/^\\/+/, '').split('/');\n return rest.length ? rest.join('/') : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function buildAssetDeliveryUrl(\n baseUrl: string | undefined,\n workspace?: string,\n path?: string,\n fallback?: string\n): string | undefined {\n const sanitizedBase = sanitizeBaseUrl(baseUrl);\n if (!sanitizedBase || !workspace || !path) {\n return fallback;\n }\n\n const normalizedPath = path\n .split('/')\n .filter(Boolean)\n .map(segment => encodeURIComponent(segment))\n .join('/');\n\n return `${sanitizedBase}/${workspace}/${normalizedPath}`.replace(/([^:]\\/)\\/+/g, '$1');\n}\n\n","import { AutorenderApiClient } from '../client/api-client';\nimport { DEFAULT_ASSET_DELIVERY_BASE_URL } from '../constants/defaults';\nimport type {\n CreateUploaderOptions,\n UploadItem,\n UploadedFileResponse,\n ThemeOptions,\n UploadSourceOption,\n AppRunnerResponse,\n UploadSuccessFile,\n} from '../types';\nimport {\n applyCssVariables,\n buildAssetDeliveryUrl,\n calculateBatchProgress,\n extractPathFromUrl,\n extractWorkspaceFromUrl,\n generateId,\n getRelativeFolderPath,\n sanitizeBaseUrl,\n toCssVars,\n} from '../utils/helpers';\nimport { fileTypeFromBlob } from 'file-type';\n\nconst DEFAULT_PARALLEL_UPLOADS = 4;\nconst MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024; // 100MB\n\ninterface FileSelection {\n file: File;\n relativePath?: string;\n}\n\nexport interface ControllerOptions\n extends Omit<CreateUploaderOptions, 'target' | 'theme' | 'sources'> {\n theme?: ThemeOptions;\n sources?: UploadSourceOption[];\n}\n\nexport interface ControllerState {\n items: UploadItem[];\n isUploading: boolean;\n progress: number;\n duplicates: string[];\n}\n\ntype ControllerEvents =\n | 'statechange'\n | 'progress'\n | 'fileprogress'\n | 'error'\n | 'complete'\n | 'filesadded';\n\nexport class UploaderController extends EventTarget {\n private options: ControllerOptions;\n private readonly client: AutorenderApiClient;\n private items: UploadItem[] = [];\n private abortController: AbortController | null = null;\n private isUploading = false;\n private targetElement: HTMLElement;\n private duplicateConflicts = new Set<string>();\n\n private isAbortError(error: unknown): boolean {\n if (!error) return false;\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof Error && error.name === 'AbortError') return true;\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n return typeof message === 'string' && message.toLowerCase().includes('abort');\n }\n\n constructor(\n client: AutorenderApiClient,\n target: HTMLElement,\n options: ControllerOptions\n ) {\n super();\n this.client = client;\n this.targetElement = target;\n this.options = options;\n this.applyTheme();\n }\n\n setOptions(options: Partial<ControllerOptions>) {\n this.options = {\n ...this.options,\n ...options,\n };\n this.applyTheme();\n this.dispatch('statechange');\n }\n\n getOptions(): ControllerOptions {\n return this.options;\n }\n\n getState(): ControllerState {\n return {\n items: this.items,\n isUploading: this.isUploading,\n progress: calculateBatchProgress(this.items),\n duplicates: Array.from(this.duplicateConflicts),\n };\n }\n\n async addFiles(files: FileSelection[]) {\n const existingKeys = new Map<string, UploadItem>();\n const basePathKey = this.normalizePath(this.options.folderPath) ?? '';\n const buildKey = (file: File, folderPath?: string, relativePath?: string) =>\n `${basePathKey}::${folderPath ?? ''}::${relativePath ?? ''}::${file.name}::${file.size}`;\n\n this.items.forEach(item => {\n existingKeys.set(buildKey(item.file, item.folderPath, item.relativePath), item);\n });\n\n // Detect mimeType for files that don't have it\n const filesWithMimeType = await Promise.all(\n files.map(async ({ file, relativePath }) => {\n let mimeType = file.type;\n \n // If file doesn't have mimeType, detect it using file-type\n if (!mimeType || mimeType === 'application/octet-stream' || mimeType === '') {\n try {\n const detected = await fileTypeFromBlob(file);\n if (detected?.mime) {\n mimeType = detected.mime;\n // Update the File object's type property if possible\n Object.defineProperty(file, 'type', {\n value: mimeType,\n writable: false,\n configurable: true,\n });\n } else {\n // Fallback to application/octet-stream if detection fails\n mimeType = 'application/octet-stream';\n }\n } catch (error) {\n // If detection fails, use fallback\n mimeType = 'application/octet-stream';\n }\n }\n\n return { file, relativePath, mimeType };\n })\n );\n\n const newItems = filesWithMimeType.map(({ file, relativePath, mimeType }) => {\n const folderPath = getRelativeFolderPath(\n this.options.folderPath,\n relativePath\n ) ?? '';\n\n // Only create preview URL for images\n const previewUrl = mimeType.startsWith('image/')\n ? URL.createObjectURL(file)\n : undefined;\n\n // Check file size limit (100MB)\n const fileSizeMB = (file.size / (1024 * 1024)).toFixed(2);\n const info = file.size > MAX_FILE_SIZE_BYTES\n ? `File size (${fileSizeMB}MB) exceeds the maximum limit of 100MB`\n : undefined;\n\n const baseItem: UploadItem = {\n id: generateId(),\n file,\n relativePath,\n folderPath,\n status: 'pending' as const,\n progress: 0,\n previewUrl,\n info,\n };\n\n const key = buildKey(file, folderPath, relativePath);\n if (existingKeys.has(key)) {\n baseItem.status = 'completed';\n baseItem.progress = 100;\n baseItem.error = undefined;\n existingKeys.set(key, baseItem);\n return baseItem;\n }\n\n existingKeys.set(key, baseItem);\n return baseItem;\n });\n\n this.items = [...this.items, ...newItems];\n this.dispatch('filesadded', { items: newItems });\n\n const duplicates = newItems.filter(item => item.status === 'completed');\n if (duplicates.length) {\n this.markDuplicatesCompleted(duplicates);\n }\n\n this.dispatch('statechange');\n }\n\n removeFile(id: string) {\n const item = this.items.find(entry => entry.id === id);\n if (item?.previewUrl) {\n URL.revokeObjectURL(item.previewUrl);\n }\n this.items = this.items.filter(item => item.id !== id);\n if (item) {\n this.duplicateConflicts.delete(item.file.name);\n }\n this.dispatch('statechange');\n }\n\n reset() {\n this.abortController?.abort();\n this.abortController = null;\n this.isUploading = false;\n this.cleanupPreviews();\n this.items = [];\n this.duplicateConflicts.clear();\n this.dispatch('statechange');\n }\n\n async uploadAll() {\n if (this.isUploading) return;\n if (this.items.length === 0) return;\n\n this.duplicateConflicts.clear();\n this.isUploading = true;\n this.abortController = new AbortController();\n this.dispatch('statechange');\n\n try {\n await this.processUploads();\n const files = this.buildSuccessFiles();\n this.dispatch('complete', {\n items: this.items,\n files,\n });\n } catch (error) {\n if (this.isAbortError(error)) {\n this.dispatch('error', error);\n return;\n }\n this.annotateItemsWithError(error);\n this.dispatch('error', error);\n throw error;\n } finally {\n this.isUploading = false;\n this.abortController = null;\n this.dispatch('statechange');\n }\n }\n\n cancel() {\n this.abortController?.abort();\n this.abortController = null;\n }\n\n private isDuplicateError(error: unknown) {\n if (!error) return false;\n if (typeof error === 'object' && error !== null) {\n const status = (error as any).status ?? (error as any).statusCode;\n if (status === 409) {\n return true;\n }\n const code = (error as any).code;\n if (typeof code === 'string' && code.toLowerCase() === 'conflict') {\n return true;\n }\n }\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n const normalized = message.toLowerCase();\n return (\n normalized.includes('duplicate') ||\n normalized.includes('already exists') ||\n normalized.includes('status 409') ||\n normalized.includes('conflict 409') ||\n normalized.includes('409')\n );\n }\n\n private markDuplicatesCompleted(\n items: UploadItem[],\n duplicateNames?: string[],\n options: { annotateError?: boolean } = {}\n ): UploadItem[] {\n const normalizedNames =\n duplicateNames\n ?.map(name => name.trim().toLowerCase())\n .filter(Boolean) ?? [];\n const targetSet =\n normalizedNames.length > 0 ? new Set(normalizedNames) : null;\n\n const targetItems =\n targetSet !== null\n ? items.filter(item =>\n targetSet.has(item.file.name.trim().toLowerCase())\n )\n : items;\n\n const duplicates =\n targetSet !== null && targetItems.length === 0 ? items : targetItems;\n\n const { annotateError = true } = options;\n\n duplicates.forEach(item => {\n if (!item) return;\n\n const name = item.file.name;\n if (!this.duplicateConflicts.has(name)) {\n this.duplicateConflicts.add(name);\n }\n\n item.status = 'completed';\n item.progress = 100;\n item.error = annotateError ? 'duplicate' : undefined;\n this.dispatch('fileprogress', { item });\n });\n\n if (duplicates.length > 0) {\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n\n this.dispatch('statechange');\n }\n\n return duplicates;\n }\n\n private isAuthError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n return (\n typeof message === 'string' &&\n message.toLowerCase().includes('unauthorized')\n );\n }\n\n const status = (error as any).status;\n if (typeof status === 'number' && (status === 401 || status === 403)) {\n return true;\n }\n\n const message =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : '';\n const normalized = String(message).toLowerCase();\n return (\n normalized.includes('unauthorized') ||\n normalized.includes('forbidden') ||\n normalized.includes('invalid api key')\n );\n }\n\n private annotateItemsWithError(error: unknown) {\n const isAuth = this.isAuthError(error);\n const fallbackMessage =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : 'Upload failed';\n\n let mutated = false;\n\n this.items.forEach(item => {\n if (item.status === 'completed') return;\n mutated = true;\n item.status = 'error';\n item.progress = item.progress ?? 0;\n item.error = isAuth ? 'invalid-api-key' : fallbackMessage;\n this.dispatch('fileprogress', { item });\n });\n\n if (mutated) {\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n this.dispatch('statechange');\n }\n }\n\n private async processUploads() {\n const allItems = this.items.filter(item => item.status !== 'completed');\n\n if (allItems.length === 0) {\n return;\n }\n\n const parallel = Math.max(1, this.options.parallelUploads ?? DEFAULT_PARALLEL_UPLOADS);\n const uploadSettings = this.options.uploadSettings;\n\n // Process all items in parallel with concurrency limit\n const tasks = allItems.map(item => async () => {\n if (this.abortController?.signal.aborted) {\n throw new Error('Upload cancelled');\n }\n\n try {\n await this.uploadSingleFile(item, uploadSettings);\n } catch (error) {\n if (this.isAbortError(error)) {\n return; // Don't mark as error for aborted uploads\n }\n if (this.isDuplicateError(error)) {\n this.markDuplicatesCompleted([item], [item.file.name], {\n annotateError: true,\n });\n } else {\n const err = error instanceof Error ? error : new Error(String(error));\n item.status = 'error';\n item.error = err.message;\n this.dispatch('fileprogress', { item });\n this.dispatch('statechange');\n }\n }\n });\n\n await this.runWithConcurrency(tasks, parallel);\n }\n\n private async uploadSingleFile(\n item: UploadItem,\n uploadSettings?: CreateUploaderOptions['uploadSettings']\n ) {\n // Check file size limit before uploading\n if (item.file.size > MAX_FILE_SIZE_BYTES) {\n // Don't upload, but keep status as pending and show info message\n const fileSizeMB = (item.file.size / (1024 * 1024)).toFixed(2);\n item.info = `File size (${fileSizeMB}MB) exceeds the maximum limit of 100MB`;\n this.dispatch('fileprogress', { item });\n this.dispatch('statechange');\n return; // Skip upload for files that are too large\n }\n\n item.status = 'uploading';\n item.progress = 0;\n this.dispatch('statechange');\n\n const folderPath = item.folderPath\n ? this.combinePaths(this.options.folderPath, item.folderPath)\n : this.normalizePath(this.options.folderPath);\n\n const appRunnerResponse: AppRunnerResponse = await this.client.uploadFile(\n {\n file: item.file,\n folderPath: folderPath ?? undefined,\n relativePath: item.relativePath,\n settings: uploadSettings\n ? {\n pretransformations: uploadSettings.pretransformations,\n tags: uploadSettings.tags,\n is_unique_suffix_name: uploadSettings.is_unique_suffix_name ?? false,\n }\n : undefined,\n },\n progress => {\n item.progress = progress;\n this.dispatch('fileprogress', { item });\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n },\n this.abortController?.signal\n );\n\n if (!appRunnerResponse.success) {\n const error = new Error(appRunnerResponse.message ?? 'Upload failed');\n (error as any).code = appRunnerResponse.errorCode;\n throw error;\n }\n\n item.status = 'completed';\n item.progress = 100;\n item.response = {\n file_no: appRunnerResponse.file_no,\n name: appRunnerResponse.name,\n url: appRunnerResponse.url,\n file_size: appRunnerResponse.file_size,\n folder_no: undefined,\n path: appRunnerResponse.path,\n width: appRunnerResponse.width,\n height: appRunnerResponse.height,\n format: appRunnerResponse.format,\n workspace_no: appRunnerResponse.workspace_no,\n };\n item.uploadedAt = new Date(appRunnerResponse.created_at);\n\n if (appRunnerResponse.isDuplicate) {\n item.error = 'duplicate';\n }\n\n this.dispatch('fileprogress', { item });\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n this.dispatch('statechange');\n }\n\n\n\n private applyTheme() {\n if (!this.options.theme) return;\n const vars = toCssVars(this.options.theme);\n applyCssVariables(this.targetElement, vars);\n if (this.options.theme.appearance && this.options.theme.appearance !== 'system') {\n this.targetElement.dataset.theme = this.options.theme.appearance;\n } else {\n delete this.targetElement.dataset.theme;\n }\n }\n\n private dispatch(event: ControllerEvents, detail?: CustomEventInit['detail']) {\n const customEvent = new CustomEvent(event, { detail });\n this.dispatchEvent(customEvent);\n\n switch (event) {\n case 'progress':\n this.options.onProgress?.(\n (detail as any)?.progress ?? calculateBatchProgress(this.items),\n this.items\n );\n break;\n case 'fileprogress':\n this.options.onFileProgress?.((detail as any).item);\n break;\n case 'error':\n this.options.onError?.(\n detail instanceof Error ? detail : new Error(String(detail))\n );\n break;\n case 'complete':\n this.options.onSuccess?.((detail as any)?.files ?? []);\n break;\n default:\n break;\n }\n }\n\n private resolveAssetDeliveryBaseUrl() {\n return (\n sanitizeBaseUrl(this.options.assetDeliveryBaseUrl) ??\n DEFAULT_ASSET_DELIVERY_BASE_URL\n );\n }\n\n private buildSuccessFiles(): UploadSuccessFile[] {\n const baseUrl = this.resolveAssetDeliveryBaseUrl();\n\n return this.items\n .filter(item => item.status === 'completed' && item.response)\n .map(item => {\n const response = item.response as UploadedFileResponse;\n const workspace =\n response.workspace_no ?? extractWorkspaceFromUrl(response.url);\n const assetPath = response.path ?? extractPathFromUrl(response.url);\n const resolvedUrl =\n buildAssetDeliveryUrl(baseUrl, workspace, assetPath, response.url) ??\n response.url;\n\n return {\n id: item.id,\n previewUrl: item.previewUrl,\n file_no: response.file_no,\n name: response.name,\n url: resolvedUrl,\n input_file_size: item.file?.size ?? response.file_size ?? 0,\n output_file_size: response.file_size ?? 0,\n path: response.path ?? assetPath,\n width: response.width,\n height: response.height,\n format: response.format,\n workspace_no: workspace,\n uploadedAt: item.uploadedAt?.toISOString(),\n };\n });\n }\n\n private async runWithConcurrency(tasks: Array<() => Promise<void>>, limit: number) {\n const executing = new Set<Promise<void>>();\n\n for (const task of tasks) {\n if (this.abortController?.signal.aborted) {\n throw new Error('Upload cancelled');\n }\n\n const promise = task().finally(() => {\n executing.delete(promise);\n });\n executing.add(promise);\n\n if (executing.size >= limit) {\n await Promise.race(executing);\n }\n }\n\n await Promise.all(executing);\n }\n\n private cleanupPreviews() {\n this.items.forEach(item => {\n if (item.previewUrl) {\n URL.revokeObjectURL(item.previewUrl);\n item.previewUrl = undefined;\n }\n });\n }\n\n private normalizePath(path?: string): string | undefined {\n if (!path) {\n return undefined;\n }\n\n const normalized = path\n .split('/')\n .map(segment => segment.trim())\n .filter(Boolean)\n .join('/');\n\n return normalized.length > 0 ? normalized : undefined;\n }\n\n private combinePaths(basePath?: string, relativePath?: string): string | undefined {\n const base = this.normalizePath(basePath);\n const relative = this.normalizePath(relativePath);\n\n if (base && relative) {\n return `${base}/${relative}`;\n }\n\n return base || relative || undefined;\n }\n\n}\n\n","export const widgetStyles = /* css */ `\n:host {\n --ar-font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --ar-color-bg: hsl(0 0% 100%);\n --ar-color-bg-muted: hsl(210 40% 96%);\n --ar-color-border: hsl(214 32% 91%);\n --ar-color-text: hsl(222 47% 11%);\n --ar-color-muted-foreground: hsl(215 16% 47%);\n /* let palette or theme set accent */\n --ar-color-accent: unset;\n --ar-color-accent-hover: unset;\n --ar-color-accent-button: unset;\n --ar-radius: 8px;\n display: block;\n}\n\n/* Palette: Blue (default) */\n:host([data-palette='at-blue']),\n:host:not([data-palette]) {\n --ar-color-accent: #e0f2fe;\n --ar-color-accent-hover: #f0f9ff;\n --ar-color-accent-button: #0c55f9;\n}\n\n/* Palette: Purple */\n:host([data-palette='at-purple']) {\n --ar-color-accent: #f3e8ff;\n --ar-color-accent-hover: #faf5ff;\n --ar-color-accent-button: #8a3ffc;\n}\n\n/* Palette: Red */\n:host([data-palette='at-red']) {\n --ar-color-accent: #fee2e2;\n --ar-color-accent-hover: #fef2f2;\n --ar-color-accent-button: #da1e28;\n}\n\n/* Palette: Orange */\n:host([data-palette='at-orange']) {\n --ar-color-accent: #ffedd5;\n --ar-color-accent-hover: #fff7ed;\n --ar-color-accent-button: #ff832b;\n}\n\n/* Palette: Green */\n:host([data-palette='at-green']) {\n --ar-color-accent: #dcfce7;\n --ar-color-accent-hover: #f0fdf4;\n --ar-color-accent-button: #24a148;\n}\n\n/* Palette: Turquoise */\n:host([data-palette='at-turquoise']) {\n --ar-color-accent: #ccfbf1;\n --ar-color-accent-hover: #f0fdfa;\n --ar-color-accent-button: #0072c3;\n}\n\n/* Palette: Gray */\n:host([data-palette='at-gray']) {\n --ar-color-accent: #f3f4f6;\n --ar-color-accent-hover: #f9fafb;\n --ar-color-accent-button: #525252;\n}\n\n:host([data-trigger='inline']) .ar-uploader-root,\n:host([data-trigger='inline']) .ar-inline-upload,\n:host([data-trigger='inline']) .ar-inline-panel {\n width: 100%;\n min-width: 0;\n}\n\n:host([data-theme='dark']) {\n --ar-color-bg: hsl(222 41% 6%);\n --ar-color-bg-muted: hsl(217 33% 17%);\n --ar-color-border: hsl(217 19% 27%);\n --ar-color-text: hsl(213 31% 91%);\n --ar-color-muted-foreground: hsl(215 20% 65%);\n --ar-color-accent: unset;\n --ar-color-accent-hover: unset;\n}\n\n/* Dark theme palette overrides */\n:host([data-theme='dark'][data-palette='at-blue']),\n:host([data-theme='dark']:not([data-palette])) {\n --ar-color-accent: rgba(120, 169, 255, 0.8);\n --ar-color-accent-hover: rgba(120, 169, 255, 0.2);\n --ar-color-accent-button: #78a9ff;\n}\n\n:host([data-theme='dark'][data-palette='at-purple']) {\n --ar-color-accent: rgba(167, 139, 250, 0.8);\n --ar-color-accent-hover: rgba(167, 139, 250, 0.2);\n --ar-color-accent-button: #a78bfa;\n}\n\n:host([data-theme='dark'][data-palette='at-red']) {\n --ar-color-accent: rgba(255, 131, 137, 0.8);\n --ar-color-accent-hover: rgba(255, 131, 137, 0.2);\n --ar-color-accent-button: #ff8389;\n}\n\n:host([data-theme='dark'][data-palette='at-orange']) {\n --ar-color-accent: rgba(255, 179, 102, 0.8);\n --ar-color-accent-hover: rgba(255, 179, 102, 0.2);\n --ar-color-accent-button: #ffb366;\n}\n\n:host([data-theme='dark'][data-palette='at-green']) {\n --ar-color-accent: rgba(111, 220, 140, 0.8);\n --ar-color-accent-hover: rgba(111, 220, 140, 0.2);\n --ar-color-accent-button: #6fdc8c;\n}\n\n:host([data-theme='dark'][data-palette='at-turquoise']) {\n --ar-color-accent: rgba(130, 207, 255, 0.8);\n --ar-color-accent-hover: rgba(130, 207, 255, 0.2);\n --ar-color-accent-button: #82cfff;\n}\n\n:host([data-theme='dark'][data-palette='at-gray']) {\n --ar-color-accent: rgba(198, 198, 198, 0.8);\n --ar-color-accent-hover: rgba(198, 198, 198, 0.2);\n --ar-color-accent-button: #c6c6c6;\n}\n\n.ar-uploader-root {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n font-family: var(--ar-font-family);\n background-color: var(--ar-color-bg);\n color: var(--ar-color-text);\n border: 1px solid var(--ar-color-border);\n border-radius: var(--ar-radius);\n padding: 0.5rem 1rem 1rem 1rem;\n}\n\n/* Reduce root gap when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-uploader-root:has(.ar-inline-upload--no-sources) {\n gap: 0.75rem;\n}\n\n\n:host([data-theme='dark']) .ar-uploader-root {\n background-color: hsl(222 41% 6%);\n}\n\n.ar-uploader-root[data-trigger='button'] {\n border: none;\n padding: 0;\n box-shadow: none;\n background: transparent;\n}\n\n.ar-header {\n display: none;\n}\n\n.ar-uploader-root.has-items .ar-header {\n display: flex;\n}\n\n.ar-title {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n}\n\n.ar-description {\n margin: 0;\n color: var(--ar-color-muted-foreground);\n font-size: 0.95rem;\n}\n\n\n.ar-subtext {\n margin: 0;\n font-size: 0.8rem;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-button-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.45rem;\n padding: 0.55rem 1.25rem;\n font-weight: 600;\n border-radius: var(--ar-radius);\n border: 1px solid rgba(15, 23, 42, 0.08);\n background: rgba(248, 250, 252, 0.9);\n color: var(--ar-color-text);\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 6px 16px rgba(15, 23, 42, 0.06);\n}\n\n:host([data-theme='dark']) .ar-button-trigger {\n border: 1px solid rgba(148, 163, 184, 0.25);\n background: rgba(30, 41, 59, 0.75);\n color: var(--ar-color-text);\n}\n\n.ar-button-trigger:hover {\n transform: translateY(-1px);\n}\n\n.ar-button-trigger:active {\n transform: translateY(0);\n}\n\n.ar-button-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.ar-button-icon svg {\n width: 1rem;\n height: 1rem;\n fill: currentColor;\n}\n\n.ar-inline-upload {\n display: flex;\n flex-direction: column;\n gap: 1.1rem;\n}\n\n/* Reduce gap when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-inline-upload--no-sources {\n gap: 0.5rem;\n}\n\n.ar-inline-panel {\n display: flex;\n flex-direction: column;\n}\n\n.ar-dropzone {\n position: relative;\n border: 1.5px dashed var(--ar-dropzone-border, var(--ar-color-border));\n border-radius: var(--ar-radius);\n background: var(--ar-dropzone-bg, var(--ar-color-bg));\n padding: 3rem 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n gap: 1rem;\n cursor: pointer;\n transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.2s ease;\n margin: 0.6rem 0rem 1rem 0rem;\n}\n\n/* Reduce bottom margin when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-modal-body--no-sources .ar-dropzone {\n margin-bottom: 0.25rem;\n}\n\n.ar-dropzone:hover {\n background-color: var(--ar-color-accent-hover);\n transform: translateY(-1px);\n}\n\n.ar-dropzone:hover .ar-dropzone-icon {\n background: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragover {\n border-color: var(--ar-color-accent);\n background-color: var(--ar-color-accent-hover);\n}\n\n.ar-dropzone.is-dragover .ar-dropzone-icon {\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragover .ar-description {\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragging {\n border-color: var(--ar-color-accent);\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragging .ar-dropzone-icon {\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragging .ar-description {\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone-icon {\n width: 3rem;\n height: 3rem;\n border-radius: 999px;\n background: rgba(148, 163, 184, 0.12);\n color: var(--ar-color-muted-foreground);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n:host([data-theme='dark']) .ar-dropzone-icon {\n color: var(--ar-color-text);\n}\n\n.ar-dropzone svg {\n width: 1.75rem;\n height: 1.75rem;\n fill: currentColor;\n}\n\n.ar-dropzone-actions {\n display: none;\n}\n\n.ar-file-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n margin-bottom: 1rem;\n}\n\n.ar-file-list.is-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 1rem;\n}\n\n.ar-file-item {\n border: none;\n border-radius: var(--ar-radius);\n background: rgba(148, 163, 184, 0.15);\n padding: 0.5rem;\n display: flex;\n flex-direction: column;\n gap: 0.45rem;\n position: relative;\n box-sizing: border-box;\n min-height: 50px;\n overflow: hidden;\n}\n\n.ar-file-item.is-grid {\n height: auto;\n padding: 0px;\n background: none;\n}\n\n:host([data-theme='dark']) .ar-file-item {\n background: hsl(222 41% 10%);\n}\n\n.ar-file-header {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n min-width: 0;\n flex: 1;\n}\n\n.ar-file-header.is-grid {\n flex-direction: column;\n align-items: stretch;\n}\n\n.ar-file-thumb {\n width: 32px;\n height: 32px;\n border-radius: calc(var(--ar-radius) * 0.5);\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.8rem;\n font-weight: 600;\n overflow: hidden;\n position: relative;\n}\n\n.ar-file-thumb-document {\n background: rgba(148, 163, 184, 0.15);\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-file-thumb-document svg {\n width: 20px;\n height: 20px;\n color: currentColor;\n}\n\n.ar-file-thumb.is-grid {\n width: 100%;\n height: 140px;\n border-radius: calc(var(--ar-radius) * 0.75);\n font-size: 1rem;\n}\n\n.ar-file-thumb.is-grid.ar-file-thumb-document svg {\n width: 48px;\n height: 48px;\n}\n\n.ar-file-item.is-completed .ar-file-thumb {\n color: #fff;\n}\n\n.ar-thumb-status {\n position: absolute;\n bottom: -2px;\n right: -2px;\n width: 18px;\n height: 18px;\n border-radius: 999px;\n background: #1e9f6d;\n color: #fff;\n border: 2px solid var(--ar-color-bg);\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 6px rgba(15, 23, 42, 0.25);\n}\n\n.ar-thumb-status svg {\n width: 10px;\n height: 10px;\n color: currentColor;\n}\n\n.ar-thumb-status.is-error {\n background: rgba(225, 29, 72, 0.85);\n}\n\n.ar-file-name {\n font-size: 0.8rem;\n margin: 0;\n color: var(--ar-color-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n min-width: 0;\n}\n\n.ar-file-meta {\n display: block;\n margin-top: 0.25rem;\n font-size: 0.8rem;\n color: var(--ar-color-muted-foreground);\n width: 100%;\n flex-shrink: 0;\n}\n\n.ar-file-info {\n display: block;\n font-size: 0.75rem;\n color: var(--ar-color-muted-foreground);\n font-style: italic;\n padding: 0.25rem 0.5rem;\n background: rgba(148, 163, 184, 0.15);\n border-radius: calc(var(--ar-radius) * 0.5);\n width: 100%;\n box-sizing: border-box;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.ar-file-item.is-grid .ar-file-info {\n font-size: 0.7rem;\n padding: 0.2rem 0.4rem;\n}\n\n.ar-file-item.is-grid .ar-file-meta {\n justify-content: center;\n}\n\n.ar-remove-button {\n margin-left: auto;\n border: none;\n background: transparent;\n color: var(--ar-color-muted-foreground);\n cursor: pointer;\n padding: 0.25rem;\n border-radius: var(--ar-radius);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s ease, color 0.2s ease;\n}\n\n.ar-remove-button.is-grid {\n position: absolute;\n top: 0.6rem;\n right: 0.6rem;\n background: rgba(255, 255, 255, 0.95);\n color: var(--ar-color-text);\n padding: 0.35rem;\n border-radius: var(--ar-radius);\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease, background 0.2s ease, color 0.2s ease;\n}\n\n.ar-file-item.is-grid:hover .ar-remove-button.is-grid {\n opacity: 1;\n pointer-events: auto;\n}\n\n:host([data-theme='dark']) .ar-remove-button.is-grid {\n background: rgba(15, 23, 42, 0.92);\n color: var(--ar-color-text);\n box-shadow: 0 4px 18px rgba(8, 47, 73, 0.45);\n}\n\n.ar-remove-button svg {\n width: 20px;\n height: 20px;\n display: block;\n}\n\n.ar-remove-button svg path,\n.ar-remove-button svg line,\n.ar-remove-button svg rect,\n.ar-remove-button svg circle,\n.ar-remove-button svg polyline {\n stroke: currentColor;\n fill: none;\n}\n\n.ar-remove-button:hover:not([disabled]) {\n color: var(--ar-color-text);\n}\n\n.ar-progress-track {\n width: 100%;\n height: 4px;\n border-radius: var(--ar-radius);\n background-color: rgba(148, 163, 184, 0.35);\n overflow: hidden;\n}\n\n.ar-file-item.is-uploading {\n border-color: var(--ar-color-accent);\n}\n\n.ar-file-item.is-error {\n border: 1px solid rgba(225, 29, 72, 0.4);\n background: rgba(248, 113, 113, 0.12);\n}\n\n.ar-progress-border {\n opacity: 0;\n height: 2px;\n width: 96%;\n border-radius: 999px;\n background: var(--ar-color-accent-hover);\n overflow: hidden;\n margin-top: 0.35rem;\n position: absolute;\n bottom: 0;\n left: 6px;\n right: 6px;\n}\n\n.ar-progress-border.is-active,\n.ar-progress-border.is-complete {\n opacity: 1;\n}\n\n.ar-progress-border.is-train {\n background: var(--ar-color-accent-hover);\n}\n\n.ar-progress-fill {\n height: 100%;\n width: 0%;\n border-radius: inherit;\n background: var(--ar-color-accent);\n transition: width 0.25s ease;\n transform-origin: left center;\n animation: none;\n}\n\n.ar-progress-fill.is-train {\n background-image: linear-gradient(\n 90deg,\n rgba(245, 250, 241, 0.93) 0%,\n rgba(240, 242, 247, 0.85) 80%,\n rgb(30, 101, 212) 100%\n );\n background-size: 220% 100%;\n animation: ar-progress-train 2.4s linear infinite;\n}\n\n.ar-progress-border.is-complete {\n background: rgba(34, 197, 94, 0.25);\n}\n\n.ar-progress-border.is-complete .ar-progress-fill {\n background-image: linear-gradient(\n 90deg,\n rgba(52, 211, 153, 0.3) 0%,\n rgba(16, 185, 129, 0.85) 50%,\n rgba(52, 211, 153, 0.3) 100%\n );\n animation: none;\n}\n\n@keyframes ar-progress-train {\n 0% {\n background-position: 240% 0;\n }\n 100% {\n background-position: -240% 0;\n }\n}\n\n.ar-file-item.is-completed {\n border-color: rgba(30, 159, 109, 0.6);\n}\n\n.ar-file-item.is-grid .ar-file-name {\n text-align: left;\n font-size: 0.78rem;\n color: var(--ar-color-muted-foreground);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ar-status {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-status svg {\n width: 1rem;\n height: 1rem;\n}\n\n.ar-status.is-success {\n color: #1e9f6d;\n}\n\n.ar-status.is-error {\n color: #e11d48;\n}\n\n.ar-status.is-warning {\n color: #d97706;\n}\n\n.ar-file-error {\n font-size: 0.78rem;\n color: #e11d48;\n}\n\n.ar-error-banner {\n display: none;\n margin: 0.5rem 0;\n color: #b91c1c;\n font-size: 0.82rem;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.ar-error-banner:not([hidden]) {\n display: block;\n}\n\n:host([data-theme='dark']) .ar-error-banner {\n color: #fecaca;\n}\n\n.ar-actions {\n display: flex;\n justify-content: flex-end;\n}\n\n.ar-upload-button {\n border-radius: 10px;\n padding: 0.65rem 1.5rem;\n font-weight: 600;\n border: none;\n background: var(--ar-color-accent-button, var(--ar-color-accent));\n color: white;\n cursor: pointer;\n transition: filter 0.2s ease, transform 0.2s ease;\n min-width: 140px;\n}\n\n.ar-upload-button:hover:not([disabled]) {\n filter: brightness(1.05);\n transform: translateY(-1px);\n}\n\n.ar-upload-button[disabled] {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.ar-footer {\n font-size: 0.78rem;\n color: var(--ar-color-muted-foreground);\n text-align: right;\n}\n\n.ar-modal {\n position: fixed;\n inset: 0;\n display: none;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.ar-modal.is-portal {\n position: absolute;\n}\n\n.ar-modal.is-open {\n display: flex;\n}\n\n.ar-modal-backdrop {\n position: absolute;\n inset: 0;\n background: rgba(15, 23, 42, 0.45);\n}\n\n.ar-modal-dialog {\n position: relative;\n background: var(--ar-color-bg);\n border-radius: 16px;\n border: 1px solid var(--ar-color-border);\n box-shadow: 0 32px 80px rgba(15, 23, 42, 0.25);\n width: min(343px, 92vw);\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n padding: 0.5rem 1rem 1rem 1rem;\n}\n\n.ar-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.ar-modal-header.is-inline {\n justify-content: flex-start;\n align-items: center;\n gap: 0.5rem;\n padding-top:0.5rem;\n}\n\n.ar-modal-title {\n margin: 0;\n font-size: 1rem;\n font-weight: 500;\n}\n\n.ar-modal-close {\n border: none;\n background: transparent;\n color: var(--ar-color-muted-foreground);\n cursor: pointer;\n border-radius: 999px;\n padding: 0.3rem;\n transition: color 0.2s ease, background 0.2s ease;\n}\n\n.ar-modal-close:hover {\n background: rgba(148, 163, 184, 0.15);\n color: var(--ar-color-accent);\n}\n\n.ar-modal-close-icon svg {\n width: 1.2rem;\n height: 1.2rem;\n}\n\n.ar-modal-body {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n overflow-y: auto;\n padding-right: 0.25rem;\n}\n\n/* Reduce gap when source list is hidden in inline mode */\n:host([data-trigger='inline']) .ar-modal-body--no-sources {\n gap: 0.5rem;\n}\n\n.ar-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n}\n\n.ar-modal-footer.is-inline {\n padding: 0;\n border-top: none;\n}\n\n.ar-modal-footer.is-inline .ar-modal-footer-actions {\n margin-left: auto;\n}\n\n.ar-modal-footer-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.ar-modal-add-more,\n.ar-modal-clear {\n border-radius: var(--ar-radius);\n padding: 0.55rem 1.25rem;\n font-weight: 600;\n border: 1px solid var(--ar-color-border);\n background: var(--ar-color-bg);\n color: var(--ar-color-text);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.ar-modal-add-more:hover {\n border-color: var(--ar-color-accent-button, var(--ar-color-accent));\n color: var(--ar-color-accent-button, var(--ar-color-accent));\n}\n\n.ar-modal-clear {\n background: rgba(148, 163, 184, 0.12);\n}\n\n.ar-modal-clear[disabled] {\n opacity: 0.45;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.ar-modal-clear:hover {\n border-color: var(--ar-color-accent);\n color: var(--ar-color-accent);\n}\n\n.ar-modal-upload-button,\n.ar-modal-done {\n border-radius: var(--ar-radius);\n padding: 0.55rem 1.25rem;\n font-weight: 600;\n border: none;\n background: var(--ar-color-accent-button, var(--ar-color-accent));\n color: white;\n cursor: pointer;\n transition: filter 0.2s ease;\n}\n\n.ar-modal-upload-button:hover,\n.ar-modal-done:hover {\n filter: brightness(1.05);\n}\n\n.ar-uploaded-summary {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n border-top: 1px solid var(--ar-color-border);\n padding-top: 1rem;\n}\n\n.ar-uploader-root[data-trigger='button'] .ar-uploaded-summary {\n border: 1px solid var(--ar-color-border);\n border-radius: var(--ar-radius);\n padding: 1rem;\n background: var(--ar-color-bg-muted);\n}\n\n.ar-summary-title {\n margin: 0;\n font-size: 0.95rem;\n font-weight: 600;\n}\n\n.ar-summary-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.ar-summary-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.ar-summary-icon {\n width: 38px;\n height: 38px;\n border-radius: 12px;\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n}\n\n.ar-summary-info {\n display: flex;\n flex-direction: column;\n gap: 0.2rem;\n}\n\n.ar-summary-name {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ar-summary-meta {\n font-size: 0.8rem;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-uploader-root.is-uploading .ar-dropzone {\n display: none;\n}\n\n.ar-uploader-root.has-items .ar-file-list {\n display: flex;\n}\n\n.ar-file-list:empty {\n display: none;\n}\n\n.ar-modal-upload {\n display: flex;\n flex-direction: column;\n}\n\n.ar-modal-upload.is-inline {\n gap: 1rem;\n}\n\n.ar-modal-body .ar-file-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n max-height: 220px;\n overflow-y: auto;\n border: none;\n background: transparent;\n padding: 0;\n}\n\nbutton,\n.ar-button-trigger,\n.ar-dropzone-button,\n.ar-upload-button,\n.ar-modal-footer button,\n.ar-actions button,\n.ar-remove-button,\n.ar-modal-header button {\n font-size: 1rem;\n font-weight: 400;\n}\n\n@media (max-width: 640px) {\n .ar-uploader-root {\n padding: 1rem;\n }\n\n .ar-dropzone {\n padding: 2.25rem 1.25rem;\n }\n\n .ar-modal-dialog {\n width: min(90vw, 343px);\n padding: 1.25rem;\n }\n}\n\n.ar-actions-sources,\n.ar-modal-sources {\n display: none;\n}\n\n.ar-actions-sources.is-visible,\n.ar-modal-sources.is-visible {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.ar-source-list {\n display: none;\n flex-direction: column;\n margin: 1rem 0rem;\n}\n\n/* Remove margin when source list is hidden in inline mode */\n:host([data-trigger='inline']) .ar-source-list:not(.ar-source-list--choices) {\n margin: 0;\n}\n\n.ar-source-list--choices {\n display: flex;\n}\n\n.ar-source-option {\n display: flex;\n align-items: center;\n gap: 0.65rem;\n width: 100%;\n border: none;\n border-radius: var(--ar-radius);\n background: transparent;\n padding: 0.55rem 0.75rem;\n text-align: left;\n color: var(--ar-color-text);\n cursor: pointer;\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n\n.ar-source-option.is-primary {\n background: rgba(148, 163, 184, 0.12);\n color: var(--ar-color-muted-foreground);\n}\n\n:host([data-theme='dark']) .ar-source-option.is-primary {\n color: var(--ar-color-text);\n}\n\n.ar-source-option:hover:not([disabled]),\n.ar-source-option:focus-visible {\n background: var(--ar-color-accent-hover);\n}\n\n.ar-source-option[disabled] {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.ar-source-option-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-source-option-label {\n flex: 1;\n font-size: 0.95rem;\n}\n\n.ar-source-inline {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.ar-source-inline-button {\n width: 36px;\n height: 36px;\n border-radius: 999px;\n border: 1px solid var(--ar-color-border);\n background: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--ar-color-text);\n transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n}\n\n.ar-source-inline-button:hover:not([disabled]) {\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n border-color: var(--ar-color-accent);\n}\n\n.ar-source-inline-button svg {\n width: 18px;\n height: 18px;\n display: block;\n}\n\n.ar-modal-cancel {\n background: rgba(148, 163, 184, 0.15);\n border: none;\n color: var(--ar-color-text);\n padding:0.5rem 1rem;\n border-radius: var(--ar-radius);\n}\n\n.ar-modal-cancel:hover:not([disabled]) {\n background: rgba(148, 163, 184, 0.25);\n}\n\n.ar-modal-cancel.is-fullwidth {\n width: 100%;\n justify-content: center;\n border-radius: var(--ar-radius);\n cursor: pointer;\n}\n\n.ar-modal-powered,\n.ar-inline-powered {\n margin-top: 12px;\n font-size: 0.75rem;\n color: var(--ar-color-muted-foreground);\n text-align: center;\n}\n\n/* Reduce margin when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-inline-upload--no-sources .ar-inline-powered {\n margin-top: 0.5rem;\n}\n\n.ar-duplicate-banner {\n display: none;\n margin: 0.75rem 0;\n padding: 0.75rem;\n border-radius: var(--ar-radius);\n background: rgba(248, 113, 113, 0.12);\n color: #9f1239;\n font-size: 0.85rem;\n line-height: 1.3;\n}\n\n.ar-duplicate-banner[hidden] {\n display: none !important;\n}\n\n`;\n\n","import { UploaderController, type ControllerOptions } from '../core/uploader-controller';\nimport { DEFAULT_ICONS, DEFAULT_LABELS, DEFAULT_THEME } from '../constants/defaults';\nimport type {\n IconSet,\n LabelSet,\n ThemeOptions,\n UploadItem,\n UploadSourceOption,\n UploaderClassNames,\n} from '../types';\nimport { resolveIcon } from '../utils/helpers';\nimport { widgetStyles } from './styles';\n\nconst HTMLElementShim: typeof HTMLElement =\n typeof globalThis === 'undefined' || typeof globalThis.HTMLElement === 'undefined'\n ? (class HTMLElementFallback {} as unknown as typeof HTMLElement)\n : globalThis.HTMLElement;\n\ninterface FilesAddedDetail {\n items: UploadItem[];\n}\n\ninterface FileSystemEntry {\n isFile: boolean;\n isDirectory: boolean;\n name: string;\n fullPath: string;\n}\n\ninterface FileSystemFileEntry extends FileSystemEntry {\n file: (callback: (file: File) => void, errorCallback?: (error: DOMException) => void) => void;\n}\n\ninterface FileSystemDirectoryEntry extends FileSystemEntry {\n createReader: () => FileSystemDirectoryReader;\n}\n\ninterface FileSystemDirectoryReader {\n readEntries: (\n successCallback: (entries: FileSystemEntry[]) => void,\n errorCallback?: (error: DOMException) => void\n ) => void;\n}\n\nexport class AutorenderUploaderElement extends HTMLElementShim {\n static tagName = 'autorender-uploader';\n\n private shadow: ShadowRoot;\n private controller: UploaderController | null = null;\n private options!: ControllerOptions;\n private labels: Required<LabelSet> = DEFAULT_LABELS;\n private icons: Required<IconSet> = DEFAULT_ICONS;\n private classNames: UploaderClassNames = {};\n private sourceOptions: UploadSourceOption[] = [];\n\n private triggerType: 'button' | 'inline' = 'inline';\n private isModalOpen = false;\n private fileLayout: 'list' | 'grid' = 'list';\n private showGridFileName = true;\n\n private rootElement: HTMLElement | null = null;\n private fileInput!: HTMLInputElement;\n private dropzone: HTMLDivElement | null = null;\n private fileList: HTMLUListElement | null = null;\n private sourceLists: HTMLElement[] = [];\n private modalBody: HTMLElement | null = null;\n private inlineUpload: HTMLElement | null = null;\n private uploadButton: HTMLButtonElement | null = null;\n private triggerButton: HTMLButtonElement | null = null;\n private modalElement: HTMLElement | null = null;\n private modalCloseButton: HTMLButtonElement | null = null;\n private modalDoneButton: HTMLButtonElement | null = null;\n private modalClearButton: HTMLButtonElement | null = null;\n private modalUploadButton: HTMLButtonElement | null = null;\n private modalCancelButton: HTMLButtonElement | null = null;\n private modalAddMoreButton: HTMLButtonElement | null = null;\n private modalFooterActions: HTMLElement | null = null;\n private modalSourceContainer: HTMLElement | null = null;\n private actionsSourceContainer: HTMLElement | null = null;\n private modalTitleElement: HTMLElement | null = null;\n private modalHeaderElement: HTMLElement | null = null;\n private modalPoweredElement: HTMLElement | null = null;\n private inlinePoweredElement: HTMLElement | null = null;\n private duplicateBanners: HTMLElement[] = [];\n private errorBannerElement: HTMLElement | null = null;\n private globalErrorMessage: string | null = null;\n private portalContainer: HTMLElement | null = null;\n private portalDiv: HTMLElement | null = null;\n private isInsideContainer: boolean = false;\n\n private isAbortError(error: unknown): boolean {\n if (!error) return false;\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof Error && error.name === 'AbortError') return true;\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n return typeof message === 'string' && message.toLowerCase().includes('abort');\n }\n\n private controllerListeners = new Map<string, (event: Event) => void>();\n private handleKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && this.isModalOpen) {\n this.isModalOpen = false;\n this.render();\n }\n };\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback() {\n this.render();\n }\n\n disconnectedCallback() {\n this.detachController();\n window.removeEventListener('keydown', this.handleKeydown);\n this.cleanupPortal();\n }\n\n private setupPortal() {\n if (!this.options.container) {\n this.isInsideContainer = false;\n return;\n }\n\n const container = typeof this.options.container === 'string'\n ? document.querySelector<HTMLElement>(this.options.container)\n : this.options.container;\n\n if (!container) {\n console.warn(`Container \"${this.options.container}\" not found`);\n this.isInsideContainer = false;\n return;\n }\n\n // Check if the widget is already inside the container\n // If so, we don't need a portal - everything is already contained\n let currentParent: Node | null = this.parentNode;\n while (currentParent && currentParent !== document.body) {\n if (currentParent === container) {\n // Widget is already inside container, no portal needed\n // But we need to ensure container has position relative for absolute modal positioning\n const containerStyle = window.getComputedStyle(container);\n if (containerStyle.position === 'static') {\n container.style.position = 'relative';\n }\n this.portalContainer = null;\n this.portalDiv = null;\n this.isInsideContainer = true;\n return;\n }\n currentParent = currentParent.parentNode;\n }\n\n // Widget is not inside container, use portal for modal only\n // Ensure container has position relative or absolute for absolute positioning\n const containerStyle = window.getComputedStyle(container);\n if (containerStyle.position === 'static') {\n container.style.position = 'relative';\n }\n\n this.portalContainer = container;\n this.isInsideContainer = false;\n\n // Create or reuse portal div\n if (!this.portalDiv) {\n this.portalDiv = document.createElement('div');\n this.portalDiv.className = 'ar-sdk-portal';\n this.portalDiv.style.position = 'absolute';\n this.portalDiv.style.inset = '0';\n this.portalDiv.style.zIndex = '1000';\n container.appendChild(this.portalDiv);\n }\n }\n\n private cleanupPortal() {\n if (this.portalDiv) {\n this.portalDiv.remove();\n this.portalDiv = null;\n }\n this.portalContainer = null;\n this.isInsideContainer = false;\n }\n\n setController(controller: UploaderController, options: ControllerOptions) {\n this.detachController();\n this.controller = controller;\n this.globalErrorMessage = null;\n this.applyOptions(options);\n this.attachController();\n this.render();\n }\n\n updateOptions(options: Partial<ControllerOptions>) {\n if (!this.controller) return;\n this.applyOptions({ ...this.options, ...options });\n this.controller.setOptions(this.options);\n this.render();\n }\n\n openFileDialog() {\n if (this.triggerType === 'button' && !this.isModalOpen) {\n this.isModalOpen = true;\n this.render();\n requestAnimationFrame(() => this.fileInput?.click());\n return;\n }\n this.fileInput?.click();\n }\n\n private applyOptions(options: ControllerOptions) {\n const previousOptions = this.options ?? ({} as ControllerOptions);\n const themeInput = (options.theme ?? previousOptions.theme ?? DEFAULT_THEME) as ThemeOptions;\n const resolvedTheme = {\n appearance: themeInput.appearance ?? DEFAULT_THEME.appearance,\n borderRadius: themeInput.borderRadius ?? DEFAULT_THEME.borderRadius,\n dropzoneBackground: themeInput.dropzoneBackground ?? DEFAULT_THEME.dropzoneBackground,\n dropzoneBorder: themeInput.dropzoneBorder ?? DEFAULT_THEME.dropzoneBorder,\n fontFamily: themeInput.fontFamily ?? previousOptions.theme?.fontFamily,\n };\n\n // Sources are already normalized by normalizeOptions (empty array if all disabled)\n const resolvedSources = options.sources ?? previousOptions.sources ?? [];\n const previousSourceIds = this.sourceOptions?.map(s => s.id).sort().join(',') ?? '';\n\n // Resolve container\n const containerChanged = previousOptions.container !== options.container;\n if (containerChanged && this.portalDiv && this.portalContainer) {\n // Clean up old portal\n this.portalDiv.remove();\n this.portalDiv = null;\n this.portalContainer = null;\n }\n\n this.options = {\n ...previousOptions,\n ...options,\n theme: resolvedTheme,\n sources: resolvedSources,\n };\n\n // Setup portal if container is specified and widget is not already inside it\n if (this.options.container) {\n this.setupPortal();\n } else {\n this.cleanupPortal();\n }\n\n this.labels = {\n ...DEFAULT_LABELS,\n ...(this.options.labels ?? {}),\n };\n\n this.icons = DEFAULT_ICONS;\n\n const currentSourceIds = resolvedSources.map(s => s.id).sort().join(',');\n const sourcesChanged = previousSourceIds !== currentSourceIds;\n \n this.sourceOptions = resolvedSources;\n this.options.onSourceSelect = options.onSourceSelect ?? previousOptions.onSourceSelect;\n\n const requestedType = this.options.type ?? 'inline';\n this.triggerType = requestedType === 'button' ? 'button' : 'inline';\n this.fileLayout = this.options.fileLayout ?? 'list';\n this.showGridFileName = this.options.showGridFileName ?? true;\n this.classNames = this.options.classNames ?? {};\n\n if (this.options.autoUpload === undefined && this.triggerType === 'inline') {\n this.options.autoUpload = true;\n }\n\n // Re-render source list if sources changed and widget is already rendered\n if (this.rootElement && sourcesChanged) {\n const hasItems = (this.controller?.getState().items.length ?? 0) > 0;\n this.renderSourceOptions(hasItems);\n }\n }\n\n private attachController() {\n if (!this.controller) return;\n\n const stateListener = () => this.updateState();\n const progressListener = () => this.updateState();\n const filesAddedListener = (event: Event) => {\n const detail = (event as CustomEvent<FilesAddedDetail>).detail;\n if (this.options.autoUpload && detail?.items?.length) {\n void this.controller?.uploadAll();\n }\n };\n const completeListener = () => {\n this.clearGlobalError();\n this.render();\n };\n const errorListener = (event: Event) => {\n const detail = (event as CustomEvent).detail;\n this.handleControllerError(detail);\n };\n\n this.controller.addEventListener('statechange', stateListener);\n this.controller.addEventListener('progress', progressListener);\n this.controller.addEventListener('fileprogress', progressListener);\n this.controller.addEventListener('filesadded', filesAddedListener);\n this.controller.addEventListener('complete', completeListener);\n this.controller.addEventListener('error', errorListener);\n\n this.controllerListeners.set('statechange', stateListener);\n this.controllerListeners.set('progress', progressListener);\n this.controllerListeners.set('fileprogress', progressListener);\n this.controllerListeners.set('filesadded', filesAddedListener);\n this.controllerListeners.set('complete', completeListener);\n this.controllerListeners.set('error', errorListener);\n }\n\n private detachController() {\n if (!this.controller) return;\n for (const [event, handler] of this.controllerListeners.entries()) {\n this.controller.removeEventListener(event, handler);\n }\n this.controllerListeners.clear();\n this.controller = null;\n }\n\n private resolveClassName(key: keyof UploaderClassNames, fallback: string) {\n const extra = this.classNames[key];\n return extra ? `${fallback} ${extra}` : fallback;\n }\n\n private render() {\n if (!this.controller) return;\n\n this.setAttribute('data-trigger', this.triggerType);\n\n const duplicateBannerMarkup = `<div class=\"ar-duplicate-banner\" hidden></div>`;\n const errorBannerMarkup = `<div class=\"ar-error-banner\" role=\"alert\" hidden></div>`;\n\n const dropzoneMarkup = `\n <div class=\"${this.resolveClassName('dropzone', 'ar-dropzone')}\" role=\"button\" tabindex=\"0\">\n <div class=\"ar-dropzone-icon\"></div>\n <p class=\"ar-description\">${this.labels.dropzoneTitle}</p>\n </div>\n `;\n\n const fileListMarkup = `<ul class=\"${this.resolveClassName('fileList', 'ar-file-list')}\"></ul>`;\n const sourceListMarkup = '<div class=\"ar-source-list\"></div>';\n\n const modalHeaderMarkup = `\n <div class=\"ar-modal-header\">\n <h3 class=\"ar-modal-title\">${this.labels.title}</h3>\n <button type=\"button\" class=\"ar-modal-close\" aria-label=\"Close\"><span class=\"ar-modal-close-icon\"></span></button>\n </div>\n `;\n\n const inlineHeaderMarkup = `\n <div class=\"ar-modal-header is-inline\">\n <h3 class=\"ar-modal-title\">${this.labels.title}</h3>\n </div>\n `;\n\n const uploadPanelMarkup = `\n <div class=\"ar-modal-body\">\n <div class=\"ar-modal-upload${this.triggerType === 'inline' ? ' is-inline' : ''}\">\n ${dropzoneMarkup}\n ${errorBannerMarkup}\n ${duplicateBannerMarkup}\n ${sourceListMarkup}\n ${fileListMarkup}\n </div>\n </div>\n `;\n\n const footerMarkup = `\n <div class=\"ar-modal-footer${this.triggerType === 'inline' ? ' is-inline' : ''}\">\n <button type=\"button\" class=\"ar-modal-clear\">${this.labels.clear}</button>\n <button type=\"button\" class=\"ar-modal-cancel\">${this.labels.cancel}</button>\n <div class=\"ar-modal-footer-actions\">\n <div class=\"ar-modal-sources\"></div>\n <button type=\"button\" class=\"ar-modal-add-more\">${this.labels.addMore}</button>\n <button type=\"button\" class=\"ar-modal-upload-button\">${this.labels.uploadButton}</button>\n <button type=\"button\" class=\"ar-modal-done\">${this.labels.done}</button>\n </div>\n </div>\n `;\n\n // Add is-portal class if widget is inside container (for absolute positioning) or if using portal div\n const shouldUsePortalPositioning = this.portalDiv || this.isInsideContainer;\n const modalMarkup = this.triggerType === 'button'\n ? `\n <div class=\"${this.resolveClassName('modal', 'ar-modal')} ${this.isModalOpen ? 'is-open' : ''} ${shouldUsePortalPositioning ? 'is-portal' : ''}\">\n <div class=\"ar-modal-backdrop\"></div>\n <div class=\"ar-modal-dialog\">\n ${modalHeaderMarkup}\n ${uploadPanelMarkup}\n ${footerMarkup}\n <div class=\"ar-modal-powered\">Powered by Autorender</div>\n </div>\n </div>\n `\n : '';\n\n const inlineMarkup = this.triggerType === 'inline'\n ? `\n <div class=\"ar-inline-upload\">\n <div class=\"ar-inline-panel\">\n ${inlineHeaderMarkup}\n ${uploadPanelMarkup}\n ${footerMarkup}\n </div>\n <div class=\"ar-inline-powered\">Powered by Autorender</div>\n </div>\n `\n : '';\n\n const template = document.createElement('template');\n template.innerHTML = `\n <style>${widgetStyles}</style>\n <div class=\"${this.resolveClassName('root', 'ar-uploader-root')}\" data-trigger=\"${this.triggerType}\">\n <input type=\"file\" class=\"ar-file-input\" hidden />\n ${\n this.triggerType === 'button'\n ? `<button type=\"button\" class=\"${this.resolveClassName('triggerButton', 'ar-button-trigger')}\"><span class=\"ar-button-icon\"></span><span>${this.labels.selectButton}</span></button>`\n : inlineMarkup\n }\n ${this.portalDiv ? '' : modalMarkup}\n </div>\n `;\n\n this.shadow.innerHTML = '';\n this.shadow.appendChild(template.content.cloneNode(true));\n\n // Render modal in portal if container is specified\n if (this.portalDiv && this.triggerType === 'button') {\n const portalTemplate = document.createElement('template');\n portalTemplate.innerHTML = `<style>${widgetStyles}</style>${modalMarkup}`;\n this.portalDiv.innerHTML = '';\n this.portalDiv.appendChild(portalTemplate.content.cloneNode(true));\n } else if (this.portalDiv && !this.triggerType) {\n // Clean up portal if not needed\n this.portalDiv.innerHTML = '';\n }\n\n this.captureElements();\n this.applyDimensions();\n this.configureInputs();\n this.bindEvents();\n this.applyThemeVariables();\n this.updateState();\n\n if (this.triggerType === 'button') {\n if (this.isModalOpen) {\n window.addEventListener('keydown', this.handleKeydown);\n } else {\n window.removeEventListener('keydown', this.handleKeydown);\n }\n }\n }\n\n private queryModalElement(selector: string): Element | null {\n // Query from portal first if it exists, otherwise from shadow\n if (this.portalDiv) {\n return this.portalDiv.querySelector(selector) || this.shadow.querySelector(selector);\n }\n return this.shadow.querySelector(selector);\n }\n\n private queryModalElements(selector: string): Element[] {\n // Query from portal first if it exists, otherwise from shadow\n if (this.portalDiv) {\n const portalResults = Array.from(this.portalDiv.querySelectorAll(selector));\n const shadowResults = Array.from(this.shadow.querySelectorAll(selector));\n // Combine results (portal takes precedence)\n const combined: Element[] = [];\n portalResults.forEach(el => combined.push(el));\n shadowResults.forEach(el => {\n if (!combined.includes(el)) combined.push(el);\n });\n return combined;\n }\n return Array.from(this.shadow.querySelectorAll(selector));\n }\n\n private captureElements() {\n this.rootElement = this.shadow.querySelector('.ar-uploader-root');\n this.fileInput = this.shadow.querySelector('.ar-file-input') as HTMLInputElement;\n this.dropzone = this.shadow.querySelector('.ar-dropzone');\n this.fileList = this.shadow.querySelector('.ar-file-list');\n this.sourceLists = Array.from(this.shadow.querySelectorAll('.ar-source-list')) as HTMLElement[];\n this.modalBody = this.queryModalElement('.ar-modal-body') as HTMLElement | null;\n this.inlineUpload = this.shadow.querySelector('.ar-inline-upload');\n this.uploadButton = this.shadow.querySelector('.ar-upload-button');\n this.triggerButton = this.shadow.querySelector('.ar-button-trigger');\n this.modalElement = this.queryModalElement('.ar-modal') as HTMLElement | null;\n this.modalCloseButton = this.queryModalElement('.ar-modal-close') as HTMLButtonElement | null;\n this.modalDoneButton = this.queryModalElement('.ar-modal-done') as HTMLButtonElement | null;\n this.modalClearButton = this.queryModalElement('.ar-modal-clear') as HTMLButtonElement | null;\n this.modalUploadButton = this.queryModalElement('.ar-modal-upload-button') as HTMLButtonElement | null;\n this.modalCancelButton = this.queryModalElement('.ar-modal-cancel') as HTMLButtonElement | null;\n this.modalAddMoreButton = this.queryModalElement('.ar-modal-add-more') as HTMLButtonElement | null;\n this.modalFooterActions = this.queryModalElement('.ar-modal-footer-actions') as HTMLElement | null;\n this.modalSourceContainer = this.queryModalElement('.ar-modal-sources') as HTMLElement | null;\n this.actionsSourceContainer = this.shadow.querySelector('.ar-actions-sources');\n this.modalTitleElement = this.queryModalElement('.ar-modal-title') as HTMLElement | null;\n this.modalHeaderElement = this.queryModalElement('.ar-modal-header') as HTMLElement | null;\n this.modalPoweredElement = this.queryModalElement('.ar-modal-powered') as HTMLElement | null;\n this.inlinePoweredElement = this.shadow.querySelector('.ar-inline-powered');\n this.duplicateBanners = this.queryModalElements('.ar-duplicate-banner') as HTMLElement[];\n this.errorBannerElement = this.queryModalElement('.ar-error-banner') as HTMLElement | null;\n this.updateErrorBanner();\n\n const icon = resolveIcon(this.icons.upload);\n const iconContainer = this.shadow.querySelector('.ar-dropzone-icon');\n if (icon && iconContainer) {\n iconContainer.innerHTML = '';\n iconContainer.appendChild(icon);\n }\n const buttonIcon = resolveIcon(this.icons.upload);\n const triggerIconContainer = this.shadow.querySelector('.ar-button-icon');\n if (buttonIcon && triggerIconContainer) {\n triggerIconContainer.innerHTML = '';\n triggerIconContainer.appendChild(buttonIcon);\n }\n const closeIcon = resolveIcon(this.icons.close);\n const closeIconContainer = this.queryModalElement('.ar-modal-close-icon');\n if (closeIcon && closeIconContainer) {\n closeIconContainer.innerHTML = '';\n closeIconContainer.appendChild(closeIcon);\n }\n }\n\n private applyDimensions() {\n if (!this.rootElement) return;\n\n const requestedWidth = this.options.width;\n\n if (requestedWidth === undefined || requestedWidth === null || requestedWidth === '') {\n if (this.triggerType === 'inline') {\n this.rootElement.style.width = '100%';\n } else {\n this.rootElement.style.removeProperty('width');\n }\n return;\n }\n\n const normalizedWidth =\n typeof requestedWidth === 'number' ? `${requestedWidth}px` : requestedWidth;\n this.rootElement.style.width = normalizedWidth;\n }\n\n private configureInputs() {\n this.fileInput?.removeAttribute('webkitdirectory');\n this.fileInput?.removeAttribute('mozdirectory');\n this.fileInput?.removeAttribute('directory');\n\n if (this.options.allowMultiple === false) {\n this.fileInput?.removeAttribute('multiple');\n } else {\n this.fileInput?.setAttribute('multiple', '');\n }\n\n if (this.options.accept?.length) {\n this.fileInput.accept = this.options.accept.join(',');\n }\n }\n\n private bindEvents() {\n this.triggerButton?.addEventListener('click', () => {\n this.isModalOpen = true;\n this.render();\n });\n\n this.modalCloseButton?.addEventListener('click', () => {\n this.isModalOpen = false;\n this.render();\n });\n\n this.modalElement?.addEventListener('click', event => {\n const target = event.target as HTMLElement;\n if (!target) return;\n if (target === this.modalElement || target.classList.contains('ar-modal-backdrop')) {\n this.isModalOpen = false;\n this.render();\n }\n });\n\n this.modalUploadButton?.addEventListener('click', () => {\n if (!this.controller) return;\n if (this.controller.getState().isUploading) return;\n void this.controller.uploadAll();\n });\n\n this.modalDoneButton?.addEventListener('click', () => {\n if (!this.controller) return;\n const state = this.controller.getState();\n const allCompleted = state.items.length > 0 && state.items.every(item => item.status === 'completed');\n if (this.triggerType === 'inline') {\n if (state.isUploading) {\n return;\n }\n if (allCompleted || state.items.length === 0) {\n this.controller.reset();\n this.updateState();\n }\n return;\n }\n if (state.isUploading) {\n this.closeModal();\n return;\n }\n if (allCompleted) {\n this.closeModal();\n return;\n }\n this.closeModal();\n });\n\n this.modalClearButton?.addEventListener('click', () => {\n if (!this.controller) return;\n const { isUploading } = this.controller.getState();\n if (isUploading) {\n return;\n }\n this.controller.reset();\n this.updateState();\n });\n\n this.modalCancelButton?.addEventListener('click', () => {\n if (!this.controller) return;\n const currentState = this.controller.getState();\n if (currentState.isUploading) return;\n this.controller.reset();\n if (this.triggerType === 'inline') {\n this.updateState();\n return;\n }\n this.isModalOpen = false;\n this.render();\n });\n\n this.modalAddMoreButton?.addEventListener('click', () => {\n this.openFileDialog();\n });\n\n this.dropzone?.addEventListener('click', () => this.openFileDialog());\n this.dropzone?.addEventListener('dragenter', event => {\n event.preventDefault();\n this.dropzone?.classList.add('is-dragging');\n });\n this.dropzone?.addEventListener('dragover', event => {\n event.preventDefault();\n this.dropzone?.classList.add('is-dragging');\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n });\n this.dropzone?.addEventListener('dragleave', event => {\n if (event.target === this.dropzone) {\n this.dropzone?.classList.remove('is-dragging');\n }\n });\n this.dropzone?.addEventListener('drop', async event => {\n event.preventDefault();\n this.dropzone?.classList.remove('is-dragging');\n const files = await this.extractFilesFromEvent(event);\n if (files.length) {\n await this.controller?.addFiles(files);\n }\n if (this.fileInput) {\n this.fileInput.value = '';\n }\n });\n\n this.fileInput?.addEventListener('change', async () => {\n const files = this.fileInput?.files ? Array.from(this.fileInput.files) : [];\n const mapped = files.map(file => ({\n file,\n relativePath: (file as File & { webkitRelativePath?: string }).webkitRelativePath,\n }));\n await this.controller?.addFiles(mapped);\n if (this.fileInput) this.fileInput.value = '';\n });\n\n this.uploadButton?.addEventListener('click', () => {\n if (this.controller?.getState().isUploading) return;\n void this.controller?.uploadAll();\n });\n }\n\n private async extractFilesFromEvent(\n event: DragEvent\n ): Promise<Array<{ file: File; relativePath?: string }>> {\n const items = event.dataTransfer?.items;\n\n if (!items) {\n const files = event.dataTransfer?.files ? Array.from(event.dataTransfer.files) : [];\n return files.map(file => ({\n file,\n relativePath: (file as File & { webkitRelativePath?: string }).webkitRelativePath,\n }));\n }\n\n const entries = Array.from(items)\n .map(item => (item.webkitGetAsEntry ? item.webkitGetAsEntry() : null))\n .filter(Boolean) as FileSystemEntry[];\n\n const collected: Array<{ file: File; relativePath?: string }> = [];\n\n for (const entry of entries) {\n const files = await this.readEntry(entry, '');\n collected.push(...files);\n }\n\n return collected;\n }\n\n private readEntry(entry: FileSystemEntry, path = ''): Promise<Array<{ file: File; relativePath?: string }>> {\n return new Promise(resolve => {\n if (entry.isFile) {\n (entry as FileSystemFileEntry).file(file => {\n resolve([{ file, relativePath: path ? `${path}/${file.name}` : file.name }]);\n });\n } else if (entry.isDirectory) {\n const reader = (entry as FileSystemDirectoryEntry).createReader();\n reader.readEntries(async entries => {\n const results = await Promise.all(\n entries.map(child => this.readEntry(child, path ? `${path}/${entry.name}` : entry.name))\n );\n resolve(results.flat());\n });\n } else {\n resolve([]);\n }\n });\n }\n\n private closeModal() {\n this.isModalOpen = false;\n this.render();\n }\n\n private setGlobalError(message: string | null) {\n this.globalErrorMessage = message;\n this.updateErrorBanner();\n }\n\n private clearGlobalError() {\n this.setGlobalError(null);\n }\n\n private updateErrorBanner() {\n if (!this.errorBannerElement) return;\n if (this.globalErrorMessage) {\n this.errorBannerElement.hidden = false;\n this.errorBannerElement.textContent = this.globalErrorMessage;\n } else {\n this.errorBannerElement.hidden = true;\n this.errorBannerElement.textContent = '';\n }\n }\n\n private handleControllerError(error: unknown) {\n if (this.isAbortError(error)) {\n this.clearGlobalError();\n return;\n }\n\n const status =\n typeof error === 'object' && error !== null && 'status' in error\n ? (error as any).status\n : undefined;\n const messageCandidate =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : typeof error === 'string'\n ? error\n : '';\n\n const normalized = String(messageCandidate ?? '').toLowerCase();\n const isAuthError =\n (typeof status === 'number' && (status === 401 || status === 403)) ||\n normalized.includes('unauthorized') ||\n normalized.includes('forbidden') ||\n normalized.includes('invalid api key');\n\n if (isAuthError) {\n this.setGlobalError(this.labels.invalidApiKey);\n } else if (messageCandidate) {\n this.setGlobalError(String(messageCandidate));\n } else {\n this.setGlobalError(this.labels.uploadFailed);\n }\n }\n\n private updateState() {\n if (!this.controller) return;\n if (!this.fileList) return;\n\n const state = this.controller.getState();\n const { items, isUploading, duplicates } = state;\n const hasItems = items.length > 0;\n const hasAuthError = items.some(item => item.error === 'invalid-api-key');\n\n if (hasAuthError) {\n this.setGlobalError(this.labels.invalidApiKey);\n }\n\n if (this.rootElement) {\n this.rootElement.classList.toggle('is-uploading', isUploading);\n this.rootElement.classList.toggle('has-items', hasItems);\n }\n\n if (this.dropzone) {\n if (hasItems) {\n this.dropzone.style.display = 'none';\n } else {\n this.dropzone.style.display = 'flex';\n }\n }\n\n this.renderFileList(items);\n this.updateErrorBanner();\n this.renderSourceOptions(hasItems);\n this.updateModalTitle(items, isUploading);\n this.updateDuplicateBanners(duplicates);\n\n if (this.modalHeaderElement) {\n this.modalHeaderElement.style.display = hasItems ? '' : 'none';\n }\n if (this.modalPoweredElement) {\n this.modalPoweredElement.style.display = hasItems ? 'none' : '';\n }\n if (this.inlinePoweredElement) {\n this.inlinePoweredElement.style.display = hasItems ? 'none' : '';\n }\n\n if (this.triggerType === 'button' || this.triggerType === 'inline') {\n const completedCount = items.filter(item => item.status === 'completed').length;\n const allCompleted = hasItems && completedCount === items.length && completedCount > 0;\n\n if (this.modalFooterActions) {\n this.modalFooterActions.style.display = hasItems ? '' : 'none';\n }\n\n const uploadButton = this.modalUploadButton;\n const doneButton = this.modalDoneButton;\n const cancelButton = this.modalCancelButton;\n const clearButton = this.modalClearButton;\n const addMoreButton = this.modalAddMoreButton;\n\n const showUpload = hasItems && !isUploading && !allCompleted;\n const showAddMore = hasItems && !isUploading && !allCompleted;\n const showDone = hasItems && (isUploading || allCompleted);\n const showClear = hasItems && (isUploading || allCompleted);\n const showInlineCancel =\n this.triggerType === 'inline' && hasItems && !isUploading && !allCompleted;\n const showButtonCancel =\n this.triggerType === 'button' && !isUploading && (!allCompleted || !hasItems);\n const showCancel = showInlineCancel || showButtonCancel;\n\n if (uploadButton) {\n uploadButton.style.display = showUpload ? '' : 'none';\n uploadButton.toggleAttribute('disabled', !showUpload);\n }\n\n if (doneButton) {\n doneButton.style.display = showDone ? '' : 'none';\n doneButton.textContent = this.labels.done;\n doneButton.toggleAttribute('disabled', !showDone);\n }\n\n if (clearButton) {\n clearButton.style.display = showClear ? '' : 'none';\n clearButton.toggleAttribute('disabled', isUploading);\n }\n\n if (cancelButton) {\n cancelButton.style.display = showCancel ? '' : 'none';\n cancelButton.classList.toggle(\n 'is-fullwidth',\n this.triggerType === 'button' && !hasItems\n );\n }\n\n if (addMoreButton) {\n addMoreButton.style.display = showAddMore ? '' : 'none';\n addMoreButton.toggleAttribute('disabled', !showAddMore);\n }\n }\n }\n\n private renderFileList(items: UploadItem[]) {\n if (!this.fileList) return;\n this.fileList.innerHTML = '';\n if (items.length === 0) {\n this.fileList.style.display = 'none';\n this.fileList.classList.remove('is-grid');\n return;\n }\n\n const isGridLayout = this.fileLayout === 'grid';\n this.fileList.style.display = isGridLayout ? 'grid' : 'flex';\n this.fileList.classList.toggle('is-grid', isGridLayout);\n if (isGridLayout) {\n this.fileList.style.gridTemplateColumns = 'repeat(auto-fill, minmax(140px, 1fr))';\n this.fileList.style.gap = '1rem';\n } else {\n this.fileList.style.removeProperty('grid-template-columns');\n this.fileList.style.removeProperty('gap');\n }\n\n const isUploading = this.controller?.getState().isUploading ?? false;\n\n items.forEach(item => {\n const li = document.createElement('li');\n li.className = 'ar-file-item';\n li.classList.toggle('is-grid', isGridLayout);\n\n const isInvalidApiKeyError = item.error === 'invalid-api-key';\n\n if (item.status === 'uploading' || item.status === 'pending') li.classList.add('is-uploading');\n if (item.status === 'completed') li.classList.add('is-completed');\n if (item.status === 'error' && !isInvalidApiKeyError) li.classList.add('is-error');\n\n const header = document.createElement('div');\n header.className = 'ar-file-header';\n header.classList.toggle('is-grid', isGridLayout);\n\n const thumb = document.createElement('div');\n thumb.className = 'ar-file-thumb';\n thumb.classList.toggle('is-grid', isGridLayout);\n const isImage = item.file.type.startsWith('image/');\n if (item.previewUrl && isImage) {\n const img = document.createElement('img');\n img.src = item.previewUrl;\n img.alt = item.file.name;\n thumb.appendChild(img);\n } else {\n // Show document icon for non-images\n thumb.classList.add('ar-file-thumb-document');\n const documentIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n documentIcon.setAttribute('viewBox', '0 0 24 24');\n documentIcon.setAttribute('width', '24');\n documentIcon.setAttribute('height', '24');\n documentIcon.setAttribute('fill', 'none');\n documentIcon.setAttribute('aria-hidden', 'true');\n const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path1.setAttribute('d', 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6Z');\n path1.setAttribute('stroke', 'currentColor');\n path1.setAttribute('stroke-width', '1.5');\n path1.setAttribute('stroke-linecap', 'round');\n path1.setAttribute('stroke-linejoin', 'round');\n const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path2.setAttribute('d', 'M14 2v6h6');\n path2.setAttribute('stroke', 'currentColor');\n path2.setAttribute('stroke-width', '1.5');\n path2.setAttribute('stroke-linecap', 'round');\n path2.setAttribute('stroke-linejoin', 'round');\n documentIcon.appendChild(path1);\n documentIcon.appendChild(path2);\n thumb.appendChild(documentIcon);\n }\n\n if (item.status === 'completed') {\n const statusOverlay = document.createElement('div');\n statusOverlay.className = 'ar-thumb-status';\n const successIcon = resolveIcon(this.icons.success);\n if (successIcon) {\n statusOverlay.appendChild(successIcon);\n }\n thumb.appendChild(statusOverlay);\n } else if (item.status === 'error' && !isInvalidApiKeyError) {\n const statusOverlay = document.createElement('div');\n statusOverlay.className = 'ar-thumb-status is-error';\n const errorIcon = resolveIcon(this.icons.error);\n if (errorIcon) {\n statusOverlay.appendChild(errorIcon);\n }\n thumb.appendChild(statusOverlay);\n }\n\n const name = document.createElement('span');\n name.className = 'ar-file-name';\n name.textContent = item.file.name;\n if (isGridLayout && !this.showGridFileName) {\n name.style.display = 'none';\n } else {\n name.style.display = '';\n }\n\n const removeButton = document.createElement('button');\n removeButton.type = 'button';\n removeButton.className = 'ar-remove-button';\n const shouldShowRemove =\n (item.status === 'pending' ||\n (item.status === 'error' && isInvalidApiKeyError)) &&\n !isUploading;\n removeButton.disabled = !shouldShowRemove;\n removeButton.hidden = !shouldShowRemove;\n removeButton.style.display = shouldShowRemove ? 'inline-flex' : 'none';\n removeButton.classList.toggle('is-grid', isGridLayout);\n const removeIcon = resolveIcon(this.icons.remove);\n if (removeIcon) {\n removeButton.appendChild(removeIcon);\n }\n removeButton.addEventListener('click', () => {\n if (this.controller?.getState().isUploading) return;\n this.controller?.removeFile(item.id);\n });\n\n header.appendChild(thumb);\n header.appendChild(name);\n header.appendChild(removeButton);\n li.appendChild(header);\n\n // Display info message (not error) if present - show it right after header\n if (item.info) {\n const metaRow = document.createElement('div');\n metaRow.className = 'ar-file-meta';\n const infoText = document.createElement('span');\n infoText.className = 'ar-file-info';\n infoText.textContent = item.info;\n metaRow.appendChild(infoText);\n li.appendChild(metaRow);\n }\n\n const progressBorder = document.createElement('div');\n progressBorder.className = 'ar-progress-border';\n\n const progressFill = document.createElement('div');\n progressFill.className = 'ar-progress-fill';\n\n const isPendingStatus = item.status === 'pending';\n const isUploadingStatus = item.status === 'uploading';\n const isCompleteStatus = item.status === 'completed';\n const rawProgress = Math.max(0, Math.min(100, item.progress ?? 0));\n const calculatedTrain = !isCompleteStatus && rawProgress < 20;\n const shouldAnimateTrain = (isUploadingStatus || (isUploading && isPendingStatus)) && calculatedTrain;\n // Keep indicator active if uploading, even if progress hasn't updated recently\n const isActive = isUploadingStatus || shouldAnimateTrain || (rawProgress > 0 && !isCompleteStatus);\n const stateLabel = isCompleteStatus ? 'complete' : shouldAnimateTrain ? 'train' : rawProgress >= 20 ? 'progress' : isUploadingStatus ? 'progress' : 'idle';\n\n progressBorder.dataset.state = stateLabel;\n progressBorder.dataset.status = item.status;\n progressBorder.dataset.progress = rawProgress.toFixed(0);\n\n progressBorder.classList.toggle('is-active', isActive);\n progressBorder.classList.toggle('is-train', shouldAnimateTrain);\n progressBorder.classList.toggle('is-complete', isCompleteStatus);\n progressBorder.style.display = isCompleteStatus ? 'none' : '';\n\n progressFill.classList.toggle('is-train', shouldAnimateTrain);\n progressFill.classList.toggle('is-animating', shouldAnimateTrain);\n\n if (isCompleteStatus) {\n progressFill.style.width = '100%';\n } else if (shouldAnimateTrain) {\n progressFill.style.width = '100%';\n } else if (isUploadingStatus && rawProgress === 0) {\n // Show minimal progress for uploading items even if progress hasn't started\n progressFill.style.width = '3%';\n } else {\n const computedWidth = Math.max(rawProgress, 3);\n progressFill.style.width = `${Math.min(computedWidth, 100)}%`;\n }\n\n progressBorder.appendChild(progressFill);\n\n li.appendChild(progressBorder);\n\n this.fileList?.appendChild(li);\n });\n }\n\n private renderSourceOptions(hasItems: boolean) {\n // Filter out disabled sources - only show enabled ones\n const enabledSources = this.sourceOptions.filter(option => !option.disabled);\n const hasSourcesConfigured = enabledSources.length > 0;\n\n const renderChoiceList = (container: HTMLElement) => {\n container.innerHTML = '';\n if (!hasSourcesConfigured) {\n container.style.display = 'none';\n container.classList.remove('ar-source-list--choices');\n return;\n }\n\n container.style.display = hasItems ? 'none' : 'flex';\n container.classList.toggle('ar-source-list--choices', !hasItems);\n if (hasItems) return;\n\n // Only render enabled sources\n enabledSources.forEach(option => {\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'ar-source-option';\n\n const icon = resolveIcon(option.icon ?? this.icons.upload);\n if (icon) {\n const iconWrapper = document.createElement('span');\n iconWrapper.className = 'ar-source-option-icon';\n iconWrapper.appendChild(icon);\n button.appendChild(iconWrapper);\n }\n\n const label = document.createElement('span');\n label.className = 'ar-source-option-label';\n label.textContent = option.label;\n button.appendChild(label);\n\n button.addEventListener('click', () => this.handleSourceOption(option));\n container.appendChild(button);\n });\n };\n\n this.sourceLists.forEach(container => {\n renderChoiceList(container);\n });\n\n if (this.modalSourceContainer) {\n this.modalSourceContainer.classList.toggle('is-visible', hasSourcesConfigured && !hasItems);\n this.modalSourceContainer.style.display = hasSourcesConfigured ? '' : 'none';\n this.modalSourceContainer.innerHTML = '';\n }\n if (this.actionsSourceContainer) {\n this.actionsSourceContainer.classList.toggle('is-visible', hasSourcesConfigured && !hasItems);\n this.actionsSourceContainer.style.display = hasSourcesConfigured ? '' : 'none';\n this.actionsSourceContainer.innerHTML = '';\n }\n\n // Add class to modal body and inline upload when sources are empty in inline mode\n if (this.triggerType === 'inline') {\n if (this.modalBody) {\n this.modalBody.classList.toggle('ar-modal-body--no-sources', !hasSourcesConfigured);\n }\n if (this.inlineUpload) {\n this.inlineUpload.classList.toggle('ar-inline-upload--no-sources', !hasSourcesConfigured);\n }\n }\n }\n\n private updateModalTitle(items: UploadItem[], isUploading: boolean) {\n if (!this.modalTitleElement) return;\n if (items.length === 0) {\n this.modalTitleElement.textContent = isUploading\n ? this.labels.uploading\n : this.labels.title;\n this.modalTitleElement.classList.remove('is-dynamic', 'is-success');\n return;\n }\n\n const total = items.length;\n const modalTitle = this.modalTitleElement;\n\n const suffix = total === 1 ? 'file' : 'files';\n const completedCount = items.filter(item => item.status === 'completed').length;\n\n modalTitle.classList.add('is-dynamic');\n modalTitle.classList.toggle('is-success', completedCount === total);\n\n if (isUploading) {\n modalTitle.textContent = `Uploading ${completedCount}/${total} ${suffix}`;\n return;\n }\n\n if (completedCount === total) {\n modalTitle.textContent = `${total} ${suffix} uploaded`;\n return;\n }\n\n modalTitle.textContent = `${total} ${suffix} ready`;\n }\n\n private updateDuplicateBanners(duplicates: string[]) {\n const hasDuplicates = duplicates.length > 0;\n const prefix =\n duplicates.length === 1\n ? this.labels.duplicateFileExists\n : this.labels.duplicateFilesExist;\n const message = hasDuplicates\n ? `${prefix} ${duplicates.join(', ')}`\n : '';\n\n this.duplicateBanners.forEach(banner => {\n banner.hidden = !hasDuplicates;\n banner.textContent = message;\n });\n }\n\n private handleSourceOption(option: UploadSourceOption) {\n if (option.disabled) return;\n\n this.options.onSourceSelect?.(option);\n this.dispatchEvent(new CustomEvent('sourceselect', { detail: option }));\n\n if (option.kind === 'device' && !option.action) {\n this.openFileDialog();\n return;\n }\n\n if (option.action) {\n try {\n option.action();\n } catch (error) {\n console.error('[AutorenderUploader] Source action failed', error);\n }\n return;\n }\n\n console.warn('[AutorenderUploader] No handler configured for source option', option);\n }\n\n private applyThemeVariables() {\n const theme = (this.options.theme ?? {}) as ThemeOptions;\n const borderRadius = theme.borderRadius;\n const accentColor = theme.accentColor;\n const dropzoneBackground = theme.dropzoneBackground ?? DEFAULT_THEME.dropzoneBackground;\n const dropzoneBorder = theme.dropzoneBorder ?? DEFAULT_THEME.dropzoneBorder;\n const fontFamily = theme.fontFamily;\n\n if (borderRadius !== undefined) {\n this.style.setProperty(\n '--ar-radius',\n typeof borderRadius === 'number' ? `${borderRadius}px` : String(borderRadius)\n );\n } else {\n this.style.removeProperty('--ar-radius');\n }\n\n // Only set accent color if explicitly provided; otherwise let palette CSS handle it\n if (accentColor) {\n this.style.setProperty('--ar-color-accent', accentColor);\n } else {\n this.style.removeProperty('--ar-color-accent');\n }\n\n if (dropzoneBackground) {\n this.style.setProperty('--ar-dropzone-bg', dropzoneBackground);\n }\n if (dropzoneBorder) {\n this.style.setProperty('--ar-dropzone-border', dropzoneBorder);\n }\n if (fontFamily) {\n this.style.setProperty('--ar-font-family', fontFamily);\n }\n\n const appearance = theme.appearance ?? DEFAULT_THEME.appearance;\n let resolvedAppearance = appearance;\n if (appearance === 'system' && typeof window !== 'undefined') {\n resolvedAppearance = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n this.setAttribute('data-theme', resolvedAppearance);\n\n // Apply palette\n const palette = this.options.palette;\n if (palette) {\n this.setAttribute('data-palette', palette);\n } else {\n this.removeAttribute('data-palette');\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'autorender-uploader': AutorenderUploaderElement;\n }\n}","/**\n * Device detection utilities for DPR and connection quality\n */\n\nexport function getDPR(): number {\n if (typeof window === 'undefined') return 1;\n const dpr = window.devicePixelRatio || 1;\n // Round to 1 or 2 for most cases (can be extended to 3 for high-DPI)\n return dpr >= 2 ? 2 : 1;\n}\n\n// export function getConnectionQuality(): '2g' | '3g' | '4g' | 'wifi' | 'unknown' {\n\n// if (typeof navigator === 'undefined') return 'unknown';\n \n// // Check for Network Information API\n// const connection = (navigator as any).connection || \n// (navigator as any).mozConnection || \n// (navigator as any).webkitConnection;\n \n// if (!connection) return 'unknown';\n \n// const effectiveType = connection.effectiveType || connection.effectiveConnectionType;\n// const type = connection.type;\n \n// // Use effectiveType if available (Chrome/Edge)\n// if (effectiveType) {\n// if (effectiveType === 'slow-2g' || effectiveType === '2g') return '2g';\n// if (effectiveType === '3g') return '3g';\n// if (effectiveType === '4g') return '4g';\n// }\n \n// // Fallback to type (older API)\n// if (type) {\n// if (type === 'cellular') {\n// // Try to infer from downlink\n// const downlink = connection.downlink;\n// if (downlink) {\n// if (downlink < 0.5) return '2g';\n// if (downlink < 1.5) return '3g';\n// return '4g';\n// }\n// return '3g'; // Default for cellular\n// }\n// if (type === 'wifi' || type === 'ethernet') return 'wifi';\n// }\n \n// return 'unknown';\n// }\n\n// export function getQualityForConnection(connectionQuality: '2g' | '3g' | '4g' | 'wifi' | 'unknown' | 'auto'): string | number {\n// if (connectionQuality === 'auto') {\n// const detected = getConnectionQuality();\n// return getQualityForConnection(detected);\n// }\n \n// switch (connectionQuality) {\n// case '2g':\n// return 50;\n// case '3g':\n// return 70;\n// case '4g':\n// case 'wifi':\n// return 'auto';\n// default:\n// return 'auto';\n// }\n// }\n\n\nexport type ConnectionQuality = '2g' | '3g' | '4g' | 'wifi' | 'unknown';\nexport type QualityMode = 'auto' | 50 | 70 | 75;\n\ntype ConnectionResult = {\n quality: ConnectionQuality;\n reason: string;\n saveData: boolean;\n effectiveType?: string;\n downlinkMbps?: number;\n rttMs?: number;\n};\n\nfunction getNavigatorConnection(): any | null {\n if (typeof navigator === 'undefined') return null;\n const nav: any = navigator;\n return nav.connection || nav.mozConnection || nav.webkitConnection || null;\n}\n\n/**\n * Production-ready connection detection:\n * - \"wifi\" is only returned when the API truly exposes type === 'wifi'/'ethernet'.\n * - Otherwise we stick to effectiveType (2g/3g/4g) or unknown.\n * - saveData is captured as a strong signal.\n */\nexport function getConnectionQualityDetailed(): ConnectionResult {\n if (typeof navigator === 'undefined') {\n return { quality: 'unknown', reason: 'ssr:no-navigator', saveData: false };\n }\n\n const connection = getNavigatorConnection();\n if (!connection) {\n return { quality: 'unknown', reason: 'no-network-info-api', saveData: false };\n }\n\n const saveData = connection.saveData === true;\n\n // Strong hint: user explicitly wants reduced data usage.\n // We still return a \"quality\" label for UI, but you should act on saveData in your quality logic.\n const effectiveType: string | undefined =\n connection.effectiveType || connection.effectiveConnectionType;\n\n const downlinkMbps: number | undefined =\n typeof connection.downlink === 'number' ? connection.downlink : undefined;\n\n const rttMs: number | undefined =\n typeof connection.rtt === 'number' ? connection.rtt : undefined;\n\n // 1) Preferred: effectiveType (Chromium mostly)\n if (effectiveType) {\n if (effectiveType === 'slow-2g' || effectiveType === '2g') {\n return { quality: '2g', reason: `effectiveType:${effectiveType}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n if (effectiveType === '3g') {\n return { quality: '3g', reason: 'effectiveType:3g', saveData, effectiveType, downlinkMbps, rttMs };\n }\n if (effectiveType === '4g') {\n // Note: 4g might still be cellular or wifi; effectiveType doesn't mean wifi.\n return { quality: '4g', reason: 'effectiveType:4g', saveData, effectiveType, downlinkMbps, rttMs };\n }\n }\n\n // 2) Optional: connection.type (rarely available in modern browsers)\n // Only return \"wifi\" if the browser explicitly says so.\n const type: string | undefined = connection.type;\n if (type === 'wifi' || type === 'ethernet') {\n return { quality: 'wifi', reason: `type:${type}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n\n // 3) Soft fallback: infer from downlink IF we have it.\n // Thresholds are conservative and should be treated as a hint.\n if (typeof downlinkMbps === 'number') {\n if (downlinkMbps < 0.7) {\n return { quality: '2g', reason: `downlink<0.7Mbps:${downlinkMbps}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n if (downlinkMbps < 1.8) {\n return { quality: '3g', reason: `downlink<1.8Mbps:${downlinkMbps}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n return { quality: '4g', reason: `downlink>=1.8Mbps:${downlinkMbps}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n\n return { quality: 'unknown', reason: 'insufficient-signals', saveData, effectiveType, downlinkMbps, rttMs };\n}\n\nexport function getConnectionQuality(): ConnectionQuality {\n return getConnectionQualityDetailed().quality;\n}\n\n/**\n * Production-ready quality selection:\n * - saveData => force low quality (strongest signal)\n * - 2g => q_50\n * - 3g => q_70\n * - 4g/wifi/unknown => 'auto' (your server-side q_auto policy) OR 75 if you want fixed\n */\nexport function getQualityForConnection(\n input: ConnectionQuality | 'auto',\n opts?: {\n // What to do when connection is unknown / high quality:\n // 'auto' means let AutoRender decide (q_auto)\n // 75 means fixed quality\n highQuality?: 'auto' | 75;\n // If user enabled data saver, override everything\n saveDataQuality?: 50 | 70;\n }\n): QualityMode {\n const highQuality = opts?.highQuality ?? 'auto';\n const saveDataQuality = opts?.saveDataQuality ?? 50;\n\n if (input === 'auto') {\n const detected = getConnectionQualityDetailed();\n if (detected.saveData) return saveDataQuality;\n return getQualityForConnection(detected.quality, opts);\n }\n\n switch (input) {\n case '2g':\n return 50;\n case '3g':\n return 70;\n case '4g':\n case 'wifi':\n return highQuality;\n default:\n return highQuality; // unknown -> don't degrade unless you are sure\n }\n}\n\n","/**\n * Browser format detection utilities\n * Detects which image formats the browser supports\n */\n\nlet cachedFormat: string | null = null;\n\n/**\n * Detect the best image format supported by the browser\n * Priority: AVIF > WebP > JPEG\n * Uses synchronous detection for immediate results\n */\nexport function detectBestFormat(): string {\n if (cachedFormat !== null) {\n return cachedFormat;\n }\n\n if (typeof document === 'undefined' || typeof Image === 'undefined') {\n // Server-side or non-browser environment\n cachedFormat = 'webp';\n return cachedFormat;\n }\n\n // Synchronous detection using canvas.toDataURL\n try {\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n cachedFormat = 'webp';\n return cachedFormat;\n }\n\n // Test AVIF\n try {\n const avifDataURL = canvas.toDataURL('image/avif');\n if (avifDataURL && avifDataURL.indexOf('data:image/avif') === 0) {\n cachedFormat = 'avif';\n return cachedFormat;\n }\n } catch (e) {\n // AVIF not supported\n }\n\n // Test WebP\n try {\n const webpDataURL = canvas.toDataURL('image/webp');\n if (webpDataURL && webpDataURL.indexOf('data:image/webp') === 0) {\n cachedFormat = 'webp';\n return cachedFormat;\n }\n } catch (e) {\n // WebP not supported\n }\n\n // Fallback to JPEG\n cachedFormat = 'jpg';\n return cachedFormat;\n } catch (e) {\n // Fallback to WebP if detection fails\n cachedFormat = 'webp';\n return cachedFormat;\n }\n}\n\n\n/**\n * Get the best format synchronously (uses cached value or detects)\n */\nexport function getBestFormatSync(): string {\n if (cachedFormat !== null) {\n return cachedFormat;\n }\n return detectBestFormat();\n}\n\n/**\n * Reset cached format (useful for testing)\n */\nexport function resetFormatCache(): void {\n cachedFormat = null;\n}\n\n","/**\n * Transformation builder - converts TransformOptions to URL transformation string\n * with deterministic sorting\n */\n\nimport type { TransformOptions, LayerOptions } from './types';\nimport { getDPR, getQualityForConnection } from './device';\nimport { getBestFormatSync } from './format-detection';\n\ninterface TransformationPart {\n param: string;\n value: string;\n sortKey: string; // For deterministic sorting\n}\n\n/**\n * Build transformation string from options\n * Transformations are sorted alphabetically by param prefix\n */\nexport function buildTransformString(\n transform: TransformOptions,\n defaults?: { f?: string; q?: string | number; [key: string]: any },\n enableDPR: boolean = true,\n connectionQuality?: 'auto' | '2g' | '3g' | '4g' | 'wifi'\n): string {\n const parts: TransformationPart[] = [];\n \n // Helper to add transformation part\n const addPart = (param: string, value: string | number | boolean) => {\n if (value === undefined || value === null) return;\n \n let valueStr: string;\n if (typeof value === 'boolean') {\n valueStr = value ? '' : '';\n if (!value) return; // Skip false booleans\n } else {\n valueStr = String(value);\n }\n \n // Create sort key: param prefix determines order\n // Special handling: dpr_ should come early, but after basic size params\n let sortKey = param;\n if (param.startsWith('dpr_')) {\n sortKey = 'dpr_' + param; // Keep dpr early\n } else if (param.startsWith('a_')) {\n sortKey = 'a_' + param; // Text rotation\n } else if (param.startsWith('ar_')) {\n sortKey = 'ar_' + param;\n } else if (param.startsWith('bg_')) {\n sortKey = 'bg_' + param;\n } else if (param.startsWith('c_')) {\n sortKey = 'c_' + param;\n } else if (param.startsWith('co_')) {\n sortKey = 'co_' + param; // Text color\n } else if (param.startsWith('e_')) {\n sortKey = 'e_' + param;\n } else if (param.startsWith('f_')) {\n sortKey = 'f_' + param;\n } else if (param.startsWith('fl_')) {\n sortKey = 'fl_' + param;\n } else if (param.startsWith('fo_')) {\n sortKey = 'fo_' + param;\n } else if (param.startsWith('flip_')) {\n sortKey = 'flip_' + param;\n } else if (param.startsWith('h_')) {\n sortKey = 'h_' + param;\n } else if (param.startsWith('ip_')) {\n sortKey = 'ip_' + param; // Image layer placement\n } else if (param.startsWith('k_')) {\n sortKey = 'k_' + param;\n } else if (param.startsWith('l_')) {\n sortKey = 'l_' + param;\n } else if (param.startsWith('la_')) {\n sortKey = 'la_' + param;\n } else if (param.startsWith('lar_')) {\n sortKey = 'lar_' + param;\n } else if (param.startsWith('lbg_')) {\n sortKey = 'lbg_' + param;\n } else if (param.startsWith('lc_')) {\n sortKey = 'lc_' + param;\n } else if (param.startsWith('le_')) {\n sortKey = 'le_' + param;\n } else if (param.startsWith('lf_')) {\n sortKey = 'lf_' + param;\n } else if (param.startsWith('lflip_')) {\n sortKey = 'lflip_' + param;\n } else if (param.startsWith('lh_')) {\n sortKey = 'lh_' + param;\n } else if (param.startsWith('lp_')) {\n sortKey = 'lp_' + param;\n } else if (param.startsWith('lq_')) {\n sortKey = 'lq_' + param;\n } else if (param.startsWith('lr_')) {\n sortKey = 'lr_' + param;\n } else if (param.startsWith('ltype_')) {\n sortKey = 'ltype_' + param;\n } else if (param.startsWith('lw_')) {\n sortKey = 'lw_' + param;\n } else if (param.startsWith('lzoom_')) {\n sortKey = 'lzoom_' + param;\n } else if (param.startsWith('lbr_')) {\n sortKey = 'lbr_' + param;\n } else if (param.startsWith('o_')) {\n sortKey = 'o_' + param; // Opacity\n } else if (param.startsWith('p_')) {\n sortKey = 'p_' + param;\n } else if (param.startsWith('ps_')) {\n sortKey = 'ps_' + param;\n } else if (param.startsWith('q_')) {\n sortKey = 'q_' + param;\n } else if (param.startsWith('r_')) {\n sortKey = 'r_' + param;\n } else if (param.startsWith('tp_')) {\n sortKey = 'tp_' + param; // Text placement\n } else if (param.startsWith('w_')) {\n sortKey = 'w_' + param;\n } else if (param.startsWith('x_')) {\n sortKey = 'x_' + param;\n } else if (param.startsWith('y_')) {\n sortKey = 'y_' + param;\n } else if (param.startsWith('z_')) {\n sortKey = 'z_' + param;\n } else if (param.startsWith('br_')) {\n sortKey = 'br_' + param;\n }\n \n parts.push({ param, value: valueStr, sortKey });\n };\n \n // Size & Crop\n if (transform.w !== undefined) addPart('w_', transform.w);\n if (transform.h !== undefined) addPart('h_', transform.h);\n if (transform.fit) {\n const fitMap: Record<string, string> = {\n crop: 'crop',\n fill: 'fill',\n fit: 'fit',\n scale: 'scale'\n };\n addPart('c_', fitMap[transform.fit] || transform.fit);\n }\n if (transform.ar) addPart('ar_', transform.ar);\n if (transform.p) addPart('p_', transform.p);\n if (transform.ps) addPart('ps_', transform.ps);\n if (transform.focus) addPart('fo_', transform.focus);\n \n // Transform\n if (transform.r !== undefined) addPart('r_', transform.r);\n if (transform.z !== undefined) addPart('z_', transform.z);\n if (transform.flip) addPart('flip_', transform.flip);\n if (transform.br !== undefined) addPart('br_', transform.br);\n \n // Format & Quality\n let format = transform.f ?? defaults?.f;\n // If format is 'auto', detect browser support\n if (format === 'auto' || format === undefined) {\n format = getBestFormatSync();\n }\n if (format) addPart('f_', format);\n \n // Quality: use connection quality if auto, otherwise use transform or default\n let quality = transform.q;\n \n // If quality is explicitly set to a number, use it\n // If quality is 'auto' or undefined, resolve using connection quality\n if (quality === 'auto' || quality === undefined) {\n const defaultQuality = defaults?.q;\n \n // If transform doesn't specify quality, use default\n if (quality === undefined) {\n quality = defaultQuality;\n }\n \n // If quality is 'auto' (from transform or defaults), resolve using connection quality\n if (quality === 'auto' || quality === undefined) {\n if (connectionQuality) {\n // Resolve 'auto' to actual quality based on connection\n // connectionQuality is already resolved (not 'auto') when passed from createAR\n const resolvedQuality = getQualityForConnection(connectionQuality);\n quality = resolvedQuality;\n } else {\n // No connection info available, keep as 'auto'\n quality = 'auto';\n }\n }\n }\n // If quality is explicitly set to a number, use it as-is (no connection-based adjustment)\n \n if (quality !== undefined) addPart('q_', quality);\n \n // Background\n if (transform.bg) {\n if (transform.bg.startsWith('rgb:')) {\n addPart('bg_rgb:', transform.bg.replace('rgb:', ''));\n } else {\n addPart('bg_', transform.bg);\n }\n }\n \n // Kernel\n if (transform.k) addPart('k_', transform.k);\n \n // DPR (auto-inject if enabled and not explicitly set)\n if (enableDPR && transform.dpr === undefined) {\n const dpr = getDPR();\n if (dpr !== 1) addPart('dpr_', dpr);\n } else if (transform.dpr !== undefined) {\n addPart('dpr_', transform.dpr);\n }\n \n // Effects (e_*)\n if (transform.improve !== undefined) {\n if (typeof transform.improve === 'boolean' && transform.improve) {\n addPart('e_improve', '');\n } else if (typeof transform.improve === 'string') {\n addPart('e_improve', transform.improve);\n } else if (typeof transform.improve === 'object') {\n const { mode, blend } = transform.improve;\n let value = mode || '';\n if (blend !== undefined) value += `:${blend}`;\n addPart('e_improve', value);\n }\n }\n if (transform.unsharpMask !== undefined) addPart('e_unsharp_mask:', transform.unsharpMask);\n if (transform.saturation !== undefined) addPart('e_saturation:', transform.saturation);\n if (transform.contrast !== undefined) addPart('e_contrast:', transform.contrast);\n if (transform.brightness !== undefined) addPart('e_brightness:', transform.brightness);\n if (transform.gamma !== undefined) addPart('e_gamma:', transform.gamma);\n if (transform.sharpen !== undefined) {\n if (typeof transform.sharpen === 'boolean' && transform.sharpen) {\n addPart('e_sharpen', '');\n } else {\n addPart('e_sharpen:', transform.sharpen);\n }\n }\n if (transform.grayscale) addPart('e_grayscale', '');\n if (transform.blackwhite !== undefined) addPart('e_blackwhite:', transform.blackwhite);\n if (transform.hue !== undefined) addPart('e_hue:', transform.hue);\n if (transform.warmth !== undefined) addPart('e_warmth:', transform.warmth);\n if (transform.tint !== undefined) addPart('e_tint:', transform.tint);\n if (transform.normalize) addPart('e_normalize', '');\n if (transform.invert) addPart('e_invert', '');\n if (transform.fade !== undefined) addPart('e_fade:', transform.fade);\n if (transform.vignette !== undefined) addPart('e_vignette:', transform.vignette);\n if (transform.highlights !== undefined) addPart('e_highlights:', transform.highlights);\n if (transform.shadows !== undefined) addPart('e_shadows:', transform.shadows);\n if (transform.exposure !== undefined) addPart('e_exposure:', transform.exposure);\n if (transform.structure !== undefined) addPart('e_structure:', transform.structure);\n if (transform.autoEnhance) addPart('e_auto_enhance', '');\n if (transform.temperature !== undefined) addPart('e_temperature:', transform.temperature);\n if (transform.linear) addPart('e_linear:', transform.linear);\n if (transform.recomb) addPart('e_recomb:', transform.recomb);\n if (transform.threshold !== undefined) addPart('e_threshold:', transform.threshold);\n if (transform.convolve) addPart('e_convolve:', transform.convolve);\n if (transform.unflatten) addPart('e_unflatten', '');\n if (transform.flatten) addPart('e_flatten', '');\n if (transform.median !== undefined) addPart('e_median:', transform.median);\n if (transform.blur !== undefined) addPart('e_blur:', transform.blur);\n if (transform.extend) addPart('e_extend:', transform.extend);\n if (transform.affine) addPart('e_affine:', transform.affine);\n if (transform.extract) addPart('e_extract:', transform.extract);\n if (transform.ensureAlpha) addPart('e_ensure_alpha', '');\n if (transform.removeAlpha) addPart('e_remove_alpha:', transform.removeAlpha);\n \n // Blend mode (for layers)\n if (transform.blend) addPart('e_', transform.blend);\n \n // Raw transformations (for advanced users)\n Object.keys(transform).forEach(key => {\n if (key.startsWith('_') || \n ['w', 'h', 'fit', 'ar', 'p', 'ps', 'focus', 'r', 'z', 'flip', 'br', 'f', 'q', 'bg', 'k', 'dpr',\n 'improve', 'unsharpMask', 'saturation', 'contrast', 'brightness', 'gamma', 'sharpen',\n 'grayscale', 'blackwhite', 'hue', 'warmth', 'tint', 'normalize', 'invert', 'fade',\n 'vignette', 'highlights', 'shadows', 'exposure', 'structure', 'autoEnhance', 'temperature',\n 'linear', 'recomb', 'threshold', 'convolve', 'unflatten', 'flatten', 'median', 'blur',\n 'extend', 'affine', 'extract', 'ensureAlpha', 'removeAlpha', 'blend', 'layers'].includes(key)) {\n return; // Skip already processed keys\n }\n \n // Allow raw transformation strings\n if (typeof transform[key] === 'string' || typeof transform[key] === 'number' || typeof transform[key] === 'boolean') {\n addPart(key, transform[key] as any);\n }\n });\n \n // Sort base transformation parts deterministically by param prefix\n parts.sort((a, b) => {\n // Extract prefix for comparison\n const prefixA = a.param.split('_')[0] + '_';\n const prefixB = b.param.split('_')[0] + '_';\n \n if (prefixA !== prefixB) {\n return prefixA.localeCompare(prefixB);\n }\n \n // Same prefix, compare full param\n return a.param.localeCompare(b.param);\n });\n \n // Build base transformation string\n const baseTransform = parts.map(p => {\n if (p.value === '') {\n return p.param; // Boolean flags without values\n }\n return `${p.param}${p.value}`;\n }).join(',');\n \n // Build layers separately - each layer must end with fl_layer_apply\n const layerParts: string[] = [];\n if (transform.layers && transform.layers.length > 0) {\n transform.layers.forEach(layer => {\n const layerTransformParts: TransformationPart[] = [];\n \n const addLayerPart = (param: string, value: string | number | boolean) => {\n if (value === undefined || value === null) return;\n \n let valueStr: string;\n if (typeof value === 'boolean') {\n valueStr = value ? '' : '';\n if (!value) return; // Skip false booleans\n } else {\n valueStr = String(value);\n }\n \n layerTransformParts.push({\n param,\n value: valueStr,\n sortKey: param\n });\n };\n \n buildLayerTransform(layer, addLayerPart);\n \n // Sort layer parts with specific order (not alphabetical)\n // Order: l_image/l_text first, then ip_/tp_, then other params, then fl_layer_apply\n const applyFlag = layerTransformParts.find(p => p.param === 'fl_layer_apply');\n const regularParts = layerTransformParts.filter(p => p.param !== 'fl_layer_apply');\n \n // Define order priority for layer parameters\n const getLayerParamOrder = (param: string): number => {\n // l_image or l_text must be first\n if (param.startsWith('l_image:') || param.startsWith('l_text:')) return 0;\n // ip_ (image placement) or tp_ (text placement) comes right after l_image/l_text\n if (param.startsWith('ip_') || param.startsWith('tp_')) return 1;\n // l_type comes after placement\n if (param.startsWith('l_type:')) return 2;\n // lw_, lh_ come after l_type\n if (param.startsWith('lw_')) return 3;\n if (param.startsWith('lh_')) return 4;\n // o_ (opacity) comes after dimensions\n if (param.startsWith('o_')) return 5;\n // Other layer params\n if (param.startsWith('l')) return 6;\n // co_ (color) for text\n if (param.startsWith('co_')) return 7;\n // a_ (rotation) for text\n if (param.startsWith('a_')) return 8;\n // lr_ (rotation) for image\n if (param.startsWith('lr_')) return 8;\n // x_, y_ offsets\n if (param.startsWith('x_') || param.startsWith('y_')) return 9;\n // le_ (layer enhancements)\n if (param.startsWith('le_')) return 10;\n // e_ (blend mode)\n if (param.startsWith('e_')) return 11;\n // Everything else\n return 100;\n };\n \n regularParts.sort((a, b) => {\n const orderA = getLayerParamOrder(a.param);\n const orderB = getLayerParamOrder(b.param);\n \n if (orderA !== orderB) {\n return orderA - orderB;\n }\n \n // Same order priority, sort alphabetically\n return a.param.localeCompare(b.param);\n });\n \n // Build layer string: regular parts + fl_layer_apply at the end\n const layerString = [\n ...regularParts.map(p => p.value === '' ? p.param : `${p.param}${p.value}`),\n ...(applyFlag ? [applyFlag.param] : [])\n ].join(',');\n \n if (layerString) {\n layerParts.push(layerString);\n }\n });\n }\n \n // Combine: base transformations + layers\n const allParts = baseTransform ? [baseTransform, ...layerParts] : layerParts;\n return allParts.join(',');\n}\n\nfunction buildLayerTransform(layer: LayerOptions, addPart: (param: string, value: string | number | boolean) => void) {\n if (layer.type === 'text') {\n // Build text layer: l_text:fontFamily_fontSize_style:text\n // Example: l_text:arial_24_bold:Demo\n const parts: string[] = [];\n if (layer.fontFamily) parts.push(layer.fontFamily);\n if (layer.fontSize !== undefined) parts.push(String(layer.fontSize));\n if (layer.fontStyle) parts.push(layer.fontStyle);\n if (layer.align) parts.push(layer.align);\n \n const text = layer.text ? encodeURIComponent(layer.text) : '';\n const layerSpec = parts.length > 0 ? `${parts.join('_')}:${text}` : text;\n addPart('l_text:', layerSpec);\n \n // Text layer modifiers (after l_text)\n if (layer.fontColor) {\n // Remove # if present, convert to hex without #\n const color = layer.fontColor.replace('#', '');\n addPart('co_', color);\n }\n if (layer.placement) {\n // Convert placement to short form if needed\n const placement = normalizePlacement(layer.placement);\n if (placement) addPart('tp_', placement);\n }\n if (layer.rotation !== undefined) addPart('a_', layer.rotation);\n if (layer.x !== undefined) addPart('x_', layer.x);\n if (layer.y !== undefined) addPart('y_', layer.y);\n } else if (layer.type === 'image') {\n // Image layer: l_image:imagePath\n // Order: l_image, l_type, lw, lh, ip, o, fl_layer_apply\n // Example: l_image:fav.png,l_type:overlay,lw_200,lh_200,ip_ne,o_100,fl_layer_apply\n if (layer.imagePath) {\n addPart('l_image:', layer.imagePath);\n }\n \n // Image layer modifiers in correct order\n if (layer.layerType) addPart('l_type:', layer.layerType);\n if (layer.width !== undefined) addPart('lw_', layer.width);\n if (layer.height !== undefined) addPart('lh_', layer.height);\n if (layer.placement) {\n // Convert placement to short form if needed\n const placement = normalizePlacement(layer.placement);\n if (placement) addPart('ip_', placement);\n }\n if (layer.opacity !== undefined) addPart('o_', layer.opacity);\n if (layer.rotation !== undefined) addPart('lr_', layer.rotation);\n if (layer.crop) addPart('lc_', layer.crop);\n if (layer.aspectRatio) addPart('lar_', layer.aspectRatio);\n if (layer.quality !== undefined) addPart('lq_', layer.quality);\n if (layer.format) addPart('lf_', layer.format);\n if (layer.background) addPart('lbg_', layer.background);\n if (layer.position) addPart('lp_', layer.position);\n if (layer.borderRadius !== undefined) addPart('lbr_', layer.borderRadius);\n if (layer.flip) addPart('lflip_', layer.flip);\n if (layer.zoom !== undefined) addPart('lzoom_', layer.zoom);\n if (layer.x !== undefined) addPart('x_', layer.x);\n if (layer.y !== undefined) addPart('y_', layer.y);\n if (layer.blendMode) addPart('e_', layer.blendMode);\n \n // Layer enhancements (le_*)\n if (layer.enhance) {\n const enhance = layer.enhance;\n if (enhance.improve !== undefined) {\n if (typeof enhance.improve === 'boolean' && enhance.improve) {\n addPart('le_improve', '');\n } else if (typeof enhance.improve === 'string') {\n addPart('le_improve', enhance.improve);\n }\n }\n if (enhance.sharpen !== undefined) addPart('le_sharpen:', enhance.sharpen);\n if (enhance.brightness !== undefined) addPart('le_brightness:', enhance.brightness);\n if (enhance.saturation !== undefined) addPart('le_saturation:', enhance.saturation);\n if (enhance.contrast !== undefined) addPart('le_contrast:', enhance.contrast);\n if (enhance.hue !== undefined) addPart('le_hue:', enhance.hue);\n if (enhance.warmth !== undefined) addPart('le_warmth:', enhance.warmth);\n if (enhance.tint !== undefined) addPart('le_tint:', enhance.tint);\n if (enhance.normalize) addPart('le_normalize', '');\n if (enhance.invert) addPart('le_invert', '');\n if (enhance.fade !== undefined) addPart('le_fade:', enhance.fade);\n if (enhance.vignette !== undefined) addPart('le_vignette:', enhance.vignette);\n if (enhance.highlights !== undefined) addPart('le_highlights:', enhance.highlights);\n if (enhance.shadows !== undefined) addPart('le_shadows:', enhance.shadows);\n if (enhance.exposure !== undefined) addPart('le_exposure:', enhance.exposure);\n if (enhance.structure !== undefined) addPart('le_structure:', enhance.structure);\n if (enhance.autoEnhance) addPart('le_auto_enhance', '');\n if (enhance.temperature !== undefined) addPart('le_temperature:', enhance.temperature);\n if (enhance.blackwhite !== undefined) addPart('le_blackwhite:', enhance.blackwhite);\n if (enhance.gamma !== undefined) addPart('le_gamma:', enhance.gamma);\n if (enhance.unsharpMask !== undefined) addPart('le_unsharp_mask:', enhance.unsharpMask);\n if (enhance.grayscale) addPart('le_grayscale', '');\n }\n }\n \n // Layer apply flag (always at the end)\n addPart('fl_layer_apply', '');\n}\n\n/**\n * Normalize placement values to short form\n * north -> n, north-east -> ne, etc.\n */\nfunction normalizePlacement(placement: string): string {\n const mapping: Record<string, string> = {\n 'north': 'n',\n 'south': 's',\n 'east': 'e',\n 'west': 'w',\n 'center': 'c',\n 'north-west': 'nw',\n 'north-east': 'ne',\n 'south-west': 'sw',\n 'south-east': 'se',\n 'none': 'none'\n };\n return mapping[placement.toLowerCase()] || placement.toLowerCase();\n}\n\n","/**\n * URL builder for AutoRender image URLs\n */\n\nimport { buildTransformString } from './transform';\nimport type { TransformOptions } from './types';\n\nexport function buildImageUrl(\n baseUrl: string,\n workspace: string,\n src: string,\n transform?: TransformOptions,\n defaults?: { f?: string; q?: string | number; [key: string]: any },\n enableDPR: boolean = true,\n connectionQuality?: 'auto' | '2g' | '3g' | '4g' | 'wifi'\n): string {\n // Normalize base URL (remove trailing slashes)\n const normalizedBase = baseUrl.replace(/\\/+$/, '');\n \n // Build transformation string\n const transformStr = buildTransformString(transform || {}, defaults, enableDPR, connectionQuality);\n \n // Encode file path safely (encode each segment separately)\n const encodedPath = src\n .split('/')\n .filter(Boolean)\n .map(segment => encodeURIComponent(segment))\n .join('/');\n \n // Build URL: baseUrl/workspace/transformations/file_path\n if (transformStr) {\n return `${normalizedBase}/${workspace}/${transformStr}/${encodedPath}`;\n } else {\n return `${normalizedBase}/${workspace}/${encodedPath}`;\n }\n}\n\n","/**\n * Responsive image attributes generator\n * Implements three strategies based on input options\n */\n\nimport { buildImageUrl } from './url-builder';\nimport type { ResponsiveOptions, ResponsiveAttributes, TransformOptions } from './types';\nimport { getDPR } from './device';\n\nconst DEFAULT_DEVICE_BREAKPOINTS = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];\nconst DEFAULT_IMAGE_BREAKPOINTS = [16, 32, 48, 64, 96, 128, 256, 384];\n\n/**\n * Parse sizes attribute to extract minimum viewport width\n * Returns the smallest vw value found, or null if none found\n */\nfunction parseMinVWFromSizes(sizes: string): number | null {\n // Match patterns like \"33vw\", \"100vw\", \"(min-width: 800px) 33vw\"\n const vwMatches = sizes.match(/(\\d+(?:\\.\\d+)?)vw/g);\n if (!vwMatches || vwMatches.length === 0) return null;\n \n const vwValues = vwMatches.map(m => parseFloat(m));\n return Math.min(...vwValues);\n}\n\n/**\n * Find nearest breakpoint to a given width\n */\nfunction findNearestBreakpoint(width: number, breakpoints: number[]): number {\n return breakpoints.reduce((prev, curr) => {\n return Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev;\n });\n}\n\n/**\n * Generate responsive image attributes\n * \n * Rule 1: width only → DPR strategy (1x and 2x)\n * Rule 2: sizes provided → width-based strategy\n * Rule 3: neither → all device breakpoints\n */\nexport function generateResponsiveAttributes(\n baseUrl: string,\n workspace: string,\n options: ResponsiveOptions,\n defaults?: { f?: string; q?: string | number; [key: string]: any },\n deviceBreakpoints: number[] = DEFAULT_DEVICE_BREAKPOINTS,\n imageBreakpoints: number[] = DEFAULT_IMAGE_BREAKPOINTS,\n enableDPR: boolean = true,\n connectionQuality?: 'auto' | '2g' | '3g' | '4g' | 'wifi'\n): ResponsiveAttributes {\n const { src, width, sizes, transform, breakpoints } = options;\n \n // Use custom breakpoints if provided, otherwise use defaults\n const effectiveBreakpoints = breakpoints || deviceBreakpoints;\n \n // Rule 1: width only → DPR strategy\n if (width !== undefined && !sizes) {\n const dpr = enableDPR ? getDPR() : 1;\n const baseWidth = width;\n \n // Generate 1x and 2x URLs\n const srcSetParts: string[] = [];\n \n // 1x URL\n const transform1x: TransformOptions = {\n ...transform,\n w: baseWidth,\n dpr: 1\n };\n const url1x = buildImageUrl(baseUrl, workspace, src, transform1x, defaults, false, connectionQuality);\n srcSetParts.push(`${url1x} 1x`);\n \n // 2x URL (only if device DPR is actually >= 2)\n if (dpr >= 2) {\n const transform2x: TransformOptions = {\n ...transform,\n w: baseWidth,\n dpr: 2\n };\n const url2x = buildImageUrl(baseUrl, workspace, src, transform2x, defaults, false, connectionQuality);\n srcSetParts.push(`${url2x} 2x`);\n }\n \n // Base URL (1x)\n const baseTransform: TransformOptions = {\n ...transform,\n w: baseWidth\n };\n const baseSrc = buildImageUrl(baseUrl, workspace, src, baseTransform, defaults, enableDPR, connectionQuality);\n \n return {\n src: baseSrc,\n srcSet: srcSetParts.join(', '),\n width: baseWidth\n };\n }\n \n // Rule 2: sizes provided → width-based strategy\n if (sizes) {\n const minVW = parseMinVWFromSizes(sizes);\n \n // Filter breakpoints: only include those >= minimum required width\n // If we have a viewport width, calculate minimum pixel width needed\n // For simplicity, we'll use all breakpoints that make sense\n // In practice, you'd calculate based on viewport width\n const filteredBreakpoints = effectiveBreakpoints.filter(bp => {\n // Include all breakpoints for now\n // Could be optimized based on minVW calculation\n return true;\n });\n \n // Generate srcset with w descriptors\n const srcSetParts = filteredBreakpoints.map(bp => {\n const transformWithWidth: TransformOptions = {\n ...transform,\n w: bp\n };\n const url = buildImageUrl(baseUrl, workspace, src, transformWithWidth, defaults, enableDPR, connectionQuality);\n return `${url} ${bp}w`;\n });\n \n // Base URL (use smallest breakpoint or provided width)\n const baseWidth = width || filteredBreakpoints[0] || effectiveBreakpoints[0];\n const baseTransform: TransformOptions = {\n ...transform,\n w: baseWidth\n };\n const baseSrc = buildImageUrl(baseUrl, workspace, src, baseTransform, defaults, enableDPR, connectionQuality);\n \n return {\n src: baseSrc,\n srcSet: srcSetParts.join(', '),\n sizes: sizes,\n width: baseWidth\n };\n }\n \n // Rule 3: neither width nor sizes → all device breakpoints\n // Use all breakpoints with w descriptors\n const srcSetParts = effectiveBreakpoints.map(bp => {\n const transformWithWidth: TransformOptions = {\n ...transform,\n w: bp\n };\n const url = buildImageUrl(baseUrl, workspace, src, transformWithWidth, defaults, enableDPR, connectionQuality);\n return `${url} ${bp}w`;\n });\n \n // Base URL (use smallest breakpoint)\n const baseWidth = effectiveBreakpoints[0];\n const baseTransform: TransformOptions = {\n ...transform,\n w: baseWidth\n };\n const baseSrc = buildImageUrl(baseUrl, workspace, src, baseTransform, defaults, enableDPR, connectionQuality);\n \n return {\n src: baseSrc,\n srcSet: srcSetParts.join(', '),\n sizes: '100vw',\n width: baseWidth\n };\n}\n\n","/**\n * Main AutoRender client factory\n * Creates an AR instance with URL building and responsive image capabilities\n */\n\nimport { buildImageUrl } from './url-builder';\nimport { buildTransformString } from './transform';\nimport { generateResponsiveAttributes } from './responsive';\nimport { getDPR, getConnectionQuality } from './device';\nimport type {\n CreateARConfig,\n ARInstance,\n TransformOptions,\n ResponsiveOptions,\n ResponsiveAttributes\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://assets.autorender.io';\nconst DEFAULT_DEVICE_BREAKPOINTS = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];\nconst DEFAULT_IMAGE_BREAKPOINTS = [16, 32, 48, 64, 96, 128, 256, 384];\n\nexport function createAR(config: CreateARConfig): ARInstance {\n const {\n baseUrl = DEFAULT_BASE_URL,\n workspace,\n defaults = {},\n deviceBreakpoints = DEFAULT_DEVICE_BREAKPOINTS,\n imageBreakpoints = DEFAULT_IMAGE_BREAKPOINTS,\n enableDPR = true,\n connectionQuality: configConnectionQuality = 'auto'\n } = config;\n \n if (!workspace) {\n throw new Error('workspace is required');\n }\n \n // Normalize defaults - preserve 'auto' for q if not explicitly set\n const normalizedDefaults = {\n f: defaults.f || 'auto',\n q: defaults.q !== undefined ? defaults.q : 'auto',\n ...defaults\n };\n \n // Get connection quality for quality adjustment\n // If configConnectionQuality is 'auto', detect from browser\n // Otherwise, use the provided value directly\n const effectiveConnectionQuality: '2g' | '3g' | '4g' | 'wifi' = \n configConnectionQuality === 'auto' \n ? (() => {\n const detected = getConnectionQuality();\n console.log('detected', detected);\n return detected === 'unknown' ? 'wifi' : detected;\n })()\n : configConnectionQuality;\n \n const instance: ARInstance = {\n /**\n * Generate image URL with transformations\n */\n url(src: string, transform?: TransformOptions): string {\n return buildImageUrl(\n baseUrl,\n workspace,\n src,\n transform,\n normalizedDefaults,\n enableDPR,\n effectiveConnectionQuality\n );\n },\n \n /**\n * Generate transformation string only (without URL)\n */\n transformString(transform: TransformOptions): string {\n return buildTransformString(\n transform,\n normalizedDefaults,\n enableDPR,\n effectiveConnectionQuality\n );\n },\n \n /**\n * Generate responsive image attributes\n */\n responsiveImageAttributes(options: ResponsiveOptions): ResponsiveAttributes {\n // Allow per-call breakpoint override\n const effectiveDeviceBreakpoints = options.breakpoints || deviceBreakpoints;\n \n return generateResponsiveAttributes(\n baseUrl,\n workspace,\n options,\n normalizedDefaults,\n effectiveDeviceBreakpoints,\n imageBreakpoints,\n enableDPR,\n effectiveConnectionQuality\n );\n },\n \n /**\n * Get current device pixel ratio\n */\n getDPR(): number {\n return getDPR();\n },\n \n /**\n * Get current connection quality\n */\n getConnectionQuality(): '2g' | '3g' | '4g' | 'wifi' | 'unknown' {\n return getConnectionQuality();\n }\n };\n \n return instance;\n}\n\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACatC,IAAM,kBACJ,OAAO,eAAe,eAAe,OAAO,WAAW,gBAAgB,cAClE,MAAM,oBAAoB;AAAC,IAC5B,WAAW;AA4BV,IAAM,4BAAN,cAAwC,gBAAgB;AAAA,EAmE7D,cAAc;AACZ,UAAM;AAhER,SAAQ,aAAwC;AAEhD,SAAQ,SAA6B;AACrC,SAAQ,QAA2B;AACnC,SAAQ,aAAiC,CAAC;AAC1C,SAAQ,gBAAsC,CAAC;AAE/C,SAAQ,cAAmC;AAC3C,SAAQ,cAAc;AACtB,SAAQ,aAA8B;AACtC,SAAQ,mBAAmB;AAE3B,SAAQ,cAAkC;AAE1C,SAAQ,WAAkC;AAC1C,SAAQ,WAAoC;AAC5C,SAAQ,cAA6B,CAAC;AACtC,SAAQ,YAAgC;AACxC,SAAQ,eAAmC;AAC3C,SAAQ,eAAyC;AACjD,SAAQ,gBAA0C;AAClD,SAAQ,eAAmC;AAC3C,SAAQ,mBAA6C;AACrD,SAAQ,kBAA4C;AACpD,SAAQ,mBAA6C;AACrD,SAAQ,oBAA8C;AACtD,SAAQ,oBAA8C;AACtD,SAAQ,qBAA+C;AACvD,SAAQ,qBAAyC;AACjD,SAAQ,uBAA2C;AACnD,SAAQ,yBAA6C;AACrD,SAAQ,oBAAwC;AAChD,SAAQ,qBAAyC;AACjD,SAAQ,sBAA0C;AAClD,SAAQ,uBAA2C;AACnD,SAAQ,mBAAkC,CAAC;AAC3C,SAAQ,qBAAyC;AACjD,SAAQ,qBAAoC;AAC5C,SAAQ,kBAAsC;AAC9C,SAAQ,YAAgC;AACxC,SAAQ,oBAA6B;AAerC,SAAQ,sBAAsB,oBAAI,IAAoC;AACtE,SAAQ,gBAAgB,CAAC,UAAyB;AAChD,UAAI,MAAM,QAAQ,YAAY,KAAK,aAAa;AAC9C,aAAK,cAAc;AACnB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAIE,SAAK,SAAS,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAAA,EAClD;AAAA,EAxBQ,aAAa,OAAyB;AAC5C,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,iBAAiB,gBAAgB,MAAM,SAAS,aAAc,QAAO;AACzE,QAAI,iBAAiB,SAAS,MAAM,SAAS,aAAc,QAAO;AAClE,UAAM,UACJ,iBAAiB,QACb,MAAM,UACN,OAAO,UAAU,WACjB,QACA;AACN,WAAO,OAAO,YAAY,YAAY,QAAQ,YAAY,EAAE,SAAS,OAAO;AAAA,EAC9E;AAAA,EAeA,oBAAoB;AAClB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,uBAAuB;AACrB,SAAK,iBAAiB;AACtB,WAAO,oBAAoB,WAAW,KAAK,aAAa;AACxD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEQ,cAAc;AACpB,QAAI,CAAC,KAAK,QAAQ,WAAW;AAC3B,WAAK,oBAAoB;AACzB;AAAA,IACF;AAEA,UAAM,YAAY,OAAO,KAAK,QAAQ,cAAc,WAChD,SAAS,cAA2B,KAAK,QAAQ,SAAS,IAC1D,KAAK,QAAQ;AAEjB,QAAI,CAAC,WAAW;AACd,cAAQ,KAAK,cAAc,KAAK,QAAQ,SAAS,aAAa;AAC9D,WAAK,oBAAoB;AACzB;AAAA,IACF;AAIA,QAAI,gBAA6B,KAAK;AACtC,WAAO,iBAAiB,kBAAkB,SAAS,MAAM;AACvD,UAAI,kBAAkB,WAAW;AAG/B,cAAMC,kBAAiB,OAAO,iBAAiB,SAAS;AACxD,YAAIA,gBAAe,aAAa,UAAU;AACxC,oBAAU,MAAM,WAAW;AAAA,QAC7B;AACA,aAAK,kBAAkB;AACvB,aAAK,YAAY;AACjB,aAAK,oBAAoB;AACzB;AAAA,MACF;AACA,sBAAgB,cAAc;AAAA,IAChC;AAIA,UAAM,iBAAiB,OAAO,iBAAiB,SAAS;AACxD,QAAI,eAAe,aAAa,UAAU;AACxC,gBAAU,MAAM,WAAW;AAAA,IAC7B;AAEA,SAAK,kBAAkB;AACvB,SAAK,oBAAoB;AAGzB,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,YAAY,SAAS,cAAc,KAAK;AAC7C,WAAK,UAAU,YAAY;AAC3B,WAAK,UAAU,MAAM,WAAW;AAChC,WAAK,UAAU,MAAM,QAAQ;AAC7B,WAAK,UAAU,MAAM,SAAS;AAC9B,gBAAU,YAAY,KAAK,SAAS;AAAA,IACtC;AAAA,EACF;AAAA,EAEQ,gBAAgB;AACtB,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,OAAO;AACtB,WAAK,YAAY;AAAA,IACnB;AACA,SAAK,kBAAkB;AACvB,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,cAAc,YAAgC,SAA4B;AACxE,SAAK,iBAAiB;AACtB,SAAK,aAAa;AAClB,SAAK,qBAAqB;AAC1B,SAAK,aAAa,OAAO;AACzB,SAAK,iBAAiB;AACtB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,cAAc,SAAqC;AACjD,QAAI,CAAC,KAAK,WAAY;AACtB,SAAK,aAAa,EAAE,GAAG,KAAK,SAAS,GAAG,QAAQ,CAAC;AACjD,SAAK,WAAW,WAAW,KAAK,OAAO;AACvC,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,iBAAiB;AACf,QAAI,KAAK,gBAAgB,YAAY,CAAC,KAAK,aAAa;AACtD,WAAK,cAAc;AACnB,WAAK,OAAO;AACZ,4BAAsB,MAAM,KAAK,WAAW,MAAM,CAAC;AACnD;AAAA,IACF;AACA,SAAK,WAAW,MAAM;AAAA,EACxB;AAAA,EAEQ,aAAa,SAA4B;AAC/C,UAAM,kBAAkB,KAAK,WAAY,CAAC;AAC1C,UAAM,aAAc,QAAQ,SAAS,gBAAgB,SAAS;AAC9D,UAAM,gBAAgB;AAAA,MACpB,YAAY,WAAW,cAAc,cAAc;AAAA,MACnD,cAAc,WAAW,gBAAgB,cAAc;AAAA,MACvD,oBAAoB,WAAW,sBAAsB,cAAc;AAAA,MACnE,gBAAgB,WAAW,kBAAkB,cAAc;AAAA,MAC3D,YAAY,WAAW,cAAc,gBAAgB,OAAO;AAAA,IAC9D;AAGA,UAAM,kBAAkB,QAAQ,WAAW,gBAAgB,WAAW,CAAC;AACvE,UAAM,oBAAoB,KAAK,eAAe,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK;AAGjF,UAAM,mBAAmB,gBAAgB,cAAc,QAAQ;AAC/D,QAAI,oBAAoB,KAAK,aAAa,KAAK,iBAAiB;AAE9D,WAAK,UAAU,OAAO;AACtB,WAAK,YAAY;AACjB,WAAK,kBAAkB;AAAA,IACzB;AAEA,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAGA,QAAI,KAAK,QAAQ,WAAW;AAC1B,WAAK,YAAY;AAAA,IACnB,OAAO;AACL,WAAK,cAAc;AAAA,IACrB;AAEA,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,GAAI,KAAK,QAAQ,UAAU,CAAC;AAAA,IAC9B;AAEA,SAAK,QAAQ;AAEb,UAAM,mBAAmB,gBAAgB,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG;AACvE,UAAM,iBAAiB,sBAAsB;AAE7C,SAAK,gBAAgB;AACrB,SAAK,QAAQ,iBAAiB,QAAQ,kBAAkB,gBAAgB;AAExE,UAAM,gBAAgB,KAAK,QAAQ,QAAQ;AAC3C,SAAK,cAAc,kBAAkB,WAAW,WAAW;AAC3D,SAAK,aAAa,KAAK,QAAQ,cAAc;AAC7C,SAAK,mBAAmB,KAAK,QAAQ,oBAAoB;AACzD,SAAK,aAAa,KAAK,QAAQ,cAAc,CAAC;AAE9C,QAAI,KAAK,QAAQ,eAAe,UAAa,KAAK,gBAAgB,UAAU;AAC1E,WAAK,QAAQ,aAAa;AAAA,IAC5B;AAGA,QAAI,KAAK,eAAe,gBAAgB;AACtC,YAAM,YAAY,KAAK,YAAY,SAAS,EAAE,MAAM,UAAU,KAAK;AACnE,WAAK,oBAAoB,QAAQ;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,mBAAmB;AACzB,QAAI,CAAC,KAAK,WAAY;AAEtB,UAAM,gBAAgB,MAAM,KAAK,YAAY;AAC7C,UAAM,mBAAmB,MAAM,KAAK,YAAY;AAChD,UAAM,qBAAqB,CAAC,UAAiB;AAC3C,YAAM,SAAU,MAAwC;AACxD,UAAI,KAAK,QAAQ,cAAc,QAAQ,OAAO,QAAQ;AACpD,aAAK,KAAK,YAAY,UAAU;AAAA,MAClC;AAAA,IACF;AACA,UAAM,mBAAmB,MAAM;AAC7B,WAAK,iBAAiB;AACtB,WAAK,OAAO;AAAA,IACd;AACA,UAAM,gBAAgB,CAAC,UAAiB;AACtC,YAAM,SAAU,MAAsB;AACtC,WAAK,sBAAsB,MAAM;AAAA,IACnC;AAEA,SAAK,WAAW,iBAAiB,eAAe,aAAa;AAC7D,SAAK,WAAW,iBAAiB,YAAY,gBAAgB;AAC7D,SAAK,WAAW,iBAAiB,gBAAgB,gBAAgB;AACjE,SAAK,WAAW,iBAAiB,cAAc,kBAAkB;AACjE,SAAK,WAAW,iBAAiB,YAAY,gBAAgB;AAC7D,SAAK,WAAW,iBAAiB,SAAS,aAAa;AAEvD,SAAK,oBAAoB,IAAI,eAAe,aAAa;AACzD,SAAK,oBAAoB,IAAI,YAAY,gBAAgB;AACzD,SAAK,oBAAoB,IAAI,gBAAgB,gBAAgB;AAC7D,SAAK,oBAAoB,IAAI,cAAc,kBAAkB;AAC7D,SAAK,oBAAoB,IAAI,YAAY,gBAAgB;AACzD,SAAK,oBAAoB,IAAI,SAAS,aAAa;AAAA,EACrD;AAAA,EAEQ,mBAAmB;AACzB,QAAI,CAAC,KAAK,WAAY;AACtB,eAAW,CAAC,OAAO,OAAO,KAAK,KAAK,oBAAoB,QAAQ,GAAG;AACjE,WAAK,WAAW,oBAAoB,OAAO,OAAO;AAAA,IACpD;AACA,SAAK,oBAAoB,MAAM;AAC/B,SAAK,aAAa;AAAA,EACpB;AAAA,EAEQ,iBAAiB,KAA+B,UAAkB;AACxE,UAAM,QAAQ,KAAK,WAAW,GAAG;AACjC,WAAO,QAAQ,GAAG,QAAQ,IAAI,KAAK,KAAK;AAAA,EAC1C;AAAA,EAEQ,SAAS;AACf,QAAI,CAAC,KAAK,WAAY;AAEtB,SAAK,aAAa,gBAAgB,KAAK,WAAW;AAElD,UAAM,wBAAwB;AAC9B,UAAM,oBAAoB;AAE1B,UAAM,iBAAiB;AAAA,oBACP,KAAK,iBAAiB,YAAY,aAAa,CAAC;AAAA;AAAA,oCAEhC,KAAK,OAAO,aAAa;AAAA;AAAA;AAIzD,UAAM,iBAAiB,cAAc,KAAK,iBAAiB,YAAY,cAAc,CAAC;AACtF,UAAM,mBAAmB;AAEzB,UAAM,oBAAoB;AAAA;AAAA,qCAEO,KAAK,OAAO,KAAK;AAAA;AAAA;AAAA;AAKlD,UAAM,qBAAqB;AAAA;AAAA,qCAEM,KAAK,OAAO,KAAK;AAAA;AAAA;AAIlD,UAAM,oBAAoB;AAAA;AAAA,qCAEO,KAAK,gBAAgB,WAAW,eAAe,EAAE;AAAA,YAC1E,cAAc;AAAA,YACd,iBAAiB;AAAA,YACjB,qBAAqB;AAAA,YACrB,gBAAgB;AAAA,YAChB,cAAc;AAAA;AAAA;AAAA;AAKtB,UAAM,eAAe;AAAA,mCACU,KAAK,gBAAgB,WAAW,eAAe,EAAE;AAAA,uDAC7B,KAAK,OAAO,KAAK;AAAA,wDAChB,KAAK,OAAO,MAAM;AAAA;AAAA;AAAA,4DAGd,KAAK,OAAO,OAAO;AAAA,iEACd,KAAK,OAAO,YAAY;AAAA,wDACjC,KAAK,OAAO,IAAI;AAAA;AAAA;AAAA;AAMpE,UAAM,6BAA6B,KAAK,aAAa,KAAK;AAC1D,UAAM,cAAc,KAAK,gBAAgB,WACrC;AAAA,oBACY,KAAK,iBAAiB,SAAS,UAAU,CAAC,IAAI,KAAK,cAAc,YAAY,EAAE,IAAI,6BAA6B,cAAc,EAAE;AAAA;AAAA;AAAA,YAGxI,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,YAAY;AAAA;AAAA;AAAA;AAAA,QAKhB;AAEJ,UAAM,eAAe,KAAK,gBAAgB,WACtC;AAAA;AAAA;AAAA,cAGM,kBAAkB;AAAA,cAClB,iBAAiB;AAAA,cACjB,YAAY;AAAA;AAAA;AAAA;AAAA,UAKlB;AAEJ,UAAM,WAAW,SAAS,cAAc,UAAU;AAClD,aAAS,YAAY;AAAA,eACV,YAAY;AAAA,oBACP,KAAK,iBAAiB,QAAQ,kBAAkB,CAAC,mBAAmB,KAAK,WAAW;AAAA;AAAA,UAG9F,KAAK,gBAAgB,WACjB,gCAAgC,KAAK,iBAAiB,iBAAiB,mBAAmB,CAAC,+CAA+C,KAAK,OAAO,YAAY,qBAClK,YACN;AAAA,UACE,KAAK,YAAY,KAAK,WAAW;AAAA;AAAA;AAIvC,SAAK,OAAO,YAAY;AACxB,SAAK,OAAO,YAAY,SAAS,QAAQ,UAAU,IAAI,CAAC;AAGxD,QAAI,KAAK,aAAa,KAAK,gBAAgB,UAAU;AACnD,YAAM,iBAAiB,SAAS,cAAc,UAAU;AACxD,qBAAe,YAAY,UAAU,YAAY,WAAW,WAAW;AACvE,WAAK,UAAU,YAAY;AAC3B,WAAK,UAAU,YAAY,eAAe,QAAQ,UAAU,IAAI,CAAC;AAAA,IACnE,WAAW,KAAK,aAAa,CAAC,KAAK,aAAa;AAE9C,WAAK,UAAU,YAAY;AAAA,IAC7B;AAEA,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,oBAAoB;AACzB,SAAK,YAAY;AAEjB,QAAI,KAAK,gBAAgB,UAAU;AACjC,UAAI,KAAK,aAAa;AACpB,eAAO,iBAAiB,WAAW,KAAK,aAAa;AAAA,MACvD,OAAO;AACL,eAAO,oBAAoB,WAAW,KAAK,aAAa;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,UAAkC;AAE1D,QAAI,KAAK,WAAW;AAClB,aAAO,KAAK,UAAU,cAAc,QAAQ,KAAK,KAAK,OAAO,cAAc,QAAQ;AAAA,IACrF;AACA,WAAO,KAAK,OAAO,cAAc,QAAQ;AAAA,EAC3C;AAAA,EAEQ,mBAAmB,UAA6B;AAEtD,QAAI,KAAK,WAAW;AAClB,YAAM,gBAAgB,MAAM,KAAK,KAAK,UAAU,iBAAiB,QAAQ,CAAC;AAC1E,YAAM,gBAAgB,MAAM,KAAK,KAAK,OAAO,iBAAiB,QAAQ,CAAC;AAEvE,YAAM,WAAsB,CAAC;AAC7B,oBAAc,QAAQ,QAAM,SAAS,KAAK,EAAE,CAAC;AAC7C,oBAAc,QAAQ,QAAM;AAC1B,YAAI,CAAC,SAAS,SAAS,EAAE,EAAG,UAAS,KAAK,EAAE;AAAA,MAC9C,CAAC;AACD,aAAO;AAAA,IACT;AACA,WAAO,MAAM,KAAK,KAAK,OAAO,iBAAiB,QAAQ,CAAC;AAAA,EAC1D;AAAA,EAEQ,kBAAkB;AACxB,SAAK,cAAc,KAAK,OAAO,cAAc,mBAAmB;AAChE,SAAK,YAAY,KAAK,OAAO,cAAc,gBAAgB;AAC3D,SAAK,WAAW,KAAK,OAAO,cAAc,cAAc;AACxD,SAAK,WAAW,KAAK,OAAO,cAAc,eAAe;AACzD,SAAK,cAAc,MAAM,KAAK,KAAK,OAAO,iBAAiB,iBAAiB,CAAC;AAC7E,SAAK,YAAY,KAAK,kBAAkB,gBAAgB;AACxD,SAAK,eAAe,KAAK,OAAO,cAAc,mBAAmB;AACjE,SAAK,eAAe,KAAK,OAAO,cAAc,mBAAmB;AACjE,SAAK,gBAAgB,KAAK,OAAO,cAAc,oBAAoB;AACnE,SAAK,eAAe,KAAK,kBAAkB,WAAW;AACtD,SAAK,mBAAmB,KAAK,kBAAkB,iBAAiB;AAChE,SAAK,kBAAkB,KAAK,kBAAkB,gBAAgB;AAC9D,SAAK,mBAAmB,KAAK,kBAAkB,iBAAiB;AAChE,SAAK,oBAAoB,KAAK,kBAAkB,yBAAyB;AACzE,SAAK,oBAAoB,KAAK,kBAAkB,kBAAkB;AAClE,SAAK,qBAAqB,KAAK,kBAAkB,oBAAoB;AACrE,SAAK,qBAAqB,KAAK,kBAAkB,0BAA0B;AAC3E,SAAK,uBAAuB,KAAK,kBAAkB,mBAAmB;AACtE,SAAK,yBAAyB,KAAK,OAAO,cAAc,qBAAqB;AAC7E,SAAK,oBAAoB,KAAK,kBAAkB,iBAAiB;AACjE,SAAK,qBAAqB,KAAK,kBAAkB,kBAAkB;AACnE,SAAK,sBAAsB,KAAK,kBAAkB,mBAAmB;AACrE,SAAK,uBAAuB,KAAK,OAAO,cAAc,oBAAoB;AAC1E,SAAK,mBAAmB,KAAK,mBAAmB,sBAAsB;AACtE,SAAK,qBAAqB,KAAK,kBAAkB,kBAAkB;AACnE,SAAK,kBAAkB;AAEvB,UAAM,OAAO,YAAY,KAAK,MAAM,MAAM;AAC1C,UAAM,gBAAgB,KAAK,OAAO,cAAc,mBAAmB;AACnE,QAAI,QAAQ,eAAe;AACzB,oBAAc,YAAY;AAC1B,oBAAc,YAAY,IAAI;AAAA,IAChC;AACA,UAAM,aAAa,YAAY,KAAK,MAAM,MAAM;AAChD,UAAM,uBAAuB,KAAK,OAAO,cAAc,iBAAiB;AACxE,QAAI,cAAc,sBAAsB;AACtC,2BAAqB,YAAY;AACjC,2BAAqB,YAAY,UAAU;AAAA,IAC7C;AACA,UAAM,YAAY,YAAY,KAAK,MAAM,KAAK;AAC9C,UAAM,qBAAqB,KAAK,kBAAkB,sBAAsB;AACxE,QAAI,aAAa,oBAAoB;AACnC,yBAAmB,YAAY;AAC/B,yBAAmB,YAAY,SAAS;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,kBAAkB;AACxB,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM,iBAAiB,KAAK,QAAQ;AAEpC,QAAI,mBAAmB,UAAa,mBAAmB,QAAQ,mBAAmB,IAAI;AACpF,UAAI,KAAK,gBAAgB,UAAU;AACjC,aAAK,YAAY,MAAM,QAAQ;AAAA,MACjC,OAAO;AACL,aAAK,YAAY,MAAM,eAAe,OAAO;AAAA,MAC/C;AACA;AAAA,IACF;AAEA,UAAM,kBACJ,OAAO,mBAAmB,WAAW,GAAG,cAAc,OAAO;AAC/D,SAAK,YAAY,MAAM,QAAQ;AAAA,EACjC;AAAA,EAEQ,kBAAkB;AACxB,SAAK,WAAW,gBAAgB,iBAAiB;AACjD,SAAK,WAAW,gBAAgB,cAAc;AAC9C,SAAK,WAAW,gBAAgB,WAAW;AAE3C,QAAI,KAAK,QAAQ,kBAAkB,OAAO;AACxC,WAAK,WAAW,gBAAgB,UAAU;AAAA,IAC5C,OAAO;AACL,WAAK,WAAW,aAAa,YAAY,EAAE;AAAA,IAC7C;AAEA,QAAI,KAAK,QAAQ,QAAQ,QAAQ;AAC/B,WAAK,UAAU,SAAS,KAAK,QAAQ,OAAO,KAAK,GAAG;AAAA,IACtD;AAAA,EACF;AAAA,EAEQ,aAAa;AACnB,SAAK,eAAe,iBAAiB,SAAS,MAAM;AAClD,WAAK,cAAc;AACnB,WAAK,OAAO;AAAA,IACd,CAAC;AAED,SAAK,kBAAkB,iBAAiB,SAAS,MAAM;AACrD,WAAK,cAAc;AACnB,WAAK,OAAO;AAAA,IACd,CAAC;AAED,SAAK,cAAc,iBAAiB,SAAS,WAAS;AACpD,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AACb,UAAI,WAAW,KAAK,gBAAgB,OAAO,UAAU,SAAS,mBAAmB,GAAG;AAClF,aAAK,cAAc;AACnB,aAAK,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AAED,SAAK,mBAAmB,iBAAiB,SAAS,MAAM;AACtD,UAAI,CAAC,KAAK,WAAY;AACtB,UAAI,KAAK,WAAW,SAAS,EAAE,YAAa;AAC5C,WAAK,KAAK,WAAW,UAAU;AAAA,IACjC,CAAC;AAED,SAAK,iBAAiB,iBAAiB,SAAS,MAAM;AACpD,UAAI,CAAC,KAAK,WAAY;AACtB,YAAM,QAAQ,KAAK,WAAW,SAAS;AACvC,YAAM,eAAe,MAAM,MAAM,SAAS,KAAK,MAAM,MAAM,MAAM,UAAQ,KAAK,WAAW,WAAW;AACpG,UAAI,KAAK,gBAAgB,UAAU;AACjC,YAAI,MAAM,aAAa;AACrB;AAAA,QACF;AACA,YAAI,gBAAgB,MAAM,MAAM,WAAW,GAAG;AAC5C,eAAK,WAAW,MAAM;AACtB,eAAK,YAAY;AAAA,QACnB;AACA;AAAA,MACF;AACA,UAAI,MAAM,aAAa;AACrB,aAAK,WAAW;AAChB;AAAA,MACF;AACA,UAAI,cAAc;AAChB,aAAK,WAAW;AAChB;AAAA,MACF;AACA,WAAK,WAAW;AAAA,IAClB,CAAC;AAED,SAAK,kBAAkB,iBAAiB,SAAS,MAAM;AACrD,UAAI,CAAC,KAAK,WAAY;AACtB,YAAM,EAAE,YAAY,IAAI,KAAK,WAAW,SAAS;AACjD,UAAI,aAAa;AACf;AAAA,MACF;AACA,WAAK,WAAW,MAAM;AACtB,WAAK,YAAY;AAAA,IACnB,CAAC;AAED,SAAK,mBAAmB,iBAAiB,SAAS,MAAM;AACtD,UAAI,CAAC,KAAK,WAAY;AACtB,YAAM,eAAe,KAAK,WAAW,SAAS;AAC9C,UAAI,aAAa,YAAa;AAC9B,WAAK,WAAW,MAAM;AACtB,UAAI,KAAK,gBAAgB,UAAU;AACjC,aAAK,YAAY;AACjB;AAAA,MACF;AACA,WAAK,cAAc;AACnB,WAAK,OAAO;AAAA,IACd,CAAC;AAED,SAAK,oBAAoB,iBAAiB,SAAS,MAAM;AACvD,WAAK,eAAe;AAAA,IACtB,CAAC;AAED,SAAK,UAAU,iBAAiB,SAAS,MAAM,KAAK,eAAe,CAAC;AACpE,SAAK,UAAU,iBAAiB,aAAa,WAAS;AACpD,YAAM,eAAe;AACrB,WAAK,UAAU,UAAU,IAAI,aAAa;AAAA,IAC5C,CAAC;AACD,SAAK,UAAU,iBAAiB,YAAY,WAAS;AACnD,YAAM,eAAe;AACrB,WAAK,UAAU,UAAU,IAAI,aAAa;AAC1C,UAAI,MAAM,cAAc;AACtB,cAAM,aAAa,aAAa;AAAA,MAClC;AAAA,IACF,CAAC;AACD,SAAK,UAAU,iBAAiB,aAAa,WAAS;AACpD,UAAI,MAAM,WAAW,KAAK,UAAU;AAClC,aAAK,UAAU,UAAU,OAAO,aAAa;AAAA,MAC/C;AAAA,IACF,CAAC;AACD,SAAK,UAAU,iBAAiB,QAAQ,OAAM,UAAS;AACrD,YAAM,eAAe;AACrB,WAAK,UAAU,UAAU,OAAO,aAAa;AAC7C,YAAM,QAAQ,MAAM,KAAK,sBAAsB,KAAK;AACpD,UAAI,MAAM,QAAQ;AAChB,cAAM,KAAK,YAAY,SAAS,KAAK;AAAA,MACvC;AACA,UAAI,KAAK,WAAW;AAClB,aAAK,UAAU,QAAQ;AAAA,MACzB;AAAA,IACF,CAAC;AAED,SAAK,WAAW,iBAAiB,UAAU,YAAY;AACrD,YAAM,QAAQ,KAAK,WAAW,QAAQ,MAAM,KAAK,KAAK,UAAU,KAAK,IAAI,CAAC;AAC1E,YAAM,SAAS,MAAM,IAAI,WAAS;AAAA,QAChC;AAAA,QACA,cAAe,KAAgD;AAAA,MACjE,EAAE;AACF,YAAM,KAAK,YAAY,SAAS,MAAM;AACtC,UAAI,KAAK,UAAW,MAAK,UAAU,QAAQ;AAAA,IAC7C,CAAC;AAED,SAAK,cAAc,iBAAiB,SAAS,MAAM;AACjD,UAAI,KAAK,YAAY,SAAS,EAAE,YAAa;AAC7C,WAAK,KAAK,YAAY,UAAU;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,sBACZ,OACuD;AACvD,UAAM,QAAQ,MAAM,cAAc;AAElC,QAAI,CAAC,OAAO;AACV,YAAM,QAAQ,MAAM,cAAc,QAAQ,MAAM,KAAK,MAAM,aAAa,KAAK,IAAI,CAAC;AAClF,aAAO,MAAM,IAAI,WAAS;AAAA,QACxB;AAAA,QACA,cAAe,KAAgD;AAAA,MACjE,EAAE;AAAA,IACJ;AAEA,UAAM,UAAU,MAAM,KAAK,KAAK,EAC7B,IAAI,UAAS,KAAK,mBAAmB,KAAK,iBAAiB,IAAI,IAAK,EACpE,OAAO,OAAO;AAEjB,UAAM,YAA0D,CAAC;AAEjE,eAAW,SAAS,SAAS;AAC3B,YAAM,QAAQ,MAAM,KAAK,UAAU,OAAO,EAAE;AAC5C,gBAAU,KAAK,GAAG,KAAK;AAAA,IACzB;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,UAAU,OAAwB,OAAO,IAA2D;AAC1G,WAAO,IAAI,QAAQ,aAAW;AAC5B,UAAI,MAAM,QAAQ;AAChB,QAAC,MAA8B,KAAK,UAAQ;AAC1C,kBAAQ,CAAC,EAAE,MAAM,cAAc,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC;AAAA,QAC7E,CAAC;AAAA,MACH,WAAW,MAAM,aAAa;AAC5B,cAAM,SAAU,MAAmC,aAAa;AAChE,eAAO,YAAY,OAAM,YAAW;AAClC,gBAAM,UAAU,MAAM,QAAQ;AAAA,YAC5B,QAAQ,IAAI,WAAS,KAAK,UAAU,OAAO,OAAO,GAAG,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;AAAA,UACzF;AACA,kBAAQ,QAAQ,KAAK,CAAC;AAAA,QACxB,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ,CAAC,CAAC;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,aAAa;AACnB,SAAK,cAAc;AACnB,SAAK,OAAO;AAAA,EACd;AAAA,EAEQ,eAAe,SAAwB;AAC7C,SAAK,qBAAqB;AAC1B,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,mBAAmB;AACzB,SAAK,eAAe,IAAI;AAAA,EAC1B;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,CAAC,KAAK,mBAAoB;AAC9B,QAAI,KAAK,oBAAoB;AAC3B,WAAK,mBAAmB,SAAS;AACjC,WAAK,mBAAmB,cAAc,KAAK;AAAA,IAC7C,OAAO;AACL,WAAK,mBAAmB,SAAS;AACjC,WAAK,mBAAmB,cAAc;AAAA,IACxC;AAAA,EACF;AAAA,EAEQ,sBAAsB,OAAgB;AAC5C,QAAI,KAAK,aAAa,KAAK,GAAG;AAC5B,WAAK,iBAAiB;AACtB;AAAA,IACF;AAEA,UAAM,SACJ,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,QACtD,MAAc,SACf;AACN,UAAM,mBACJ,iBAAiB,QACb,MAAM,UACN,OAAQ,OAAe,YAAY,WAClC,MAAc,UACf,OAAO,UAAU,WACjB,QACA;AAEN,UAAM,aAAa,OAAO,oBAAoB,EAAE,EAAE,YAAY;AAC9D,UAAM,cACH,OAAO,WAAW,aAAa,WAAW,OAAO,WAAW,QAC7D,WAAW,SAAS,cAAc,KAClC,WAAW,SAAS,WAAW,KAC/B,WAAW,SAAS,iBAAiB;AAEvC,QAAI,aAAa;AACf,WAAK,eAAe,KAAK,OAAO,aAAa;AAAA,IAC/C,WAAW,kBAAkB;AAC3B,WAAK,eAAe,OAAO,gBAAgB,CAAC;AAAA,IAC9C,OAAO;AACL,WAAK,eAAe,KAAK,OAAO,YAAY;AAAA,IAC9C;AAAA,EACF;AAAA,EAEQ,cAAc;AACpB,QAAI,CAAC,KAAK,WAAY;AACtB,QAAI,CAAC,KAAK,SAAU;AAEpB,UAAM,QAAQ,KAAK,WAAW,SAAS;AACvC,UAAM,EAAE,OAAO,aAAa,WAAW,IAAI;AAC3C,UAAM,WAAW,MAAM,SAAS;AAChC,UAAM,eAAe,MAAM,KAAK,UAAQ,KAAK,UAAU,iBAAiB;AAExE,QAAI,cAAc;AAChB,WAAK,eAAe,KAAK,OAAO,aAAa;AAAA,IAC/C;AAEA,QAAI,KAAK,aAAa;AACpB,WAAK,YAAY,UAAU,OAAO,gBAAgB,WAAW;AAC7D,WAAK,YAAY,UAAU,OAAO,aAAa,QAAQ;AAAA,IACzD;AAEA,QAAI,KAAK,UAAU;AACjB,UAAI,UAAU;AACZ,aAAK,SAAS,MAAM,UAAU;AAAA,MAChC,OAAO;AACL,aAAK,SAAS,MAAM,UAAU;AAAA,MAChC;AAAA,IACF;AAEA,SAAK,eAAe,KAAK;AACzB,SAAK,kBAAkB;AACvB,SAAK,oBAAoB,QAAQ;AACjC,SAAK,iBAAiB,OAAO,WAAW;AACxC,SAAK,uBAAuB,UAAU;AAEtC,QAAI,KAAK,oBAAoB;AAC3B,WAAK,mBAAmB,MAAM,UAAU,WAAW,KAAK;AAAA,IAC1D;AACA,QAAI,KAAK,qBAAqB;AAC5B,WAAK,oBAAoB,MAAM,UAAU,WAAW,SAAS;AAAA,IAC/D;AACA,QAAI,KAAK,sBAAsB;AAC7B,WAAK,qBAAqB,MAAM,UAAU,WAAW,SAAS;AAAA,IAChE;AAEA,QAAI,KAAK,gBAAgB,YAAY,KAAK,gBAAgB,UAAU;AAClE,YAAM,iBAAiB,MAAM,OAAO,UAAQ,KAAK,WAAW,WAAW,EAAE;AACzE,YAAM,eAAe,YAAY,mBAAmB,MAAM,UAAU,iBAAiB;AAErF,UAAI,KAAK,oBAAoB;AAC3B,aAAK,mBAAmB,MAAM,UAAU,WAAW,KAAK;AAAA,MAC1D;AAEA,YAAM,eAAe,KAAK;AAC1B,YAAM,aAAa,KAAK;AACxB,YAAM,eAAe,KAAK;AAC1B,YAAM,cAAc,KAAK;AACzB,YAAM,gBAAgB,KAAK;AAE3B,YAAM,aAAa,YAAY,CAAC,eAAe,CAAC;AAChD,YAAM,cAAc,YAAY,CAAC,eAAe,CAAC;AACjD,YAAM,WAAW,aAAa,eAAe;AAC7C,YAAM,YAAY,aAAa,eAAe;AAC9C,YAAM,mBACJ,KAAK,gBAAgB,YAAY,YAAY,CAAC,eAAe,CAAC;AAChE,YAAM,mBACJ,KAAK,gBAAgB,YAAY,CAAC,gBAAgB,CAAC,gBAAgB,CAAC;AACtE,YAAM,aAAa,oBAAoB;AAEvC,UAAI,cAAc;AAChB,qBAAa,MAAM,UAAU,aAAa,KAAK;AAC/C,qBAAa,gBAAgB,YAAY,CAAC,UAAU;AAAA,MACtD;AAEA,UAAI,YAAY;AACd,mBAAW,MAAM,UAAU,WAAW,KAAK;AAC3C,mBAAW,cAAc,KAAK,OAAO;AACrC,mBAAW,gBAAgB,YAAY,CAAC,QAAQ;AAAA,MAClD;AAEA,UAAI,aAAa;AACf,oBAAY,MAAM,UAAU,YAAY,KAAK;AAC7C,oBAAY,gBAAgB,YAAY,WAAW;AAAA,MACrD;AAEA,UAAI,cAAc;AAChB,qBAAa,MAAM,UAAU,aAAa,KAAK;AAC/C,qBAAa,UAAU;AAAA,UACrB;AAAA,UACA,KAAK,gBAAgB,YAAY,CAAC;AAAA,QACpC;AAAA,MACF;AAEA,UAAI,eAAe;AACjB,sBAAc,MAAM,UAAU,cAAc,KAAK;AACjD,sBAAc,gBAAgB,YAAY,CAAC,WAAW;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAe,OAAqB;AAC1C,QAAI,CAAC,KAAK,SAAU;AACpB,SAAK,SAAS,YAAY;AAC1B,QAAI,MAAM,WAAW,GAAG;AACtB,WAAK,SAAS,MAAM,UAAU;AAC9B,WAAK,SAAS,UAAU,OAAO,SAAS;AACxC;AAAA,IACF;AAEA,UAAM,eAAe,KAAK,eAAe;AACzC,SAAK,SAAS,MAAM,UAAU,eAAe,SAAS;AACtD,SAAK,SAAS,UAAU,OAAO,WAAW,YAAY;AACtD,QAAI,cAAc;AAChB,WAAK,SAAS,MAAM,sBAAsB;AAC1C,WAAK,SAAS,MAAM,MAAM;AAAA,IAC5B,OAAO;AACL,WAAK,SAAS,MAAM,eAAe,uBAAuB;AAC1D,WAAK,SAAS,MAAM,eAAe,KAAK;AAAA,IAC1C;AAEA,UAAM,cAAc,KAAK,YAAY,SAAS,EAAE,eAAe;AAE/D,UAAM,QAAQ,UAAQ;AACpB,YAAM,KAAK,SAAS,cAAc,IAAI;AACtC,SAAG,YAAY;AACf,SAAG,UAAU,OAAO,WAAW,YAAY;AAE3C,YAAM,uBAAuB,KAAK,UAAU;AAE5C,UAAI,KAAK,WAAW,eAAe,KAAK,WAAW,UAAW,IAAG,UAAU,IAAI,cAAc;AAC7F,UAAI,KAAK,WAAW,YAAa,IAAG,UAAU,IAAI,cAAc;AAChE,UAAI,KAAK,WAAW,WAAW,CAAC,qBAAsB,IAAG,UAAU,IAAI,UAAU;AAEjF,YAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,aAAO,YAAY;AACnB,aAAO,UAAU,OAAO,WAAW,YAAY;AAE/C,YAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,YAAM,YAAY;AAClB,YAAM,UAAU,OAAO,WAAW,YAAY;AAC9C,YAAM,UAAU,KAAK,KAAK,KAAK,WAAW,QAAQ;AAClD,UAAI,KAAK,cAAc,SAAS;AAC9B,cAAM,MAAM,SAAS,cAAc,KAAK;AACxC,YAAI,MAAM,KAAK;AACf,YAAI,MAAM,KAAK,KAAK;AACpB,cAAM,YAAY,GAAG;AAAA,MACvB,OAAO;AAEL,cAAM,UAAU,IAAI,wBAAwB;AAC5C,cAAM,eAAe,SAAS,gBAAgB,8BAA8B,KAAK;AACjF,qBAAa,aAAa,WAAW,WAAW;AAChD,qBAAa,aAAa,SAAS,IAAI;AACvC,qBAAa,aAAa,UAAU,IAAI;AACxC,qBAAa,aAAa,QAAQ,MAAM;AACxC,qBAAa,aAAa,eAAe,MAAM;AAC/C,cAAM,QAAQ,SAAS,gBAAgB,8BAA8B,MAAM;AAC3E,cAAM,aAAa,KAAK,iEAAiE;AACzF,cAAM,aAAa,UAAU,cAAc;AAC3C,cAAM,aAAa,gBAAgB,KAAK;AACxC,cAAM,aAAa,kBAAkB,OAAO;AAC5C,cAAM,aAAa,mBAAmB,OAAO;AAC7C,cAAM,QAAQ,SAAS,gBAAgB,8BAA8B,MAAM;AAC3E,cAAM,aAAa,KAAK,WAAW;AACnC,cAAM,aAAa,UAAU,cAAc;AAC3C,cAAM,aAAa,gBAAgB,KAAK;AACxC,cAAM,aAAa,kBAAkB,OAAO;AAC5C,cAAM,aAAa,mBAAmB,OAAO;AAC7C,qBAAa,YAAY,KAAK;AAC9B,qBAAa,YAAY,KAAK;AAC9B,cAAM,YAAY,YAAY;AAAA,MAChC;AAEA,UAAI,KAAK,WAAW,aAAa;AAC/B,cAAM,gBAAgB,SAAS,cAAc,KAAK;AAClD,sBAAc,YAAY;AAC1B,cAAM,cAAc,YAAY,KAAK,MAAM,OAAO;AAClD,YAAI,aAAa;AACf,wBAAc,YAAY,WAAW;AAAA,QACvC;AACA,cAAM,YAAY,aAAa;AAAA,MACjC,WAAW,KAAK,WAAW,WAAW,CAAC,sBAAsB;AAC3D,cAAM,gBAAgB,SAAS,cAAc,KAAK;AAClD,sBAAc,YAAY;AAC1B,cAAM,YAAY,YAAY,KAAK,MAAM,KAAK;AAC9C,YAAI,WAAW;AACb,wBAAc,YAAY,SAAS;AAAA,QACrC;AACA,cAAM,YAAY,aAAa;AAAA,MACjC;AAEA,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,YAAY;AACjB,WAAK,cAAc,KAAK,KAAK;AAC7B,UAAI,gBAAgB,CAAC,KAAK,kBAAkB;AAC1C,aAAK,MAAM,UAAU;AAAA,MACvB,OAAO;AACL,aAAK,MAAM,UAAU;AAAA,MACvB;AAEA,YAAM,eAAe,SAAS,cAAc,QAAQ;AACpD,mBAAa,OAAO;AACpB,mBAAa,YAAY;AACzB,YAAM,oBACH,KAAK,WAAW,aACd,KAAK,WAAW,WAAW,yBAC9B,CAAC;AACH,mBAAa,WAAW,CAAC;AACzB,mBAAa,SAAS,CAAC;AACvB,mBAAa,MAAM,UAAU,mBAAmB,gBAAgB;AAChE,mBAAa,UAAU,OAAO,WAAW,YAAY;AACrD,YAAM,aAAa,YAAY,KAAK,MAAM,MAAM;AAChD,UAAI,YAAY;AACd,qBAAa,YAAY,UAAU;AAAA,MACrC;AACA,mBAAa,iBAAiB,SAAS,MAAM;AAC3C,YAAI,KAAK,YAAY,SAAS,EAAE,YAAa;AAC7C,aAAK,YAAY,WAAW,KAAK,EAAE;AAAA,MACrC,CAAC;AAED,aAAO,YAAY,KAAK;AACxB,aAAO,YAAY,IAAI;AACvB,aAAO,YAAY,YAAY;AAC/B,SAAG,YAAY,MAAM;AAGrB,UAAI,KAAK,MAAM;AACb,cAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,gBAAQ,YAAY;AACpB,cAAM,WAAW,SAAS,cAAc,MAAM;AAC9C,iBAAS,YAAY;AACrB,iBAAS,cAAc,KAAK;AAC5B,gBAAQ,YAAY,QAAQ;AAC5B,WAAG,YAAY,OAAO;AAAA,MACxB;AAEA,YAAM,iBAAiB,SAAS,cAAc,KAAK;AACnD,qBAAe,YAAY;AAE3B,YAAM,eAAe,SAAS,cAAc,KAAK;AACjD,mBAAa,YAAY;AAEzB,YAAM,kBAAkB,KAAK,WAAW;AACxC,YAAM,oBAAoB,KAAK,WAAW;AAC1C,YAAM,mBAAmB,KAAK,WAAW;AACzC,YAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,YAAY,CAAC,CAAC;AACjE,YAAM,kBAAkB,CAAC,oBAAoB,cAAc;AAC3D,YAAM,sBAAsB,qBAAsB,eAAe,oBAAqB;AAEtF,YAAM,WAAW,qBAAqB,sBAAuB,cAAc,KAAK,CAAC;AACjF,YAAM,aAAa,mBAAmB,aAAa,qBAAqB,UAAU,eAAe,KAAK,aAAa,oBAAoB,aAAa;AAEpJ,qBAAe,QAAQ,QAAQ;AAC/B,qBAAe,QAAQ,SAAS,KAAK;AACrC,qBAAe,QAAQ,WAAW,YAAY,QAAQ,CAAC;AAEvD,qBAAe,UAAU,OAAO,aAAa,QAAQ;AACrD,qBAAe,UAAU,OAAO,YAAY,kBAAkB;AAC9D,qBAAe,UAAU,OAAO,eAAe,gBAAgB;AAC/D,qBAAe,MAAM,UAAU,mBAAmB,SAAS;AAE3D,mBAAa,UAAU,OAAO,YAAY,kBAAkB;AAC5D,mBAAa,UAAU,OAAO,gBAAgB,kBAAkB;AAEhE,UAAI,kBAAkB;AACpB,qBAAa,MAAM,QAAQ;AAAA,MAC7B,WAAW,oBAAoB;AAC7B,qBAAa,MAAM,QAAQ;AAAA,MAC7B,WAAW,qBAAqB,gBAAgB,GAAG;AAEjD,qBAAa,MAAM,QAAQ;AAAA,MAC7B,OAAO;AACL,cAAM,gBAAgB,KAAK,IAAI,aAAa,CAAC;AAC7C,qBAAa,MAAM,QAAQ,GAAG,KAAK,IAAI,eAAe,GAAG,CAAC;AAAA,MAC5D;AAEA,qBAAe,YAAY,YAAY;AAEvC,SAAG,YAAY,cAAc;AAE7B,WAAK,UAAU,YAAY,EAAE;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEQ,oBAAoB,UAAmB;AAE7C,UAAM,iBAAiB,KAAK,cAAc,OAAO,YAAU,CAAC,OAAO,QAAQ;AAC3E,UAAM,uBAAuB,eAAe,SAAS;AAErD,UAAM,mBAAmB,CAAC,cAA2B;AACnD,gBAAU,YAAY;AACtB,UAAI,CAAC,sBAAsB;AACzB,kBAAU,MAAM,UAAU;AAC1B,kBAAU,UAAU,OAAO,yBAAyB;AACpD;AAAA,MACF;AAEA,gBAAU,MAAM,UAAU,WAAW,SAAS;AAC9C,gBAAU,UAAU,OAAO,2BAA2B,CAAC,QAAQ;AAC/D,UAAI,SAAU;AAGd,qBAAe,QAAQ,YAAU;AAC/B,cAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,eAAO,OAAO;AACd,eAAO,YAAY;AAEnB,cAAM,OAAO,YAAY,OAAO,QAAQ,KAAK,MAAM,MAAM;AACzD,YAAI,MAAM;AACR,gBAAM,cAAc,SAAS,cAAc,MAAM;AACjD,sBAAY,YAAY;AACxB,sBAAY,YAAY,IAAI;AAC5B,iBAAO,YAAY,WAAW;AAAA,QAChC;AAEA,cAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,cAAM,YAAY;AAClB,cAAM,cAAc,OAAO;AAC3B,eAAO,YAAY,KAAK;AAExB,eAAO,iBAAiB,SAAS,MAAM,KAAK,mBAAmB,MAAM,CAAC;AACtE,kBAAU,YAAY,MAAM;AAAA,MAC9B,CAAC;AAAA,IACH;AAEA,SAAK,YAAY,QAAQ,eAAa;AACpC,uBAAiB,SAAS;AAAA,IAC5B,CAAC;AAED,QAAI,KAAK,sBAAsB;AAC7B,WAAK,qBAAqB,UAAU,OAAO,cAAc,wBAAwB,CAAC,QAAQ;AAC1F,WAAK,qBAAqB,MAAM,UAAU,uBAAuB,KAAK;AACtE,WAAK,qBAAqB,YAAY;AAAA,IACxC;AACA,QAAI,KAAK,wBAAwB;AAC/B,WAAK,uBAAuB,UAAU,OAAO,cAAc,wBAAwB,CAAC,QAAQ;AAC5F,WAAK,uBAAuB,MAAM,UAAU,uBAAuB,KAAK;AACxE,WAAK,uBAAuB,YAAY;AAAA,IAC1C;AAGA,QAAI,KAAK,gBAAgB,UAAU;AACjC,UAAI,KAAK,WAAW;AAClB,aAAK,UAAU,UAAU,OAAO,6BAA6B,CAAC,oBAAoB;AAAA,MACpF;AACA,UAAI,KAAK,cAAc;AACrB,aAAK,aAAa,UAAU,OAAO,gCAAgC,CAAC,oBAAoB;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,OAAqB,aAAsB;AAClE,QAAI,CAAC,KAAK,kBAAmB;AAC7B,QAAI,MAAM,WAAW,GAAG;AACtB,WAAK,kBAAkB,cAAc,cACjC,KAAK,OAAO,YACZ,KAAK,OAAO;AAChB,WAAK,kBAAkB,UAAU,OAAO,cAAc,YAAY;AAClE;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM;AACpB,UAAM,aAAa,KAAK;AAExB,UAAM,SAAS,UAAU,IAAI,SAAS;AACtC,UAAM,iBAAiB,MAAM,OAAO,UAAQ,KAAK,WAAW,WAAW,EAAE;AAEzE,eAAW,UAAU,IAAI,YAAY;AACrC,eAAW,UAAU,OAAO,cAAc,mBAAmB,KAAK;AAElE,QAAI,aAAa;AACf,iBAAW,cAAc,aAAa,cAAc,IAAI,KAAK,IAAI,MAAM;AACvE;AAAA,IACF;AAEA,QAAI,mBAAmB,OAAO;AAC5B,iBAAW,cAAc,GAAG,KAAK,IAAI,MAAM;AAC3C;AAAA,IACF;AAEA,eAAW,cAAc,GAAG,KAAK,IAAI,MAAM;AAAA,EAC7C;AAAA,EAEQ,uBAAuB,YAAsB;AACnD,UAAM,gBAAgB,WAAW,SAAS;AAC1C,UAAM,SACJ,WAAW,WAAW,IAClB,KAAK,OAAO,sBACZ,KAAK,OAAO;AAClB,UAAM,UAAU,gBACZ,GAAG,MAAM,IAAI,WAAW,KAAK,IAAI,CAAC,KAClC;AAEJ,SAAK,iBAAiB,QAAQ,YAAU;AACtC,aAAO,SAAS,CAAC;AACjB,aAAO,cAAc;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAmB,QAA4B;AACrD,QAAI,OAAO,SAAU;AAErB,SAAK,QAAQ,iBAAiB,MAAM;AACpC,SAAK,cAAc,IAAI,YAAY,gBAAgB,EAAE,QAAQ,OAAO,CAAC,CAAC;AAEtE,QAAI,OAAO,SAAS,YAAY,CAAC,OAAO,QAAQ;AAC9C,WAAK,eAAe;AACpB;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ;AACjB,UAAI;AACF,eAAO,OAAO;AAAA,MAChB,SAAS,OAAO;AACd,gBAAQ,MAAM,6CAA6C,KAAK;AAAA,MAClE;AACA;AAAA,IACF;AAEA,YAAQ,KAAK,gEAAgE,MAAM;AAAA,EACrF;AAAA,EAEQ,sBAAsB;AAC5B,UAAM,QAAS,KAAK,QAAQ,SAAS,CAAC;AACtC,UAAM,eAAe,MAAM;AAC3B,UAAM,cAAc,MAAM;AAC1B,UAAM,qBAAqB,MAAM,sBAAsB,cAAc;AACrE,UAAM,iBAAiB,MAAM,kBAAkB,cAAc;AAC7D,UAAM,aAAa,MAAM;AAEzB,QAAI,iBAAiB,QAAW;AAC9B,WAAK,MAAM;AAAA,QACT;AAAA,QACA,OAAO,iBAAiB,WAAW,GAAG,YAAY,OAAO,OAAO,YAAY;AAAA,MAC9E;AAAA,IACF,OAAO;AACL,WAAK,MAAM,eAAe,aAAa;AAAA,IACzC;AAGA,QAAI,aAAa;AACf,WAAK,MAAM,YAAY,qBAAqB,WAAW;AAAA,IACzD,OAAO;AACL,WAAK,MAAM,eAAe,mBAAmB;AAAA,IAC/C;AAEA,QAAI,oBAAoB;AACtB,WAAK,MAAM,YAAY,oBAAoB,kBAAkB;AAAA,IAC/D;AACA,QAAI,gBAAgB;AAClB,WAAK,MAAM,YAAY,wBAAwB,cAAc;AAAA,IAC/D;AACA,QAAI,YAAY;AACd,WAAK,MAAM,YAAY,oBAAoB,UAAU;AAAA,IACvD;AAEA,UAAM,aAAa,MAAM,cAAc,cAAc;AACrD,QAAI,qBAAqB;AACzB,QAAI,eAAe,YAAY,OAAO,WAAW,aAAa;AAC5D,2BAAqB,OAAO,WAAW,8BAA8B,EAAE,UAAU,SAAS;AAAA,IAC5F;AACA,SAAK,aAAa,cAAc,kBAAkB;AAGlD,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,SAAS;AACX,WAAK,aAAa,gBAAgB,OAAO;AAAA,IAC3C,OAAO;AACL,WAAK,gBAAgB,cAAc;AAAA,IACrC;AAAA,EACF;AACF;AAvsCa,0BACJ,UAAU;;;ACzCZ,SAAS,SAAiB;AAC/B,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM,OAAO,oBAAoB;AAEvC,SAAO,OAAO,IAAI,IAAI;AACxB;AAyEA,SAAS,yBAAqC;AAC5C,MAAI,OAAO,cAAc,YAAa,QAAO;AAC7C,QAAM,MAAW;AACjB,SAAO,IAAI,cAAc,IAAI,iBAAiB,IAAI,oBAAoB;AACxE;AAQO,SAAS,+BAAiD;AAC/D,MAAI,OAAO,cAAc,aAAa;AACpC,WAAO,EAAE,SAAS,WAAW,QAAQ,oBAAoB,UAAU,MAAM;AAAA,EAC3E;AAEA,QAAM,aAAa,uBAAuB;AAC1C,MAAI,CAAC,YAAY;AACf,WAAO,EAAE,SAAS,WAAW,QAAQ,uBAAuB,UAAU,MAAM;AAAA,EAC9E;AAEA,QAAM,WAAW,WAAW,aAAa;AAIzC,QAAM,gBACJ,WAAW,iBAAiB,WAAW;AAEzC,QAAM,eACJ,OAAO,WAAW,aAAa,WAAW,WAAW,WAAW;AAElE,QAAM,QACJ,OAAO,WAAW,QAAQ,WAAW,WAAW,MAAM;AAGxD,MAAI,eAAe;AACjB,QAAI,kBAAkB,aAAa,kBAAkB,MAAM;AACzD,aAAO,EAAE,SAAS,MAAM,QAAQ,iBAAiB,aAAa,IAAI,UAAU,eAAe,cAAc,MAAM;AAAA,IACjH;AACA,QAAI,kBAAkB,MAAM;AAC1B,aAAO,EAAE,SAAS,MAAM,QAAQ,oBAAoB,UAAU,eAAe,cAAc,MAAM;AAAA,IACnG;AACA,QAAI,kBAAkB,MAAM;AAE1B,aAAO,EAAE,SAAS,MAAM,QAAQ,oBAAoB,UAAU,eAAe,cAAc,MAAM;AAAA,IACnG;AAAA,EACF;AAIA,QAAM,OAA2B,WAAW;AAC5C,MAAI,SAAS,UAAU,SAAS,YAAY;AAC1C,WAAO,EAAE,SAAS,QAAQ,QAAQ,QAAQ,IAAI,IAAI,UAAU,eAAe,cAAc,MAAM;AAAA,EACjG;AAIA,MAAI,OAAO,iBAAiB,UAAU;AACpC,QAAI,eAAe,KAAK;AACtB,aAAO,EAAE,SAAS,MAAM,QAAQ,oBAAoB,YAAY,IAAI,UAAU,eAAe,cAAc,MAAM;AAAA,IACnH;AACA,QAAI,eAAe,KAAK;AACtB,aAAO,EAAE,SAAS,MAAM,QAAQ,oBAAoB,YAAY,IAAI,UAAU,eAAe,cAAc,MAAM;AAAA,IACnH;AACA,WAAO,EAAE,SAAS,MAAM,QAAQ,qBAAqB,YAAY,IAAI,UAAU,eAAe,cAAc,MAAM;AAAA,EACpH;AAEA,SAAO,EAAE,SAAS,WAAW,QAAQ,wBAAwB,UAAU,eAAe,cAAc,MAAM;AAC5G;AAEO,SAAS,uBAA0C;AACxD,SAAO,6BAA6B,EAAE;AACxC;AASO,SAAS,wBACd,OACA,MAQa;AACb,QAAM,cAAc,MAAM,eAAe;AACzC,QAAM,kBAAkB,MAAM,mBAAmB;AAEjD,MAAI,UAAU,QAAQ;AACpB,UAAM,WAAW,6BAA6B;AAC9C,QAAI,SAAS,SAAU,QAAO;AAC9B,WAAO,wBAAwB,SAAS,SAAS,IAAI;AAAA,EACvD;AAEA,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;;;AC9LA,IAAI,eAA8B;AAO3B,SAAS,mBAA2B;AACzC,MAAI,iBAAiB,MAAM;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,aAAa,eAAe,OAAO,UAAU,aAAa;AAEnE,mBAAe;AACf,WAAO;AAAA,EACT;AAGA,MAAI;AACF,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,UAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAI,CAAC,KAAK;AACR,qBAAe;AACf,aAAO;AAAA,IACT;AAGA,QAAI;AACF,YAAM,cAAc,OAAO,UAAU,YAAY;AACjD,UAAI,eAAe,YAAY,QAAQ,iBAAiB,MAAM,GAAG;AAC/D,uBAAe;AACf,eAAO;AAAA,MACT;AAAA,IACF,SAAS,GAAG;AAAA,IAEZ;AAGA,QAAI;AACF,YAAM,cAAc,OAAO,UAAU,YAAY;AACjD,UAAI,eAAe,YAAY,QAAQ,iBAAiB,MAAM,GAAG;AAC/D,uBAAe;AACf,eAAO;AAAA,MACT;AAAA,IACF,SAAS,GAAG;AAAA,IAEZ;AAGA,mBAAe;AACf,WAAO;AAAA,EACT,SAAS,GAAG;AAEV,mBAAe;AACf,WAAO;AAAA,EACT;AACF;AAMO,SAAS,oBAA4B;AAC1C,MAAI,iBAAiB,MAAM;AACzB,WAAO;AAAA,EACT;AACA,SAAO,iBAAiB;AAC1B;AAKO,SAAS,mBAAyB;AACvC,iBAAe;AACjB;;;AC/DO,SAAS,qBACd,WACA,UACA,YAAqB,MACrB,mBACQ;AACR,QAAM,QAA8B,CAAC;AAGrC,QAAM,UAAU,CAAC,OAAe,UAAqC;AACnE,QAAI,UAAU,UAAa,UAAU,KAAM;AAE3C,QAAI;AACJ,QAAI,OAAO,UAAU,WAAW;AAC9B,iBAAW,QAAQ,KAAK;AACxB,UAAI,CAAC,MAAO;AAAA,IACd,OAAO;AACL,iBAAW,OAAO,KAAK;AAAA,IACzB;AAIA,QAAI,UAAU;AACd,QAAI,MAAM,WAAW,MAAM,GAAG;AAC5B,gBAAU,SAAS;AAAA,IACrB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,OAAO,GAAG;AACpC,gBAAU,UAAU;AAAA,IACtB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,MAAM,GAAG;AACnC,gBAAU,SAAS;AAAA,IACrB,WAAW,MAAM,WAAW,MAAM,GAAG;AACnC,gBAAU,SAAS;AAAA,IACrB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,QAAQ,GAAG;AACrC,gBAAU,WAAW;AAAA,IACvB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,QAAQ,GAAG;AACrC,gBAAU,WAAW;AAAA,IACvB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,QAAQ,GAAG;AACrC,gBAAU,WAAW;AAAA,IACvB,WAAW,MAAM,WAAW,MAAM,GAAG;AACnC,gBAAU,SAAS;AAAA,IACrB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,IAAI,GAAG;AACjC,gBAAU,OAAO;AAAA,IACnB,WAAW,MAAM,WAAW,KAAK,GAAG;AAClC,gBAAU,QAAQ;AAAA,IACpB;AAEA,UAAM,KAAK,EAAE,OAAO,OAAO,UAAU,QAAQ,CAAC;AAAA,EAChD;AAGA,MAAI,UAAU,MAAM,OAAW,SAAQ,MAAM,UAAU,CAAC;AACxD,MAAI,UAAU,MAAM,OAAW,SAAQ,MAAM,UAAU,CAAC;AACxD,MAAI,UAAU,KAAK;AACjB,UAAM,SAAiC;AAAA,MACrC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO;AAAA,IACT;AACA,YAAQ,MAAM,OAAO,UAAU,GAAG,KAAK,UAAU,GAAG;AAAA,EACtD;AACA,MAAI,UAAU,GAAI,SAAQ,OAAO,UAAU,EAAE;AAC7C,MAAI,UAAU,EAAG,SAAQ,MAAM,UAAU,CAAC;AAC1C,MAAI,UAAU,GAAI,SAAQ,OAAO,UAAU,EAAE;AAC7C,MAAI,UAAU,MAAO,SAAQ,OAAO,UAAU,KAAK;AAGnD,MAAI,UAAU,MAAM,OAAW,SAAQ,MAAM,UAAU,CAAC;AACxD,MAAI,UAAU,MAAM,OAAW,SAAQ,MAAM,UAAU,CAAC;AACxD,MAAI,UAAU,KAAM,SAAQ,SAAS,UAAU,IAAI;AACnD,MAAI,UAAU,OAAO,OAAW,SAAQ,OAAO,UAAU,EAAE;AAG3D,MAAI,SAAS,UAAU,KAAK,UAAU;AAEtC,MAAI,WAAW,UAAU,WAAW,QAAW;AAC7C,aAAS,kBAAkB;AAAA,EAC7B;AACA,MAAI,OAAQ,SAAQ,MAAM,MAAM;AAGhC,MAAI,UAAU,UAAU;AAIxB,MAAI,YAAY,UAAU,YAAY,QAAW;AAC/C,UAAM,iBAAiB,UAAU;AAGjC,QAAI,YAAY,QAAW;AACzB,gBAAU;AAAA,IACZ;AAGA,QAAI,YAAY,UAAU,YAAY,QAAW;AAC/C,UAAI,mBAAmB;AAGrB,cAAM,kBAAkB,wBAAwB,iBAAiB;AACjE,kBAAU;AAAA,MACZ,OAAO;AAEL,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAY,OAAW,SAAQ,MAAM,OAAO;AAGhD,MAAI,UAAU,IAAI;AAChB,QAAI,UAAU,GAAG,WAAW,MAAM,GAAG;AACnC,cAAQ,WAAW,UAAU,GAAG,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACrD,OAAO;AACL,cAAQ,OAAO,UAAU,EAAE;AAAA,IAC7B;AAAA,EACF;AAGA,MAAI,UAAU,EAAG,SAAQ,MAAM,UAAU,CAAC;AAG1C,MAAI,aAAa,UAAU,QAAQ,QAAW;AAC5C,UAAM,MAAM,OAAO;AACnB,QAAI,QAAQ,EAAG,SAAQ,QAAQ,GAAG;AAAA,EACpC,WAAW,UAAU,QAAQ,QAAW;AACtC,YAAQ,QAAQ,UAAU,GAAG;AAAA,EAC/B;AAGA,MAAI,UAAU,YAAY,QAAW;AACnC,QAAI,OAAO,UAAU,YAAY,aAAa,UAAU,SAAS;AAC/D,cAAQ,aAAa,EAAE;AAAA,IACzB,WAAW,OAAO,UAAU,YAAY,UAAU;AAChD,cAAQ,aAAa,UAAU,OAAO;AAAA,IACxC,WAAW,OAAO,UAAU,YAAY,UAAU;AAChD,YAAM,EAAE,MAAM,MAAM,IAAI,UAAU;AAClC,UAAI,QAAQ,QAAQ;AACpB,UAAI,UAAU,OAAW,UAAS,IAAI,KAAK;AAC3C,cAAQ,aAAa,KAAK;AAAA,IAC5B;AAAA,EACF;AACA,MAAI,UAAU,gBAAgB,OAAW,SAAQ,mBAAmB,UAAU,WAAW;AACzF,MAAI,UAAU,eAAe,OAAW,SAAQ,iBAAiB,UAAU,UAAU;AACrF,MAAI,UAAU,aAAa,OAAW,SAAQ,eAAe,UAAU,QAAQ;AAC/E,MAAI,UAAU,eAAe,OAAW,SAAQ,iBAAiB,UAAU,UAAU;AACrF,MAAI,UAAU,UAAU,OAAW,SAAQ,YAAY,UAAU,KAAK;AACtE,MAAI,UAAU,YAAY,QAAW;AACnC,QAAI,OAAO,UAAU,YAAY,aAAa,UAAU,SAAS;AAC/D,cAAQ,aAAa,EAAE;AAAA,IACzB,OAAO;AACL,cAAQ,cAAc,UAAU,OAAO;AAAA,IACzC;AAAA,EACF;AACA,MAAI,UAAU,UAAW,SAAQ,eAAe,EAAE;AAClD,MAAI,UAAU,eAAe,OAAW,SAAQ,iBAAiB,UAAU,UAAU;AACrF,MAAI,UAAU,QAAQ,OAAW,SAAQ,UAAU,UAAU,GAAG;AAChE,MAAI,UAAU,WAAW,OAAW,SAAQ,aAAa,UAAU,MAAM;AACzE,MAAI,UAAU,SAAS,OAAW,SAAQ,WAAW,UAAU,IAAI;AACnE,MAAI,UAAU,UAAW,SAAQ,eAAe,EAAE;AAClD,MAAI,UAAU,OAAQ,SAAQ,YAAY,EAAE;AAC5C,MAAI,UAAU,SAAS,OAAW,SAAQ,WAAW,UAAU,IAAI;AACnE,MAAI,UAAU,aAAa,OAAW,SAAQ,eAAe,UAAU,QAAQ;AAC/E,MAAI,UAAU,eAAe,OAAW,SAAQ,iBAAiB,UAAU,UAAU;AACrF,MAAI,UAAU,YAAY,OAAW,SAAQ,cAAc,UAAU,OAAO;AAC5E,MAAI,UAAU,aAAa,OAAW,SAAQ,eAAe,UAAU,QAAQ;AAC/E,MAAI,UAAU,cAAc,OAAW,SAAQ,gBAAgB,UAAU,SAAS;AAClF,MAAI,UAAU,YAAa,SAAQ,kBAAkB,EAAE;AACvD,MAAI,UAAU,gBAAgB,OAAW,SAAQ,kBAAkB,UAAU,WAAW;AACxF,MAAI,UAAU,OAAQ,SAAQ,aAAa,UAAU,MAAM;AAC3D,MAAI,UAAU,OAAQ,SAAQ,aAAa,UAAU,MAAM;AAC3D,MAAI,UAAU,cAAc,OAAW,SAAQ,gBAAgB,UAAU,SAAS;AAClF,MAAI,UAAU,SAAU,SAAQ,eAAe,UAAU,QAAQ;AACjE,MAAI,UAAU,UAAW,SAAQ,eAAe,EAAE;AAClD,MAAI,UAAU,QAAS,SAAQ,aAAa,EAAE;AAC9C,MAAI,UAAU,WAAW,OAAW,SAAQ,aAAa,UAAU,MAAM;AACzE,MAAI,UAAU,SAAS,OAAW,SAAQ,WAAW,UAAU,IAAI;AACnE,MAAI,UAAU,OAAQ,SAAQ,aAAa,UAAU,MAAM;AAC3D,MAAI,UAAU,OAAQ,SAAQ,aAAa,UAAU,MAAM;AAC3D,MAAI,UAAU,QAAS,SAAQ,cAAc,UAAU,OAAO;AAC9D,MAAI,UAAU,YAAa,SAAQ,kBAAkB,EAAE;AACvD,MAAI,UAAU,YAAa,SAAQ,mBAAmB,UAAU,WAAW;AAG3E,MAAI,UAAU,MAAO,SAAQ,MAAM,UAAU,KAAK;AAGlD,SAAO,KAAK,SAAS,EAAE,QAAQ,SAAO;AACpC,QAAI,IAAI,WAAW,GAAG,KAClB;AAAA,MAAC;AAAA,MAAK;AAAA,MAAK;AAAA,MAAO;AAAA,MAAM;AAAA,MAAK;AAAA,MAAM;AAAA,MAAS;AAAA,MAAK;AAAA,MAAK;AAAA,MAAQ;AAAA,MAAM;AAAA,MAAK;AAAA,MAAK;AAAA,MAAM;AAAA,MAAK;AAAA,MACxF;AAAA,MAAW;AAAA,MAAe;AAAA,MAAc;AAAA,MAAY;AAAA,MAAc;AAAA,MAAS;AAAA,MAC3E;AAAA,MAAa;AAAA,MAAc;AAAA,MAAO;AAAA,MAAU;AAAA,MAAQ;AAAA,MAAa;AAAA,MAAU;AAAA,MAC3E;AAAA,MAAY;AAAA,MAAc;AAAA,MAAW;AAAA,MAAY;AAAA,MAAa;AAAA,MAAe;AAAA,MAC7E;AAAA,MAAU;AAAA,MAAU;AAAA,MAAa;AAAA,MAAY;AAAA,MAAa;AAAA,MAAW;AAAA,MAAU;AAAA,MAC/E;AAAA,MAAU;AAAA,MAAU;AAAA,MAAW;AAAA,MAAe;AAAA,MAAe;AAAA,MAAS;AAAA,IAAQ,EAAE,SAAS,GAAG,GAAG;AAClG;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,GAAG,MAAM,YAAY,OAAO,UAAU,GAAG,MAAM,YAAY,OAAO,UAAU,GAAG,MAAM,WAAW;AACnH,cAAQ,KAAK,UAAU,GAAG,CAAQ;AAAA,IACpC;AAAA,EACF,CAAC;AAGD,QAAM,KAAK,CAAC,GAAG,MAAM;AAEnB,UAAM,UAAU,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI;AACxC,UAAM,UAAU,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI;AAExC,QAAI,YAAY,SAAS;AACvB,aAAO,QAAQ,cAAc,OAAO;AAAA,IACtC;AAGA,WAAO,EAAE,MAAM,cAAc,EAAE,KAAK;AAAA,EACtC,CAAC;AAGD,QAAM,gBAAgB,MAAM,IAAI,OAAK;AACnC,QAAI,EAAE,UAAU,IAAI;AAClB,aAAO,EAAE;AAAA,IACX;AACA,WAAO,GAAG,EAAE,KAAK,GAAG,EAAE,KAAK;AAAA,EAC7B,CAAC,EAAE,KAAK,GAAG;AAGX,QAAM,aAAuB,CAAC;AAC9B,MAAI,UAAU,UAAU,UAAU,OAAO,SAAS,GAAG;AACnD,cAAU,OAAO,QAAQ,WAAS;AAChC,YAAM,sBAA4C,CAAC;AAEnD,YAAM,eAAe,CAAC,OAAe,UAAqC;AACxE,YAAI,UAAU,UAAa,UAAU,KAAM;AAE3C,YAAI;AACJ,YAAI,OAAO,UAAU,WAAW;AAC9B,qBAAW,QAAQ,KAAK;AACxB,cAAI,CAAC,MAAO;AAAA,QACd,OAAO;AACL,qBAAW,OAAO,KAAK;AAAA,QACzB;AAEA,4BAAoB,KAAK;AAAA,UACvB;AAAA,UACA,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAEA,0BAAoB,OAAO,YAAY;AAIvC,YAAM,YAAY,oBAAoB,KAAK,OAAK,EAAE,UAAU,gBAAgB;AAC5E,YAAM,eAAe,oBAAoB,OAAO,OAAK,EAAE,UAAU,gBAAgB;AAGjF,YAAM,qBAAqB,CAAC,UAA0B;AAEpD,YAAI,MAAM,WAAW,UAAU,KAAK,MAAM,WAAW,SAAS,EAAG,QAAO;AAExE,YAAI,MAAM,WAAW,KAAK,KAAK,MAAM,WAAW,KAAK,EAAG,QAAO;AAE/D,YAAI,MAAM,WAAW,SAAS,EAAG,QAAO;AAExC,YAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AACpC,YAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AAEpC,YAAI,MAAM,WAAW,IAAI,EAAG,QAAO;AAEnC,YAAI,MAAM,WAAW,GAAG,EAAG,QAAO;AAElC,YAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AAEpC,YAAI,MAAM,WAAW,IAAI,EAAG,QAAO;AAEnC,YAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AAEpC,YAAI,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,IAAI,EAAG,QAAO;AAE7D,YAAI,MAAM,WAAW,KAAK,EAAG,QAAO;AAEpC,YAAI,MAAM,WAAW,IAAI,EAAG,QAAO;AAEnC,eAAO;AAAA,MACT;AAEA,mBAAa,KAAK,CAAC,GAAG,MAAM;AAC1B,cAAM,SAAS,mBAAmB,EAAE,KAAK;AACzC,cAAM,SAAS,mBAAmB,EAAE,KAAK;AAEzC,YAAI,WAAW,QAAQ;AACrB,iBAAO,SAAS;AAAA,QAClB;AAGA,eAAO,EAAE,MAAM,cAAc,EAAE,KAAK;AAAA,MACtC,CAAC;AAGD,YAAM,cAAc;AAAA,QAClB,GAAG,aAAa,IAAI,OAAK,EAAE,UAAU,KAAK,EAAE,QAAQ,GAAG,EAAE,KAAK,GAAG,EAAE,KAAK,EAAE;AAAA,QAC1E,GAAI,YAAY,CAAC,UAAU,KAAK,IAAI,CAAC;AAAA,MACvC,EAAE,KAAK,GAAG;AAEV,UAAI,aAAa;AACf,mBAAW,KAAK,WAAW;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,WAAW,gBAAgB,CAAC,eAAe,GAAG,UAAU,IAAI;AAClE,SAAO,SAAS,KAAK,GAAG;AAC1B;AAEA,SAAS,oBAAoB,OAAqB,SAAoE;AACpH,MAAI,MAAM,SAAS,QAAQ;AAGzB,UAAM,QAAkB,CAAC;AACzB,QAAI,MAAM,WAAY,OAAM,KAAK,MAAM,UAAU;AACjD,QAAI,MAAM,aAAa,OAAW,OAAM,KAAK,OAAO,MAAM,QAAQ,CAAC;AACnE,QAAI,MAAM,UAAW,OAAM,KAAK,MAAM,SAAS;AAC/C,QAAI,MAAM,MAAO,OAAM,KAAK,MAAM,KAAK;AAEvC,UAAM,OAAO,MAAM,OAAO,mBAAmB,MAAM,IAAI,IAAI;AAC3D,UAAM,YAAY,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,KAAK;AACpE,YAAQ,WAAW,SAAS;AAG5B,QAAI,MAAM,WAAW;AAEnB,YAAM,QAAQ,MAAM,UAAU,QAAQ,KAAK,EAAE;AAC7C,cAAQ,OAAO,KAAK;AAAA,IACtB;AACA,QAAI,MAAM,WAAW;AAEnB,YAAM,YAAY,mBAAmB,MAAM,SAAS;AACpD,UAAI,UAAW,SAAQ,OAAO,SAAS;AAAA,IACzC;AACA,QAAI,MAAM,aAAa,OAAW,SAAQ,MAAM,MAAM,QAAQ;AAC9D,QAAI,MAAM,MAAM,OAAW,SAAQ,MAAM,MAAM,CAAC;AAChD,QAAI,MAAM,MAAM,OAAW,SAAQ,MAAM,MAAM,CAAC;AAAA,EAClD,WAAW,MAAM,SAAS,SAAS;AAIjC,QAAI,MAAM,WAAW;AACnB,cAAQ,YAAY,MAAM,SAAS;AAAA,IACrC;AAGA,QAAI,MAAM,UAAW,SAAQ,WAAW,MAAM,SAAS;AACvD,QAAI,MAAM,UAAU,OAAW,SAAQ,OAAO,MAAM,KAAK;AACzD,QAAI,MAAM,WAAW,OAAW,SAAQ,OAAO,MAAM,MAAM;AAC3D,QAAI,MAAM,WAAW;AAEnB,YAAM,YAAY,mBAAmB,MAAM,SAAS;AACpD,UAAI,UAAW,SAAQ,OAAO,SAAS;AAAA,IACzC;AACA,QAAI,MAAM,YAAY,OAAW,SAAQ,MAAM,MAAM,OAAO;AAC5D,QAAI,MAAM,aAAa,OAAW,SAAQ,OAAO,MAAM,QAAQ;AAC/D,QAAI,MAAM,KAAM,SAAQ,OAAO,MAAM,IAAI;AACzC,QAAI,MAAM,YAAa,SAAQ,QAAQ,MAAM,WAAW;AACxD,QAAI,MAAM,YAAY,OAAW,SAAQ,OAAO,MAAM,OAAO;AAC7D,QAAI,MAAM,OAAQ,SAAQ,OAAO,MAAM,MAAM;AAC7C,QAAI,MAAM,WAAY,SAAQ,QAAQ,MAAM,UAAU;AACtD,QAAI,MAAM,SAAU,SAAQ,OAAO,MAAM,QAAQ;AACjD,QAAI,MAAM,iBAAiB,OAAW,SAAQ,QAAQ,MAAM,YAAY;AACxE,QAAI,MAAM,KAAM,SAAQ,UAAU,MAAM,IAAI;AAC5C,QAAI,MAAM,SAAS,OAAW,SAAQ,UAAU,MAAM,IAAI;AAC1D,QAAI,MAAM,MAAM,OAAW,SAAQ,MAAM,MAAM,CAAC;AAChD,QAAI,MAAM,MAAM,OAAW,SAAQ,MAAM,MAAM,CAAC;AAChD,QAAI,MAAM,UAAW,SAAQ,MAAM,MAAM,SAAS;AAGlD,QAAI,MAAM,SAAS;AACjB,YAAM,UAAU,MAAM;AACtB,UAAI,QAAQ,YAAY,QAAW;AACjC,YAAI,OAAO,QAAQ,YAAY,aAAa,QAAQ,SAAS;AAC3D,kBAAQ,cAAc,EAAE;AAAA,QAC1B,WAAW,OAAO,QAAQ,YAAY,UAAU;AAC9C,kBAAQ,cAAc,QAAQ,OAAO;AAAA,QACvC;AAAA,MACF;AACA,UAAI,QAAQ,YAAY,OAAW,SAAQ,eAAe,QAAQ,OAAO;AACzE,UAAI,QAAQ,eAAe,OAAW,SAAQ,kBAAkB,QAAQ,UAAU;AAClF,UAAI,QAAQ,eAAe,OAAW,SAAQ,kBAAkB,QAAQ,UAAU;AAClF,UAAI,QAAQ,aAAa,OAAW,SAAQ,gBAAgB,QAAQ,QAAQ;AAC5E,UAAI,QAAQ,QAAQ,OAAW,SAAQ,WAAW,QAAQ,GAAG;AAC7D,UAAI,QAAQ,WAAW,OAAW,SAAQ,cAAc,QAAQ,MAAM;AACtE,UAAI,QAAQ,SAAS,OAAW,SAAQ,YAAY,QAAQ,IAAI;AAChE,UAAI,QAAQ,UAAW,SAAQ,gBAAgB,EAAE;AACjD,UAAI,QAAQ,OAAQ,SAAQ,aAAa,EAAE;AAC3C,UAAI,QAAQ,SAAS,OAAW,SAAQ,YAAY,QAAQ,IAAI;AAChE,UAAI,QAAQ,aAAa,OAAW,SAAQ,gBAAgB,QAAQ,QAAQ;AAC5E,UAAI,QAAQ,eAAe,OAAW,SAAQ,kBAAkB,QAAQ,UAAU;AAClF,UAAI,QAAQ,YAAY,OAAW,SAAQ,eAAe,QAAQ,OAAO;AACzE,UAAI,QAAQ,aAAa,OAAW,SAAQ,gBAAgB,QAAQ,QAAQ;AAC5E,UAAI,QAAQ,cAAc,OAAW,SAAQ,iBAAiB,QAAQ,SAAS;AAC/E,UAAI,QAAQ,YAAa,SAAQ,mBAAmB,EAAE;AACtD,UAAI,QAAQ,gBAAgB,OAAW,SAAQ,mBAAmB,QAAQ,WAAW;AACrF,UAAI,QAAQ,eAAe,OAAW,SAAQ,kBAAkB,QAAQ,UAAU;AAClF,UAAI,QAAQ,UAAU,OAAW,SAAQ,aAAa,QAAQ,KAAK;AACnE,UAAI,QAAQ,gBAAgB,OAAW,SAAQ,oBAAoB,QAAQ,WAAW;AACtF,UAAI,QAAQ,UAAW,SAAQ,gBAAgB,EAAE;AAAA,IACnD;AAAA,EACF;AAGA,UAAQ,kBAAkB,EAAE;AAC9B;AAMA,SAAS,mBAAmB,WAA2B;AACrD,QAAM,UAAkC;AAAA,IACtC,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,QAAQ;AAAA,EACV;AACA,SAAO,QAAQ,UAAU,YAAY,CAAC,KAAK,UAAU,YAAY;AACnE;;;AC3fO,SAAS,cACd,SACA,WACA,KACA,WACA,UACA,YAAqB,MACrB,mBACQ;AAER,QAAM,iBAAiB,QAAQ,QAAQ,QAAQ,EAAE;AAGjD,QAAM,eAAe,qBAAqB,aAAa,CAAC,GAAG,UAAU,WAAW,iBAAiB;AAGjG,QAAM,cAAc,IACjB,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,aAAW,mBAAmB,OAAO,CAAC,EAC1C,KAAK,GAAG;AAGX,MAAI,cAAc;AAChB,WAAO,GAAG,cAAc,IAAI,SAAS,IAAI,YAAY,IAAI,WAAW;AAAA,EACtE,OAAO;AACL,WAAO,GAAG,cAAc,IAAI,SAAS,IAAI,WAAW;AAAA,EACtD;AACF;;;AC1BA,IAAM,6BAA6B,CAAC,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,MAAM,IAAI;AAC/E,IAAM,4BAA4B,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,GAAG;AAMpE,SAAS,oBAAoB,OAA8B;AAEzD,QAAM,YAAY,MAAM,MAAM,oBAAoB;AAClD,MAAI,CAAC,aAAa,UAAU,WAAW,EAAG,QAAO;AAEjD,QAAM,WAAW,UAAU,IAAI,OAAK,WAAW,CAAC,CAAC;AACjD,SAAO,KAAK,IAAI,GAAG,QAAQ;AAC7B;AAkBO,SAAS,6BACd,SACA,WACA,SACA,UACA,oBAA8B,4BAC9B,mBAA6B,2BAC7B,YAAqB,MACrB,mBACsB;AACtB,QAAM,EAAE,KAAK,OAAO,OAAO,WAAW,YAAY,IAAI;AAGtD,QAAM,uBAAuB,eAAe;AAG5C,MAAI,UAAU,UAAa,CAAC,OAAO;AACjC,UAAM,MAAM,YAAY,OAAO,IAAI;AACnC,UAAMC,aAAY;AAGlB,UAAMC,eAAwB,CAAC;AAG/B,UAAM,cAAgC;AAAA,MACpC,GAAG;AAAA,MACH,GAAGD;AAAA,MACH,KAAK;AAAA,IACP;AACA,UAAM,QAAQ,cAAc,SAAS,WAAW,KAAK,aAAa,UAAU,OAAO,iBAAiB;AACpG,IAAAC,aAAY,KAAK,GAAG,KAAK,KAAK;AAG9B,QAAI,OAAO,GAAG;AACZ,YAAM,cAAgC;AAAA,QACpC,GAAG;AAAA,QACH,GAAGD;AAAA,QACH,KAAK;AAAA,MACP;AACA,YAAM,QAAQ,cAAc,SAAS,WAAW,KAAK,aAAa,UAAU,OAAO,iBAAiB;AACpG,MAAAC,aAAY,KAAK,GAAG,KAAK,KAAK;AAAA,IAChC;AAGA,UAAMC,iBAAkC;AAAA,MACtC,GAAG;AAAA,MACH,GAAGF;AAAA,IACL;AACA,UAAMG,WAAU,cAAc,SAAS,WAAW,KAAKD,gBAAe,UAAU,WAAW,iBAAiB;AAE5G,WAAO;AAAA,MACL,KAAKC;AAAA,MACL,QAAQF,aAAY,KAAK,IAAI;AAAA,MAC7B,OAAOD;AAAA,IACT;AAAA,EACF;AAGA,MAAI,OAAO;AACT,UAAM,QAAQ,oBAAoB,KAAK;AAMvC,UAAM,sBAAsB,qBAAqB,OAAO,QAAM;AAG5D,aAAO;AAAA,IACT,CAAC;AAGD,UAAMC,eAAc,oBAAoB,IAAI,QAAM;AAChD,YAAM,qBAAuC;AAAA,QAC3C,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AACA,YAAM,MAAM,cAAc,SAAS,WAAW,KAAK,oBAAoB,UAAU,WAAW,iBAAiB;AAC7G,aAAO,GAAG,GAAG,IAAI,EAAE;AAAA,IACrB,CAAC;AAGD,UAAMD,aAAY,SAAS,oBAAoB,CAAC,KAAK,qBAAqB,CAAC;AAC3E,UAAME,iBAAkC;AAAA,MACtC,GAAG;AAAA,MACH,GAAGF;AAAA,IACL;AACA,UAAMG,WAAU,cAAc,SAAS,WAAW,KAAKD,gBAAe,UAAU,WAAW,iBAAiB;AAE5G,WAAO;AAAA,MACL,KAAKC;AAAA,MACL,QAAQF,aAAY,KAAK,IAAI;AAAA,MAC7B;AAAA,MACA,OAAOD;AAAA,IACT;AAAA,EACF;AAIA,QAAM,cAAc,qBAAqB,IAAI,QAAM;AACjD,UAAM,qBAAuC;AAAA,MAC3C,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AACA,UAAM,MAAM,cAAc,SAAS,WAAW,KAAK,oBAAoB,UAAU,WAAW,iBAAiB;AAC7G,WAAO,GAAG,GAAG,IAAI,EAAE;AAAA,EACrB,CAAC;AAGD,QAAM,YAAY,qBAAqB,CAAC;AACxC,QAAM,gBAAkC;AAAA,IACtC,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACA,QAAM,UAAU,cAAc,SAAS,WAAW,KAAK,eAAe,UAAU,WAAW,iBAAiB;AAE5G,SAAO;AAAA,IACL,KAAK;AAAA,IACL,QAAQ,YAAY,KAAK,IAAI;AAAA,IAC7B,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;;;AClJA,IAAMI,oBAAmB;AACzB,IAAMC,8BAA6B,CAAC,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,MAAM,IAAI;AAC/E,IAAMC,6BAA4B,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,GAAG;AAE7D,SAAS,SAAS,QAAoC;AAC3D,QAAM;AAAA,IACJ,UAAUF;AAAA,IACV;AAAA,IACA,WAAW,CAAC;AAAA,IACZ,oBAAoBC;AAAA,IACpB,mBAAmBC;AAAA,IACnB,YAAY;AAAA,IACZ,mBAAmB,0BAA0B;AAAA,EAC/C,IAAI;AAEJ,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAGA,QAAM,qBAAqB;AAAA,IACzB,GAAG,SAAS,KAAK;AAAA,IACjB,GAAG,SAAS,MAAM,SAAY,SAAS,IAAI;AAAA,IAC3C,GAAG;AAAA,EACL;AAKA,QAAM,6BACJ,4BAA4B,UACvB,MAAM;AACL,UAAM,WAAW,qBAAqB;AACtC,YAAQ,IAAI,YAAY,QAAQ;AAChC,WAAO,aAAa,YAAY,SAAS;AAAA,EAC3C,GAAG,IACH;AAEN,QAAM,WAAuB;AAAA;AAAA;AAAA;AAAA,IAI3B,IAAI,KAAa,WAAsC;AACrD,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAgB,WAAqC;AACnD,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,0BAA0B,SAAkD;AAE1E,YAAM,6BAA6B,QAAQ,eAAe;AAE1D,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,SAAiB;AACf,aAAO,OAAO;AAAA,IAChB;AAAA;AAAA;AAAA;AAAA,IAKA,uBAAgE;AAC9D,aAAO,qBAAqB;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;;;AZxGA,IAAM,mBAA2C;AAAA,EAC/C,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAEA,SAAS,sBAAsB;AAC7B,MACE,OAAO,eAAe,eACtB,OAAO,WAAW,mBAAmB,aACrC;AACA;AAAA,EACF;AACA,MAAI,CAAC,WAAW,eAAe,IAAI,0BAA0B,OAAO,GAAG;AACrE,eAAW,eAAe;AAAA,MACxB,0BAA0B;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAA2C;AAChE,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,UAAU,SAAS,cAA2B,MAAM;AAC1D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,mBAAmB,MAAM,aAAa;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,WAAsD;AAC9E,MAAI,CAAC,UAAW,QAAO;AACvB,MAAI,OAAO,cAAc,UAAU;AACjC,UAAM,UAAU,SAAS,cAA2B,SAAS;AAC7D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,sBAAsB,SAAS,aAAa;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAiC;AAC3D,QAAM,OAAO;AAAA,IACX,cAAc,cAAc;AAAA,IAC5B,oBAAoB,cAAc;AAAA,IAClC,gBAAgB,cAAc;AAAA,EAChC;AAEA,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,GAAG;AAAA,MACL;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,GAAG;AAAA,MACL;AAAA,IACF;AACE,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,GAAG;AAAA,MACL;AAAA,EACJ;AACF;AAEA,SAAS,qBAAqB,OAAiD;AAC7E,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,WAAW,MAAM,QAAQ,KAAK,IAChC,QACA,MACG,MAAM,GAAG,EACT,IAAI,WAAS,MAAM,KAAK,CAAC,EACzB,OAAO,OAAO;AAErB,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,WAAiC,CAAC;AACxC,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,SAAS,UAAU;AAC5B,UAAM,aAAa,MAAM,YAAY,EAAE,QAAQ,YAAY,EAAE;AAC7D,UAAM,WAAW,iBAAiB,UAAU,KAAK;AACjD,QAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,UAAM,QAAQ,gBAAgB,KAAK,YAAU,OAAO,OAAO,QAAQ;AACnE,QAAI,OAAO;AACT,eAAS,KAAK,KAAK;AACnB,WAAK,IAAI,QAAQ;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,SACA,gBAAgB,OACY;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,aAAkB,EAAE,GAAG,KAAK;AAElC,MAAI,SAAS,QAAW;AACtB,eAAW,OAAO,SAAS,WAAW,WAAW;AAAA,EACnD,WAAW,eAAe;AACxB,eAAW,OAAO;AAAA,EACpB;AAEA,MAAI,UAAU,QAAW;AACvB,eAAW,QAAQ,mBAAmB,KAAK;AAAA,EAC7C,WAAW,eAAe;AACxB,eAAW,QAAQ,mBAAmB,OAAO;AAAA,EAC/C;AAEA,MAAI,QAAQ,YAAY,QAAW;AACjC,eAAW,UAAU,QAAQ;AAAA,EAC/B,WAAW,eAAe;AACxB,eAAW,UAAU;AAAA,EACvB;AAEA,MAAI,YAAY,QAAW;AACzB,eAAW,UAAU,qBAAqB,OAAO;AAAA,EACnD,WAAW,aAAa,SAAS;AAE/B,eAAW,UAAU,CAAC;AAAA,EACxB,WAAW,eAAe;AACxB,eAAW,UAAU,CAAC;AAAA,EACxB;AAEA,MAAI,eAAe,QAAW;AAC5B,eAAW,aAAa;AAAA,EAC1B;AAEA,MAAI,WAAW,QAAW;AACxB,eAAW,SAAS;AAAA,EACtB;AAEA,MAAI,eAAe,QAAW;AAC5B,eAAW,aAAa;AAAA,EAC1B,WAAW,eAAe;AACxB,eAAW,aAAa;AAAA,EAC1B;AAEA,MAAI,qBAAqB,QAAW;AAClC,eAAW,mBAAmB;AAAA,EAChC,WAAW,eAAe;AACxB,eAAW,mBAAmB;AAAA,EAChC;AAEA,MAAI,QAAQ,yBAAyB,QAAW;AAC9C,eAAW,uBAAuB,QAAQ;AAAA,EAC5C,WAAW,eAAe;AACxB,eAAW,uBAAuB;AAAA,EACpC;AAEA,SAAO;AACT;AAEO,SAAS,eAAe,SAAkD;AAE/E,QAAM,YAAY,iBAAiB,QAAQ,SAAS;AACpD,QAAM,gBAAgB,cAAc,QAAQ,MAAM;AAClD,QAAM,iBAAiB,aAAa;AAEpC,sBAAoB;AAEpB,QAAM,SAAS,SAAS;AAAA,IACtB,0BAA0B;AAAA,EAC5B;AAGA,iBAAe,YAAY;AAC3B,iBAAe,YAAY,MAAM;AAEjC,QAAM,SAAS,IAAI,oBAAoB;AAAA,IACrC,QAAQ,QAAQ;AAAA,IAChB,aAAa,QAAQ;AAAA,EACvB,CAAC;AAED,QAAM,oBAAoB,iBAAiB,SAAS,IAAI;AAIxD,MAAI,aAAa,cAAc,gBAAgB;AAC7C,sBAAkB,YAAY;AAAA,EAChC,OAAO;AAEL,sBAAkB,YAAY;AAAA,EAChC;AAEA,QAAM,aAAa,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,cAAc,YAAY,iBAAiB;AAElD,SAAO;AAAA,IACL,gBAAgB,MAAM,OAAO,eAAe;AAAA,IAC5C,aAAa,MAAM,WAAW,UAAU;AAAA,IACxC,OAAO,MAAM,WAAW,MAAM;AAAA,IAC9B,SAAS,MAAM;AACb,iBAAW,OAAO;AAClB,iBAAW,MAAM;AACjB,aAAO,OAAO;AAAA,IAChB;AAAA,IACA,eAAe,CAAC,mBAAmD;AACjE,YAAM,aAAa,iBAAiB,gBAAgB,KAAK;AACzD,iBAAW,WAAW,UAAU;AAChC,aAAO,cAAc,UAAU;AAAA,IACjC;AAAA,IACA,UAAU,MAAM,WAAW,SAAS;AAAA,EACtC;AACF;AAGO,SAAS,oCAAoC;AAClD,sBAAoB;AACtB;","names":["item","message","containerStyle","baseWidth","srcSetParts","baseTransform","baseSrc","DEFAULT_BASE_URL","DEFAULT_DEVICE_BREAKPOINTS","DEFAULT_IMAGE_BREAKPOINTS"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants/defaults.ts","../src/client/api-client.ts","../src/utils/helpers.ts","../src/core/uploader-controller.ts","../src/widget/styles.ts","../src/widget/uploader-element.ts","../src/viewtag/device.ts","../src/viewtag/format-detection.ts","../src/viewtag/transform.ts","../src/viewtag/url-builder.ts","../src/viewtag/responsive.ts","../src/viewtag/create-ar.ts"],"sourcesContent":["import { AutorenderApiClient } from './client/api-client';\nimport { UploaderController } from './core/uploader-controller';\nimport type { ControllerOptions } from './core/uploader-controller';\nimport { DEFAULT_THEME, DEFAULT_SOURCES, DEFAULT_ASSET_DELIVERY_BASE_URL } from './constants/defaults';\nimport type {\n CreateUploaderOptions,\n UploaderInstance,\n ThemeOptions,\n UploadSourceOption,\n} from './types';\nimport { AutorenderUploaderElement } from './widget/uploader-element';\n\ntype ThemeName = 'light' | 'dark' | 'system';\n\nconst SOURCE_ALIAS_MAP: Record<string, string> = {\n local: 'device',\n device: 'device',\n fromdevice: 'device',\n camera: 'camera',\n facebook: 'facebook',\n fb: 'facebook',\n insta: 'facebook',\n instagram: 'facebook',\n gdrive: 'google-drive',\n googledrive: 'google-drive',\n google: 'google-drive',\n googledisk: 'google-drive',\n 'google-drive': 'google-drive',\n};\n\nfunction ensureCustomElement() {\n if (\n typeof globalThis === 'undefined' ||\n typeof globalThis.customElements === 'undefined'\n ) {\n return;\n }\n if (!globalThis.customElements.get(AutorenderUploaderElement.tagName)) {\n globalThis.customElements.define(\n AutorenderUploaderElement.tagName,\n AutorenderUploaderElement\n );\n }\n}\n\nfunction resolveTarget(target: string | HTMLElement): HTMLElement {\n if (typeof target === 'string') {\n const element = document.querySelector<HTMLElement>(target);\n if (!element) {\n throw new Error(`Target element \"${target}\" not found`);\n }\n return element;\n }\n return target;\n}\n\nfunction resolveContainer(container?: string | HTMLElement): HTMLElement | null {\n if (!container) return null;\n if (typeof container === 'string') {\n const element = document.querySelector<HTMLElement>(container);\n if (!element) {\n throw new Error(`Container element \"${container}\" not found`);\n }\n return element;\n }\n return container;\n}\n\nfunction resolveThemePreset(theme?: ThemeName): ThemeOptions {\n const base = {\n borderRadius: DEFAULT_THEME.borderRadius,\n dropzoneBackground: DEFAULT_THEME.dropzoneBackground,\n dropzoneBorder: DEFAULT_THEME.dropzoneBorder,\n };\n\n switch (theme) {\n case 'dark':\n return {\n appearance: 'dark',\n ...base,\n };\n case 'system':\n return {\n appearance: 'system',\n ...base,\n };\n default:\n return {\n appearance: 'light',\n ...base,\n };\n }\n}\n\nfunction resolveSourcesConfig(input?: string | string[]): UploadSourceOption[] {\n if (input === undefined || input === null) {\n return [];\n }\n\n const provided = Array.isArray(input)\n ? input\n : input\n .split(',')\n .map(entry => entry.trim())\n .filter(Boolean);\n\n if (provided.length === 0) {\n return [];\n }\n\n const resolved: UploadSourceOption[] = [];\n const seen = new Set<string>();\n\n for (const entry of provided) {\n const normalized = entry.toLowerCase().replace(/[\\s_-]+/g, '');\n const mappedId = SOURCE_ALIAS_MAP[normalized] ?? normalized;\n if (seen.has(mappedId)) continue;\n const match = DEFAULT_SOURCES.find(option => option.id === mappedId);\n if (match) {\n resolved.push(match);\n seen.add(mappedId);\n }\n }\n\n return resolved;\n}\n\nfunction normalizeOptions(\n options: Partial<CreateUploaderOptions>,\n applyDefaults = false\n): Partial<ControllerOptions> {\n const {\n type,\n theme,\n sources,\n classNames,\n labels,\n fileLayout,\n showGridFileName,\n apiKey: _apiKey,\n target: _target,\n ...rest\n } = options;\n\n const normalized: any = { ...rest };\n\n if (type !== undefined) {\n normalized.type = type === 'button' ? 'button' : 'inline';\n } else if (applyDefaults) {\n normalized.type = 'inline';\n }\n\n if (theme !== undefined) {\n normalized.theme = resolveThemePreset(theme);\n } else if (applyDefaults) {\n normalized.theme = resolveThemePreset('light');\n }\n\n if (options.palette !== undefined) {\n normalized.palette = options.palette;\n } else if (applyDefaults) {\n normalized.palette = 'at-blue';\n }\n\n if (sources !== undefined) {\n normalized.sources = resolveSourcesConfig(sources);\n } else if ('sources' in options) {\n // Explicitly undefined - means no sources (all disabled)\n normalized.sources = [];\n } else if (applyDefaults) {\n normalized.sources = [];\n }\n\n if (classNames !== undefined) {\n normalized.classNames = classNames;\n }\n\n if (labels !== undefined) {\n normalized.labels = labels;\n }\n\n if (fileLayout !== undefined) {\n normalized.fileLayout = fileLayout;\n } else if (applyDefaults) {\n normalized.fileLayout = 'list';\n }\n\n if (showGridFileName !== undefined) {\n normalized.showGridFileName = showGridFileName;\n } else if (applyDefaults) {\n normalized.showGridFileName = true;\n }\n\n if (options.assetDeliveryBaseUrl !== undefined) {\n normalized.assetDeliveryBaseUrl = options.assetDeliveryBaseUrl;\n } else if (applyDefaults) {\n normalized.assetDeliveryBaseUrl = DEFAULT_ASSET_DELIVERY_BASE_URL;\n }\n\n return normalized;\n}\n\nexport function createUploader(options: CreateUploaderOptions): UploaderInstance {\n // If container is provided, use it as the target so the entire widget renders inside it\n const container = resolveContainer(options.container);\n const defaultTarget = resolveTarget(options.target);\n const resolvedTarget = container || defaultTarget;\n \n ensureCustomElement();\n\n const widget = document.createElement(\n AutorenderUploaderElement.tagName\n ) as AutorenderUploaderElement;\n\n // Clear target and mount widget\n resolvedTarget.innerHTML = '';\n resolvedTarget.appendChild(widget);\n\n const client = new AutorenderApiClient({\n apiKey: options.apiKey,\n environment: options.environment,\n });\n\n const controllerOptions = normalizeOptions(options, true) as ControllerOptions;\n \n // Only set container in options if it's different from target (for portal logic)\n // If container is the same as target, we don't need portal\n if (container && container !== resolvedTarget) {\n controllerOptions.container = container;\n } else {\n // Clear container option if it's the same as target\n controllerOptions.container = undefined;\n }\n\n const controller = new UploaderController(\n client,\n widget,\n controllerOptions\n );\n\n widget.setController(controller, controllerOptions);\n\n return {\n openFileDialog: () => widget.openFileDialog(),\n startUpload: () => controller.uploadAll(),\n reset: () => controller.reset(),\n destroy: () => {\n controller.cancel();\n controller.reset();\n widget.remove();\n },\n updateOptions: (partialOptions: Partial<CreateUploaderOptions>) => {\n const normalized = normalizeOptions(partialOptions, false);\n controller.setOptions(normalized);\n widget.updateOptions(normalized);\n },\n getState: () => controller.getState(),\n };\n}\n\nexport * from './types';\nexport function registerAutorenderUploaderElement() {\n ensureCustomElement();\n}\n\n// ViewTag SDK exports\nexport { createAR } from './viewtag/create-ar';\nexport { detectBestFormat, getBestFormatSync, resetFormatCache } from './viewtag/format-detection';\nexport type {\n CreateARConfig,\n ARInstance,\n TransformOptions,\n ResponsiveOptions,\n ResponsiveAttributes,\n LayerOptions,\n LayerEnhancementOptions\n} from './viewtag/types';\n\n","import type { IconSet, LabelSet, ThemeOptions, UploadSourceOption } from '../types';\n\nexport type Environment = 'prod' | 'dev';\n\nexport function getBaseUrl(environment: Environment = 'prod'): string {\n switch (environment) {\n case 'dev':\n return 'https://upload-dev.autorender.io/api/v1';\n case 'prod':\n default:\n return 'https://upload.autorender.io/api/v1';\n }\n}\n\nexport const DEFAULT_BASE_URL = getBaseUrl('prod');\n\nexport const DEFAULT_ASSET_DELIVERY_BASE_URL = 'https://dev.autorender.io';\n\n\nexport const DEFAULT_LABELS: Required<LabelSet> = {\n title: 'Upload files',\n description: 'Drag & drop files or click to browse.',\n selectButton: 'Upload files',\n selectFolderButton: 'Upload folder',\n uploadButton: 'Upload',\n uploading: 'Uploading...',\n uploadComplete: 'All files uploaded successfully.',\n uploadFailed: 'Unable to upload files. Please try again.',\n retry: 'Retry',\n remove: 'Remove',\n addMore: 'Add more',\n done: 'Done',\n clear: 'Clear',\n cancel: 'Cancel',\n dropzoneTitle: 'Drop files here',\n duplicateFileExists: 'The following file already exists in this folder:',\n duplicateFilesExist: 'The following files already exist in this folder:',\n duplicateFileError: 'File already exists in this folder.',\n invalidApiKey: 'Invalid API key. Please verify your credentials and try again.',\n};\n\nexport const DEFAULT_ICONS: Required<IconSet> = {\n upload: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M12 16a1 1 0 0 1-1-1V7.41l-2.3 2.3a1 1 0 1 1-1.4-1.42l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.42L13 7.41V15a1 1 0 0 1-1 1Z\" />\n <path d=\"M5 20a3 3 0 0 1-3-3v-1a1 1 0 0 1 2 0v1a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-1a1 1 0 1 1 2 0v1a3 3 0 0 1-3 3Z\" />\n </svg>\n `,\n success: `\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M9.5 17a1 1 0 0 1-.7-.29l-3.5-3.5a1 1 0 1 1 1.4-1.42l2.8 2.79 7.1-7.09a1 1 0 0 1 1.4 1.42l-7.8 7.79a1 1 0 0 1-.7.3Z\" fill=\"currentColor\" />\n </svg>\n `,\n error: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" >\n <path d=\"m12 13.41 3.29 3.3a1 1 0 0 0 1.42-1.42L13.41 12l3.3-3.29a1 1 0 0 0-1.42-1.42L12 10.59l-3.29-3.3a1 1 0 1 0-1.42 1.42L10.59 12l-3.3 3.29a1 1 0 0 0 1.42 1.42L12 13.41Z\" />\n </svg>\n `,\n remove: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M9 5.25C9 4.55964 9.55964 4 10.25 4H13.75C14.4404 4 15 4.55964 15 5.25V7H9V5.25Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n />\n <path\n d=\"M5 7H19\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <rect\n x=\"6.5\"\n y=\"7\"\n width=\"11\"\n height=\"12.5\"\n rx=\"2\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n />\n <path\n d=\"M10 11.5V16\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M14 11.5V16\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n `,\n close: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M13.41 12 18 7.41 16.59 6 12 10.59 7.41 6 6 7.41 10.59 12 6 16.59 7.41 18 12 13.41 16.59 18 18 16.59 13.41 12Z\" />\n </svg>\n `,\n};\n\nexport const DEFAULT_SOURCES: UploadSourceOption[] = [\n {\n id: 'device',\n label: 'From device',\n kind: 'device',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M9.5 4h5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n `,\n },\n {\n id: 'camera',\n label: 'Camera',\n kind: 'camera',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 7h2l1-2h8l1 2h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\" />\n <circle cx=\"12\" cy=\"13\" r=\"3.25\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n `,\n },\n {\n id: 'facebook',\n label: 'Facebook',\n kind: 'facebook',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M13 8h2V6h-2a3 3 0 0 0-3 3v1H8v2h2v6h2v-6h2v-2h-2V9a1 1 0 0 1 1-1Z\" fill=\"currentColor\" />\n </svg>\n `,\n },\n {\n id: 'google-drive',\n label: 'Google Drive',\n kind: 'google-drive',\n icon: `\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6.5 18.5h11l3-5-5-8h-6l-5 8 2 3\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\" />\n <path d=\"M8 13.5h8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n `,\n },\n];\n\nexport const DEFAULT_THEME: Required<\n Pick<ThemeOptions, 'appearance' | 'borderRadius' | 'dropzoneBackground' | 'dropzoneBorder'>\n> = {\n appearance: 'light',\n borderRadius: 8,\n dropzoneBackground: 'var(--ar-color-muted)',\n dropzoneBorder: 'var(--ar-color-border)',\n};\n\n","import { getBaseUrl } from '../constants/defaults';\nimport type { AppRunnerResponse, UploadSettings, Environment } from '../types';\n\ninterface UploadFileParams {\n file: File;\n folderPath?: string;\n relativePath?: string;\n settings?: UploadSettings;\n}\n\ninterface NewUploadResponse {\n id: string;\n workspace_id: string;\n name: string;\n path: string;\n url: string;\n width?: number;\n height?: number;\n size: number;\n format?: string;\n mime_type?: string;\n hash?: string;\n tags?: string[];\n metadata?: Record<string, unknown> | null;\n custom_id?: string | null;\n is_private?: boolean;\n is_duplicate?: boolean;\n created_at: string;\n upload_source?: string;\n folder_no?: string | null;\n file_no?: string;\n}\n\nexport class AutorenderApiClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(opts: { apiKey: string; baseUrl?: string; environment?: Environment }) {\n if (!opts.apiKey) {\n throw new Error('apiKey is required');\n }\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl || getBaseUrl(opts.environment || 'prod')).replace(/\\/+$/, '');\n }\n\n uploadFile(\n params: UploadFileParams,\n onProgress?: (progress: number) => void,\n signal?: AbortSignal\n ): Promise<AppRunnerResponse> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('Upload aborted', 'AbortError'));\n return;\n }\n\n const xhr = new XMLHttpRequest();\n\n if (signal) {\n signal.addEventListener('abort', () => {\n xhr.abort();\n reject(new DOMException('Upload aborted', 'AbortError'));\n });\n }\n\n let lastProgress = 0;\n xhr.upload.onprogress = event => {\n if (event.lengthComputable && onProgress) {\n const progress = Math.round((event.loaded / event.total) * 100);\n lastProgress = progress;\n onProgress(progress);\n } else if (onProgress && event.loaded > 0) {\n const estimatedProgress = Math.min(\n 95,\n Math.round((event.loaded / (event.loaded + 1000000)) * 100)\n );\n if (estimatedProgress > lastProgress) {\n lastProgress = estimatedProgress;\n onProgress(estimatedProgress);\n }\n }\n };\n\n xhr.onerror = () => {\n reject(new Error(`Upload failed: ${xhr.statusText}`));\n };\n\n xhr.onload = () => {\n try {\n if (xhr.status < 200 || xhr.status >= 300) {\n const errorText = xhr.responseText || xhr.statusText;\n reject(new Error(`Upload failed: ${errorText}`));\n return;\n }\n const newResponse = JSON.parse(xhr.responseText) as NewUploadResponse;\n\n const response: AppRunnerResponse = {\n success: true,\n file_no: newResponse.file_no || newResponse.id,\n name: newResponse.name,\n url: newResponse.url,\n file_size: newResponse.size,\n format: newResponse.format,\n width: newResponse.width,\n height: newResponse.height,\n created_at: newResponse.created_at,\n path: newResponse.path,\n workspace_no: newResponse.workspace_id,\n isDuplicate: newResponse.is_duplicate || false,\n };\n\n resolve(response);\n } catch (error) {\n reject(new Error('Failed to parse response'));\n }\n };\n\n const endpoint = `${this.baseUrl}/uploads`;\n const formData = new FormData();\n formData.append('file', params.file);\n formData.append('file_name', params.file.name);\n if (params.folderPath) {\n formData.append('folder', params.folderPath);\n }\n if (params.settings?.tags?.length) {\n formData.append('tags', params.settings.tags.join(','));\n }\n if (params.settings?.pretransformations) {\n formData.append('transform', params.settings.pretransformations);\n }\n if (params.settings?.custom_id) {\n formData.append('custom_id', params.settings.custom_id);\n }\n\n xhr.open('POST', endpoint);\n xhr.setRequestHeader('Authorization', `Bearer ${this.apiKey}`);\n xhr.setRequestHeader('accept', 'application/json');\n xhr.send(formData);\n });\n }\n}\n\nexport {}\n\n","export function generateId(): string {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID();\n }\n\n return 'id-' + Math.random().toString(36).slice(2, 11);\n}\n\nexport function chunkArray<T>(items: T[], chunkSize: number): T[][] {\n if (chunkSize <= 0) {\n return [items];\n }\n\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += chunkSize) {\n chunks.push(items.slice(i, i + chunkSize));\n }\n return chunks;\n}\n\nexport function clamp(value: number, min = 0, max = 1) {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function formatBytes(bytes: number) {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const num = bytes / Math.pow(k, i);\n return `${num.toFixed(num > 10 ? 0 : 1)} ${sizes[i]}`;\n}\n\nexport function createElement<T extends keyof HTMLElementTagNameMap>(\n tag: T,\n className?: string,\n textContent?: string\n): HTMLElementTagNameMap[T] {\n const element = document.createElement(tag);\n if (className) element.className = className;\n if (textContent) element.textContent = textContent;\n return element;\n}\n\nexport function resolveIcon(renderer: string | HTMLElement | (() => string | HTMLElement)) {\n if (typeof renderer === 'function') {\n return resolveIcon(renderer());\n }\n if (typeof renderer === 'string') {\n const template = document.createElement('template');\n template.innerHTML = renderer.trim();\n return template.content.firstElementChild as HTMLElement | null;\n }\n return renderer ? (renderer.cloneNode(true) as HTMLElement) : null;\n}\n\nexport function toCssVars(theme: {\n appearance?: 'light' | 'dark' | 'system';\n accentColor?: string;\n borderRadius?: number;\n fontFamily?: string;\n dropzoneBackground?: string;\n dropzoneBorder?: string;\n}) {\n const variables: Record<string, string> = {};\n if (theme.accentColor) {\n variables['--ar-accent'] = theme.accentColor;\n }\n if (theme.borderRadius !== undefined) {\n variables['--ar-radius'] = `${theme.borderRadius}px`;\n }\n if (theme.fontFamily) {\n variables['--ar-font-family'] = theme.fontFamily;\n }\n if (theme.dropzoneBackground) {\n variables['--ar-dropzone-bg'] = theme.dropzoneBackground;\n }\n if (theme.dropzoneBorder) {\n variables['--ar-dropzone-border'] = theme.dropzoneBorder;\n }\n return variables;\n}\n\nexport function applyCssVariables(\n element: HTMLElement,\n variables: Record<string, string>\n) {\n Object.entries(variables).forEach(([key, value]) => {\n element.style.setProperty(key, value);\n });\n}\n\nexport function getRelativeFolderPath(\n basePath: string | undefined,\n relativePath: string | undefined\n) {\n if (!relativePath) return undefined;\n\n const parts = relativePath\n .split('/')\n .map(segment => segment.trim())\n .filter(segment => segment && segment !== '.');\n\n if (parts.length <= 1) {\n return undefined;\n }\n\n const folderSegments = parts.slice(0, -1);\n\n if (basePath) {\n const baseSegments = basePath\n .split('/')\n .map(segment => segment.trim())\n .filter(segment => segment && segment !== '.');\n\n let offset = 0;\n while (\n offset < baseSegments.length &&\n offset < folderSegments.length &&\n folderSegments[offset] === baseSegments[offset]\n ) {\n offset += 1;\n }\n\n return offset < folderSegments.length\n ? folderSegments.slice(offset).join('/')\n : undefined;\n }\n\n return folderSegments.length ? folderSegments.join('/') : undefined;\n}\n\nexport function calculateBatchProgress(items: { progress: number }[]) {\n if (items.length === 0) return 0;\n const total = items.reduce((acc, item) => acc + item.progress, 0);\n return Math.round(total / items.length);\n}\n\nconst S3_URL_PATTERN = /^s3:\\/\\/([^/]+)\\/(.+)$/i;\n\nexport function sanitizeBaseUrl(baseUrl?: string): string | undefined {\n if (!baseUrl) return undefined;\n const trimmed = baseUrl.trim();\n if (!trimmed) return undefined;\n return trimmed.replace(/\\/+$/, '');\n}\n\nexport function extractWorkspaceFromUrl(url?: string): string | undefined {\n if (!url) return undefined;\n const s3Match = S3_URL_PATTERN.exec(url);\n if (s3Match) {\n return s3Match[1];\n }\n try {\n const parsed = new URL(url);\n const firstSegment = parsed.pathname.replace(/^\\/+/, '').split('/')[0];\n return firstSegment || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function extractPathFromUrl(url?: string): string | undefined {\n if (!url) return undefined;\n const s3Match = S3_URL_PATTERN.exec(url);\n if (s3Match) {\n return s3Match[2];\n }\n try {\n const parsed = new URL(url);\n const [, ...rest] = parsed.pathname.replace(/^\\/+/, '').split('/');\n return rest.length ? rest.join('/') : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function buildAssetDeliveryUrl(\n baseUrl: string | undefined,\n workspace?: string,\n path?: string,\n fallback?: string\n): string | undefined {\n const sanitizedBase = sanitizeBaseUrl(baseUrl);\n if (!sanitizedBase || !workspace || !path) {\n return fallback;\n }\n\n const normalizedPath = path\n .split('/')\n .filter(Boolean)\n .map(segment => encodeURIComponent(segment))\n .join('/');\n\n return `${sanitizedBase}/${workspace}/${normalizedPath}`.replace(/([^:]\\/)\\/+/g, '$1');\n}\n\n","import { AutorenderApiClient } from '../client/api-client';\nimport { DEFAULT_ASSET_DELIVERY_BASE_URL } from '../constants/defaults';\nimport type {\n CreateUploaderOptions,\n UploadItem,\n UploadedFileResponse,\n ThemeOptions,\n UploadSourceOption,\n AppRunnerResponse,\n UploadSuccessFile,\n} from '../types';\nimport {\n applyCssVariables,\n buildAssetDeliveryUrl,\n calculateBatchProgress,\n extractPathFromUrl,\n extractWorkspaceFromUrl,\n generateId,\n getRelativeFolderPath,\n sanitizeBaseUrl,\n toCssVars,\n} from '../utils/helpers';\nimport { fileTypeFromBlob } from 'file-type';\n\nconst DEFAULT_PARALLEL_UPLOADS = 4;\nconst MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024; // 100MB\n\ninterface FileSelection {\n file: File;\n relativePath?: string;\n}\n\nexport interface ControllerOptions\n extends Omit<CreateUploaderOptions, 'target' | 'theme' | 'sources'> {\n theme?: ThemeOptions;\n sources?: UploadSourceOption[];\n}\n\nexport interface ControllerState {\n items: UploadItem[];\n isUploading: boolean;\n progress: number;\n duplicates: string[];\n}\n\ntype ControllerEvents =\n | 'statechange'\n | 'progress'\n | 'fileprogress'\n | 'error'\n | 'complete'\n | 'filesadded';\n\nexport class UploaderController extends EventTarget {\n private options: ControllerOptions;\n private readonly client: AutorenderApiClient;\n private items: UploadItem[] = [];\n private abortController: AbortController | null = null;\n private isUploading = false;\n private targetElement: HTMLElement;\n private duplicateConflicts = new Set<string>();\n\n private isAbortError(error: unknown): boolean {\n if (!error) return false;\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof Error && error.name === 'AbortError') return true;\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n return typeof message === 'string' && message.toLowerCase().includes('abort');\n }\n\n constructor(\n client: AutorenderApiClient,\n target: HTMLElement,\n options: ControllerOptions\n ) {\n super();\n this.client = client;\n this.targetElement = target;\n this.options = options;\n this.applyTheme();\n }\n\n setOptions(options: Partial<ControllerOptions>) {\n this.options = {\n ...this.options,\n ...options,\n };\n this.applyTheme();\n this.dispatch('statechange');\n }\n\n getOptions(): ControllerOptions {\n return this.options;\n }\n\n getState(): ControllerState {\n return {\n items: this.items,\n isUploading: this.isUploading,\n progress: calculateBatchProgress(this.items),\n duplicates: Array.from(this.duplicateConflicts),\n };\n }\n\n async addFiles(files: FileSelection[]) {\n const existingKeys = new Map<string, UploadItem>();\n const basePathKey = this.normalizePath(this.options.folderPath) ?? '';\n const buildKey = (file: File, folderPath?: string, relativePath?: string) =>\n `${basePathKey}::${folderPath ?? ''}::${relativePath ?? ''}::${file.name}::${file.size}`;\n\n this.items.forEach(item => {\n existingKeys.set(buildKey(item.file, item.folderPath, item.relativePath), item);\n });\n\n // Detect mimeType for files that don't have it\n const filesWithMimeType = await Promise.all(\n files.map(async ({ file, relativePath }) => {\n let mimeType = file.type;\n \n // If file doesn't have mimeType, detect it using file-type\n if (!mimeType || mimeType === 'application/octet-stream' || mimeType === '') {\n try {\n const detected = await fileTypeFromBlob(file);\n if (detected?.mime) {\n mimeType = detected.mime;\n // Update the File object's type property if possible\n Object.defineProperty(file, 'type', {\n value: mimeType,\n writable: false,\n configurable: true,\n });\n } else {\n // Fallback to application/octet-stream if detection fails\n mimeType = 'application/octet-stream';\n }\n } catch (error) {\n // If detection fails, use fallback\n mimeType = 'application/octet-stream';\n }\n }\n\n return { file, relativePath, mimeType };\n })\n );\n\n const newItems = filesWithMimeType.map(({ file, relativePath, mimeType }) => {\n const folderPath = getRelativeFolderPath(\n this.options.folderPath,\n relativePath\n ) ?? '';\n\n // Only create preview URL for images\n const previewUrl = mimeType.startsWith('image/')\n ? URL.createObjectURL(file)\n : undefined;\n\n // Check file size limit (100MB)\n const fileSizeMB = (file.size / (1024 * 1024)).toFixed(2);\n const info = file.size > MAX_FILE_SIZE_BYTES\n ? `File size (${fileSizeMB}MB) exceeds the maximum limit of 100MB`\n : undefined;\n\n const baseItem: UploadItem = {\n id: generateId(),\n file,\n relativePath,\n folderPath,\n status: 'pending' as const,\n progress: 0,\n previewUrl,\n info,\n };\n\n const key = buildKey(file, folderPath, relativePath);\n if (existingKeys.has(key)) {\n baseItem.status = 'completed';\n baseItem.progress = 100;\n baseItem.error = undefined;\n existingKeys.set(key, baseItem);\n return baseItem;\n }\n\n existingKeys.set(key, baseItem);\n return baseItem;\n });\n\n this.items = [...this.items, ...newItems];\n this.dispatch('filesadded', { items: newItems });\n\n const duplicates = newItems.filter(item => item.status === 'completed');\n if (duplicates.length) {\n this.markDuplicatesCompleted(duplicates);\n }\n\n this.dispatch('statechange');\n }\n\n removeFile(id: string) {\n const item = this.items.find(entry => entry.id === id);\n if (item?.previewUrl) {\n URL.revokeObjectURL(item.previewUrl);\n }\n this.items = this.items.filter(item => item.id !== id);\n if (item) {\n this.duplicateConflicts.delete(item.file.name);\n }\n this.dispatch('statechange');\n }\n\n reset() {\n this.abortController?.abort();\n this.abortController = null;\n this.isUploading = false;\n this.cleanupPreviews();\n this.items = [];\n this.duplicateConflicts.clear();\n this.dispatch('statechange');\n }\n\n async uploadAll() {\n if (this.isUploading) return;\n if (this.items.length === 0) return;\n\n this.duplicateConflicts.clear();\n this.isUploading = true;\n this.abortController = new AbortController();\n this.dispatch('statechange');\n\n try {\n await this.processUploads();\n const files = this.buildSuccessFiles();\n this.dispatch('complete', {\n items: this.items,\n files,\n });\n } catch (error) {\n if (this.isAbortError(error)) {\n this.dispatch('error', error);\n return;\n }\n this.annotateItemsWithError(error);\n this.dispatch('error', error);\n throw error;\n } finally {\n this.isUploading = false;\n this.abortController = null;\n this.dispatch('statechange');\n }\n }\n\n cancel() {\n this.abortController?.abort();\n this.abortController = null;\n }\n\n private isDuplicateError(error: unknown) {\n if (!error) return false;\n if (typeof error === 'object' && error !== null) {\n const status = (error as any).status ?? (error as any).statusCode;\n if (status === 409) {\n return true;\n }\n const code = (error as any).code;\n if (typeof code === 'string' && code.toLowerCase() === 'conflict') {\n return true;\n }\n }\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n const normalized = message.toLowerCase();\n return (\n normalized.includes('duplicate') ||\n normalized.includes('already exists') ||\n normalized.includes('status 409') ||\n normalized.includes('conflict 409') ||\n normalized.includes('409')\n );\n }\n\n private markDuplicatesCompleted(\n items: UploadItem[],\n duplicateNames?: string[],\n options: { annotateError?: boolean } = {}\n ): UploadItem[] {\n const normalizedNames =\n duplicateNames\n ?.map(name => name.trim().toLowerCase())\n .filter(Boolean) ?? [];\n const targetSet =\n normalizedNames.length > 0 ? new Set(normalizedNames) : null;\n\n const targetItems =\n targetSet !== null\n ? items.filter(item =>\n targetSet.has(item.file.name.trim().toLowerCase())\n )\n : items;\n\n const duplicates =\n targetSet !== null && targetItems.length === 0 ? items : targetItems;\n\n const { annotateError = true } = options;\n\n duplicates.forEach(item => {\n if (!item) return;\n\n const name = item.file.name;\n if (!this.duplicateConflicts.has(name)) {\n this.duplicateConflicts.add(name);\n }\n\n item.status = 'completed';\n item.progress = 100;\n item.error = annotateError ? 'duplicate' : undefined;\n this.dispatch('fileprogress', { item });\n });\n\n if (duplicates.length > 0) {\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n\n this.dispatch('statechange');\n }\n\n return duplicates;\n }\n\n private isAuthError(error: unknown): boolean {\n if (!error || typeof error !== 'object') {\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n return (\n typeof message === 'string' &&\n message.toLowerCase().includes('unauthorized')\n );\n }\n\n const status = (error as any).status;\n if (typeof status === 'number' && (status === 401 || status === 403)) {\n return true;\n }\n\n const message =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : '';\n const normalized = String(message).toLowerCase();\n return (\n normalized.includes('unauthorized') ||\n normalized.includes('forbidden') ||\n normalized.includes('invalid api key')\n );\n }\n\n private annotateItemsWithError(error: unknown) {\n const isAuth = this.isAuthError(error);\n const fallbackMessage =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : 'Upload failed';\n\n let mutated = false;\n\n this.items.forEach(item => {\n if (item.status === 'completed') return;\n mutated = true;\n item.status = 'error';\n item.progress = item.progress ?? 0;\n item.error = isAuth ? 'invalid-api-key' : fallbackMessage;\n this.dispatch('fileprogress', { item });\n });\n\n if (mutated) {\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n this.dispatch('statechange');\n }\n }\n\n private async processUploads() {\n const allItems = this.items.filter(item => item.status !== 'completed');\n\n if (allItems.length === 0) {\n return;\n }\n\n const parallel = Math.max(1, this.options.parallelUploads ?? DEFAULT_PARALLEL_UPLOADS);\n const uploadSettings = this.options.uploadSettings;\n\n // Process all items in parallel with concurrency limit\n const tasks = allItems.map(item => async () => {\n if (this.abortController?.signal.aborted) {\n throw new Error('Upload cancelled');\n }\n\n try {\n await this.uploadSingleFile(item, uploadSettings);\n } catch (error) {\n if (this.isAbortError(error)) {\n return; // Don't mark as error for aborted uploads\n }\n if (this.isDuplicateError(error)) {\n this.markDuplicatesCompleted([item], [item.file.name], {\n annotateError: true,\n });\n } else {\n const err = error instanceof Error ? error : new Error(String(error));\n item.status = 'error';\n item.error = err.message;\n this.dispatch('fileprogress', { item });\n this.dispatch('statechange');\n }\n }\n });\n\n await this.runWithConcurrency(tasks, parallel);\n }\n\n private async uploadSingleFile(\n item: UploadItem,\n uploadSettings?: CreateUploaderOptions['uploadSettings']\n ) {\n // Check file size limit before uploading\n if (item.file.size > MAX_FILE_SIZE_BYTES) {\n // Don't upload, but keep status as pending and show info message\n const fileSizeMB = (item.file.size / (1024 * 1024)).toFixed(2);\n item.info = `File size (${fileSizeMB}MB) exceeds the maximum limit of 100MB`;\n this.dispatch('fileprogress', { item });\n this.dispatch('statechange');\n return; // Skip upload for files that are too large\n }\n\n item.status = 'uploading';\n item.progress = 0;\n this.dispatch('statechange');\n\n const folderPath = item.folderPath\n ? this.combinePaths(this.options.folderPath, item.folderPath)\n : this.normalizePath(this.options.folderPath);\n\n const appRunnerResponse: AppRunnerResponse = await this.client.uploadFile(\n {\n file: item.file,\n folderPath: folderPath ?? undefined,\n relativePath: item.relativePath,\n settings: uploadSettings\n ? {\n pretransformations: uploadSettings.pretransformations,\n tags: uploadSettings.tags,\n is_unique_suffix_name: uploadSettings.is_unique_suffix_name ?? false,\n custom_id: uploadSettings.custom_id,\n }\n : undefined,\n },\n progress => {\n item.progress = progress;\n this.dispatch('fileprogress', { item });\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n },\n this.abortController?.signal\n );\n\n if (!appRunnerResponse.success) {\n const error = new Error(appRunnerResponse.message ?? 'Upload failed');\n (error as any).code = appRunnerResponse.errorCode;\n throw error;\n }\n\n item.status = 'completed';\n item.progress = 100;\n item.response = {\n file_no: appRunnerResponse.file_no,\n name: appRunnerResponse.name,\n url: appRunnerResponse.url,\n file_size: appRunnerResponse.file_size,\n folder_no: undefined,\n path: appRunnerResponse.path,\n width: appRunnerResponse.width,\n height: appRunnerResponse.height,\n format: appRunnerResponse.format,\n workspace_no: appRunnerResponse.workspace_no,\n };\n item.uploadedAt = new Date(appRunnerResponse.created_at);\n\n if (appRunnerResponse.isDuplicate) {\n item.error = 'duplicate';\n }\n\n this.dispatch('fileprogress', { item });\n this.dispatch('progress', {\n progress: calculateBatchProgress(this.items),\n items: this.items,\n });\n this.dispatch('statechange');\n }\n\n\n\n private applyTheme() {\n if (!this.options.theme) return;\n const vars = toCssVars(this.options.theme);\n applyCssVariables(this.targetElement, vars);\n if (this.options.theme.appearance && this.options.theme.appearance !== 'system') {\n this.targetElement.dataset.theme = this.options.theme.appearance;\n } else {\n delete this.targetElement.dataset.theme;\n }\n }\n\n private dispatch(event: ControllerEvents, detail?: CustomEventInit['detail']) {\n const customEvent = new CustomEvent(event, { detail });\n this.dispatchEvent(customEvent);\n\n switch (event) {\n case 'progress':\n this.options.onProgress?.(\n (detail as any)?.progress ?? calculateBatchProgress(this.items),\n this.items\n );\n break;\n case 'fileprogress':\n this.options.onFileProgress?.((detail as any).item);\n break;\n case 'error':\n this.options.onError?.(\n detail instanceof Error ? detail : new Error(String(detail))\n );\n break;\n case 'complete':\n this.options.onSuccess?.((detail as any)?.files ?? []);\n break;\n default:\n break;\n }\n }\n\n private resolveAssetDeliveryBaseUrl() {\n return (\n sanitizeBaseUrl(this.options.assetDeliveryBaseUrl) ??\n DEFAULT_ASSET_DELIVERY_BASE_URL\n );\n }\n\n private buildSuccessFiles(): UploadSuccessFile[] {\n const baseUrl = this.resolveAssetDeliveryBaseUrl();\n\n return this.items\n .filter(item => item.status === 'completed' && item.response)\n .map(item => {\n const response = item.response as UploadedFileResponse;\n const workspace =\n response.workspace_no ?? extractWorkspaceFromUrl(response.url);\n const assetPath = response.path ?? extractPathFromUrl(response.url);\n const resolvedUrl =\n buildAssetDeliveryUrl(baseUrl, workspace, assetPath, response.url) ??\n response.url;\n\n return {\n id: item.id,\n previewUrl: item.previewUrl,\n file_no: response.file_no,\n name: response.name,\n url: resolvedUrl,\n input_file_size: item.file?.size ?? response.file_size ?? 0,\n output_file_size: response.file_size ?? 0,\n path: response.path ?? assetPath,\n width: response.width,\n height: response.height,\n format: response.format,\n workspace_no: workspace,\n uploadedAt: item.uploadedAt?.toISOString(),\n };\n });\n }\n\n private async runWithConcurrency(tasks: Array<() => Promise<void>>, limit: number) {\n const executing = new Set<Promise<void>>();\n\n for (const task of tasks) {\n if (this.abortController?.signal.aborted) {\n throw new Error('Upload cancelled');\n }\n\n const promise = task().finally(() => {\n executing.delete(promise);\n });\n executing.add(promise);\n\n if (executing.size >= limit) {\n await Promise.race(executing);\n }\n }\n\n await Promise.all(executing);\n }\n\n private cleanupPreviews() {\n this.items.forEach(item => {\n if (item.previewUrl) {\n URL.revokeObjectURL(item.previewUrl);\n item.previewUrl = undefined;\n }\n });\n }\n\n private normalizePath(path?: string): string | undefined {\n if (!path) {\n return undefined;\n }\n\n const normalized = path\n .split('/')\n .map(segment => segment.trim())\n .filter(Boolean)\n .join('/');\n\n return normalized.length > 0 ? normalized : undefined;\n }\n\n private combinePaths(basePath?: string, relativePath?: string): string | undefined {\n const base = this.normalizePath(basePath);\n const relative = this.normalizePath(relativePath);\n\n if (base && relative) {\n return `${base}/${relative}`;\n }\n\n return base || relative || undefined;\n }\n\n}\n\n","export const widgetStyles = /* css */ `\n:host {\n --ar-font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --ar-color-bg: hsl(0 0% 100%);\n --ar-color-bg-muted: hsl(210 40% 96%);\n --ar-color-border: hsl(214 32% 91%);\n --ar-color-text: hsl(222 47% 11%);\n --ar-color-muted-foreground: hsl(215 16% 47%);\n /* let palette or theme set accent */\n --ar-color-accent: unset;\n --ar-color-accent-hover: unset;\n --ar-color-accent-button: unset;\n --ar-radius: 8px;\n display: block;\n}\n\n/* Palette: Blue (default) */\n:host([data-palette='at-blue']),\n:host:not([data-palette]) {\n --ar-color-accent: #e0f2fe;\n --ar-color-accent-hover: #f0f9ff;\n --ar-color-accent-button: #0c55f9;\n}\n\n/* Palette: Purple */\n:host([data-palette='at-purple']) {\n --ar-color-accent: #f3e8ff;\n --ar-color-accent-hover: #faf5ff;\n --ar-color-accent-button: #8a3ffc;\n}\n\n/* Palette: Red */\n:host([data-palette='at-red']) {\n --ar-color-accent: #fee2e2;\n --ar-color-accent-hover: #fef2f2;\n --ar-color-accent-button: #da1e28;\n}\n\n/* Palette: Orange */\n:host([data-palette='at-orange']) {\n --ar-color-accent: #ffedd5;\n --ar-color-accent-hover: #fff7ed;\n --ar-color-accent-button: #ff832b;\n}\n\n/* Palette: Green */\n:host([data-palette='at-green']) {\n --ar-color-accent: #dcfce7;\n --ar-color-accent-hover: #f0fdf4;\n --ar-color-accent-button: #24a148;\n}\n\n/* Palette: Turquoise */\n:host([data-palette='at-turquoise']) {\n --ar-color-accent: #ccfbf1;\n --ar-color-accent-hover: #f0fdfa;\n --ar-color-accent-button: #0072c3;\n}\n\n/* Palette: Gray */\n:host([data-palette='at-gray']) {\n --ar-color-accent: #f3f4f6;\n --ar-color-accent-hover: #f9fafb;\n --ar-color-accent-button: #525252;\n}\n\n:host([data-trigger='inline']) .ar-uploader-root,\n:host([data-trigger='inline']) .ar-inline-upload,\n:host([data-trigger='inline']) .ar-inline-panel {\n width: 100%;\n min-width: 0;\n}\n\n:host([data-theme='dark']) {\n --ar-color-bg: hsl(222 41% 6%);\n --ar-color-bg-muted: hsl(217 33% 17%);\n --ar-color-border: hsl(217 19% 27%);\n --ar-color-text: hsl(213 31% 91%);\n --ar-color-muted-foreground: hsl(215 20% 65%);\n --ar-color-accent: unset;\n --ar-color-accent-hover: unset;\n}\n\n/* Dark theme palette overrides */\n:host([data-theme='dark'][data-palette='at-blue']),\n:host([data-theme='dark']:not([data-palette])) {\n --ar-color-accent: rgba(120, 169, 255, 0.8);\n --ar-color-accent-hover: rgba(120, 169, 255, 0.2);\n --ar-color-accent-button: #78a9ff;\n}\n\n:host([data-theme='dark'][data-palette='at-purple']) {\n --ar-color-accent: rgba(167, 139, 250, 0.8);\n --ar-color-accent-hover: rgba(167, 139, 250, 0.2);\n --ar-color-accent-button: #a78bfa;\n}\n\n:host([data-theme='dark'][data-palette='at-red']) {\n --ar-color-accent: rgba(255, 131, 137, 0.8);\n --ar-color-accent-hover: rgba(255, 131, 137, 0.2);\n --ar-color-accent-button: #ff8389;\n}\n\n:host([data-theme='dark'][data-palette='at-orange']) {\n --ar-color-accent: rgba(255, 179, 102, 0.8);\n --ar-color-accent-hover: rgba(255, 179, 102, 0.2);\n --ar-color-accent-button: #ffb366;\n}\n\n:host([data-theme='dark'][data-palette='at-green']) {\n --ar-color-accent: rgba(111, 220, 140, 0.8);\n --ar-color-accent-hover: rgba(111, 220, 140, 0.2);\n --ar-color-accent-button: #6fdc8c;\n}\n\n:host([data-theme='dark'][data-palette='at-turquoise']) {\n --ar-color-accent: rgba(130, 207, 255, 0.8);\n --ar-color-accent-hover: rgba(130, 207, 255, 0.2);\n --ar-color-accent-button: #82cfff;\n}\n\n:host([data-theme='dark'][data-palette='at-gray']) {\n --ar-color-accent: rgba(198, 198, 198, 0.8);\n --ar-color-accent-hover: rgba(198, 198, 198, 0.2);\n --ar-color-accent-button: #c6c6c6;\n}\n\n.ar-uploader-root {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n font-family: var(--ar-font-family);\n background-color: var(--ar-color-bg);\n color: var(--ar-color-text);\n border: 1px solid var(--ar-color-border);\n border-radius: var(--ar-radius);\n padding: 0.5rem 1rem 1rem 1rem;\n}\n\n/* Reduce root gap when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-uploader-root:has(.ar-inline-upload--no-sources) {\n gap: 0.75rem;\n}\n\n\n:host([data-theme='dark']) .ar-uploader-root {\n background-color: hsl(222 41% 6%);\n}\n\n.ar-uploader-root[data-trigger='button'] {\n border: none;\n padding: 0;\n box-shadow: none;\n background: transparent;\n}\n\n.ar-header {\n display: none;\n}\n\n.ar-uploader-root.has-items .ar-header {\n display: flex;\n}\n\n.ar-title {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n}\n\n.ar-description {\n margin: 0;\n color: var(--ar-color-muted-foreground);\n font-size: 0.95rem;\n}\n\n\n.ar-subtext {\n margin: 0;\n font-size: 0.8rem;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-button-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.45rem;\n padding: 0.55rem 1.25rem;\n font-weight: 600;\n border-radius: var(--ar-radius);\n border: 1px solid rgba(15, 23, 42, 0.08);\n background: rgba(248, 250, 252, 0.9);\n color: var(--ar-color-text);\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 6px 16px rgba(15, 23, 42, 0.06);\n}\n\n:host([data-theme='dark']) .ar-button-trigger {\n border: 1px solid rgba(148, 163, 184, 0.25);\n background: rgba(30, 41, 59, 0.75);\n color: var(--ar-color-text);\n}\n\n.ar-button-trigger:hover {\n transform: translateY(-1px);\n}\n\n.ar-button-trigger:active {\n transform: translateY(0);\n}\n\n.ar-button-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.ar-button-icon svg {\n width: 1rem;\n height: 1rem;\n fill: currentColor;\n}\n\n.ar-inline-upload {\n display: flex;\n flex-direction: column;\n gap: 1.1rem;\n}\n\n/* Reduce gap when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-inline-upload--no-sources {\n gap: 0.5rem;\n}\n\n.ar-inline-panel {\n display: flex;\n flex-direction: column;\n}\n\n.ar-dropzone {\n position: relative;\n border: 1.5px dashed var(--ar-dropzone-border, var(--ar-color-border));\n border-radius: var(--ar-radius);\n background: var(--ar-dropzone-bg, var(--ar-color-bg));\n padding: 3rem 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n gap: 1rem;\n cursor: pointer;\n transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.2s ease;\n margin: 0.6rem 0rem 1rem 0rem;\n}\n\n/* Reduce bottom margin when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-modal-body--no-sources .ar-dropzone {\n margin-bottom: 0.25rem;\n}\n\n.ar-dropzone:hover {\n background-color: var(--ar-color-accent-hover);\n transform: translateY(-1px);\n}\n\n.ar-dropzone:hover .ar-dropzone-icon {\n background: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragover {\n border-color: var(--ar-color-accent);\n background-color: var(--ar-color-accent-hover);\n}\n\n.ar-dropzone.is-dragover .ar-dropzone-icon {\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragover .ar-description {\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragging {\n border-color: var(--ar-color-accent);\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragging .ar-dropzone-icon {\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone.is-dragging .ar-description {\n color: var(--ar-color-accent);\n}\n\n.ar-dropzone-icon {\n width: 3rem;\n height: 3rem;\n border-radius: 999px;\n background: rgba(148, 163, 184, 0.12);\n color: var(--ar-color-muted-foreground);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n:host([data-theme='dark']) .ar-dropzone-icon {\n color: var(--ar-color-text);\n}\n\n.ar-dropzone svg {\n width: 1.75rem;\n height: 1.75rem;\n fill: currentColor;\n}\n\n.ar-dropzone-actions {\n display: none;\n}\n\n.ar-file-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n margin-bottom: 1rem;\n}\n\n.ar-file-list.is-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 1rem;\n}\n\n.ar-file-item {\n border: none;\n border-radius: var(--ar-radius);\n background: rgba(148, 163, 184, 0.15);\n padding: 0.5rem;\n display: flex;\n flex-direction: column;\n gap: 0.45rem;\n position: relative;\n box-sizing: border-box;\n min-height: 50px;\n overflow: hidden;\n}\n\n.ar-file-item.is-grid {\n height: auto;\n padding: 0px;\n background: none;\n}\n\n:host([data-theme='dark']) .ar-file-item {\n background: hsl(222 41% 10%);\n}\n\n.ar-file-header {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n min-width: 0;\n flex: 1;\n}\n\n.ar-file-header.is-grid {\n flex-direction: column;\n align-items: stretch;\n}\n\n.ar-file-thumb {\n width: 32px;\n height: 32px;\n border-radius: calc(var(--ar-radius) * 0.5);\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.8rem;\n font-weight: 600;\n overflow: hidden;\n position: relative;\n}\n\n.ar-file-thumb-document {\n background: rgba(148, 163, 184, 0.15);\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-file-thumb-document svg {\n width: 20px;\n height: 20px;\n color: currentColor;\n}\n\n.ar-file-thumb.is-grid {\n width: 100%;\n height: 140px;\n border-radius: calc(var(--ar-radius) * 0.75);\n font-size: 1rem;\n}\n\n.ar-file-thumb.is-grid.ar-file-thumb-document svg {\n width: 48px;\n height: 48px;\n}\n\n.ar-file-item.is-completed .ar-file-thumb {\n color: #fff;\n}\n\n.ar-thumb-status {\n position: absolute;\n bottom: -2px;\n right: -2px;\n width: 18px;\n height: 18px;\n border-radius: 999px;\n background: #1e9f6d;\n color: #fff;\n border: 2px solid var(--ar-color-bg);\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 6px rgba(15, 23, 42, 0.25);\n}\n\n.ar-thumb-status svg {\n width: 10px;\n height: 10px;\n color: currentColor;\n}\n\n.ar-thumb-status.is-error {\n background: rgba(225, 29, 72, 0.85);\n}\n\n.ar-file-name {\n font-size: 0.8rem;\n margin: 0;\n color: var(--ar-color-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n min-width: 0;\n}\n\n.ar-file-meta {\n display: block;\n margin-top: 0.25rem;\n font-size: 0.8rem;\n color: var(--ar-color-muted-foreground);\n width: 100%;\n flex-shrink: 0;\n}\n\n.ar-file-info {\n display: block;\n font-size: 0.75rem;\n color: var(--ar-color-muted-foreground);\n font-style: italic;\n padding: 0.25rem 0.5rem;\n background: rgba(148, 163, 184, 0.15);\n border-radius: calc(var(--ar-radius) * 0.5);\n width: 100%;\n box-sizing: border-box;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.ar-file-item.is-grid .ar-file-info {\n font-size: 0.7rem;\n padding: 0.2rem 0.4rem;\n}\n\n.ar-file-item.is-grid .ar-file-meta {\n justify-content: center;\n}\n\n.ar-remove-button {\n margin-left: auto;\n border: none;\n background: transparent;\n color: var(--ar-color-muted-foreground);\n cursor: pointer;\n padding: 0.25rem;\n border-radius: var(--ar-radius);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s ease, color 0.2s ease;\n}\n\n.ar-remove-button.is-grid {\n position: absolute;\n top: 0.6rem;\n right: 0.6rem;\n background: rgba(255, 255, 255, 0.95);\n color: var(--ar-color-text);\n padding: 0.35rem;\n border-radius: var(--ar-radius);\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease, background 0.2s ease, color 0.2s ease;\n}\n\n.ar-file-item.is-grid:hover .ar-remove-button.is-grid {\n opacity: 1;\n pointer-events: auto;\n}\n\n:host([data-theme='dark']) .ar-remove-button.is-grid {\n background: rgba(15, 23, 42, 0.92);\n color: var(--ar-color-text);\n box-shadow: 0 4px 18px rgba(8, 47, 73, 0.45);\n}\n\n.ar-remove-button svg {\n width: 20px;\n height: 20px;\n display: block;\n}\n\n.ar-remove-button svg path,\n.ar-remove-button svg line,\n.ar-remove-button svg rect,\n.ar-remove-button svg circle,\n.ar-remove-button svg polyline {\n stroke: currentColor;\n fill: none;\n}\n\n.ar-remove-button:hover:not([disabled]) {\n color: var(--ar-color-text);\n}\n\n.ar-progress-track {\n width: 100%;\n height: 4px;\n border-radius: var(--ar-radius);\n background-color: rgba(148, 163, 184, 0.35);\n overflow: hidden;\n}\n\n.ar-file-item.is-uploading {\n border-color: var(--ar-color-accent);\n}\n\n.ar-file-item.is-error {\n border: 1px solid rgba(225, 29, 72, 0.4);\n background: rgba(248, 113, 113, 0.12);\n}\n\n.ar-progress-border {\n opacity: 0;\n height: 2px;\n width: 96%;\n border-radius: 999px;\n background: var(--ar-color-accent-hover);\n overflow: hidden;\n margin-top: 0.35rem;\n position: absolute;\n bottom: 0;\n left: 6px;\n right: 6px;\n}\n\n.ar-progress-border.is-active,\n.ar-progress-border.is-complete {\n opacity: 1;\n}\n\n.ar-progress-border.is-train {\n background: var(--ar-color-accent-hover);\n}\n\n.ar-progress-fill {\n height: 100%;\n width: 0%;\n border-radius: inherit;\n background: var(--ar-color-accent);\n transition: width 0.25s ease;\n transform-origin: left center;\n animation: none;\n}\n\n.ar-progress-fill.is-train {\n background-image: linear-gradient(\n 90deg,\n rgba(245, 250, 241, 0.93) 0%,\n rgba(240, 242, 247, 0.85) 80%,\n rgb(30, 101, 212) 100%\n );\n background-size: 220% 100%;\n animation: ar-progress-train 2.4s linear infinite;\n}\n\n.ar-progress-border.is-complete {\n background: rgba(34, 197, 94, 0.25);\n}\n\n.ar-progress-border.is-complete .ar-progress-fill {\n background-image: linear-gradient(\n 90deg,\n rgba(52, 211, 153, 0.3) 0%,\n rgba(16, 185, 129, 0.85) 50%,\n rgba(52, 211, 153, 0.3) 100%\n );\n animation: none;\n}\n\n@keyframes ar-progress-train {\n 0% {\n background-position: 240% 0;\n }\n 100% {\n background-position: -240% 0;\n }\n}\n\n.ar-file-item.is-completed {\n border-color: rgba(30, 159, 109, 0.6);\n}\n\n.ar-file-item.is-grid .ar-file-name {\n text-align: left;\n font-size: 0.78rem;\n color: var(--ar-color-muted-foreground);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ar-status {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-status svg {\n width: 1rem;\n height: 1rem;\n}\n\n.ar-status.is-success {\n color: #1e9f6d;\n}\n\n.ar-status.is-error {\n color: #e11d48;\n}\n\n.ar-status.is-warning {\n color: #d97706;\n}\n\n.ar-file-error {\n font-size: 0.78rem;\n color: #e11d48;\n}\n\n.ar-error-banner {\n display: none;\n margin: 0.5rem 0;\n color: #b91c1c;\n font-size: 0.82rem;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.ar-error-banner:not([hidden]) {\n display: block;\n}\n\n:host([data-theme='dark']) .ar-error-banner {\n color: #fecaca;\n}\n\n.ar-actions {\n display: flex;\n justify-content: flex-end;\n}\n\n.ar-upload-button {\n border-radius: 10px;\n padding: 0.65rem 1.5rem;\n font-weight: 600;\n border: none;\n background: var(--ar-color-accent-button, var(--ar-color-accent));\n color: white;\n cursor: pointer;\n transition: filter 0.2s ease, transform 0.2s ease;\n min-width: 140px;\n}\n\n.ar-upload-button:hover:not([disabled]) {\n filter: brightness(1.05);\n transform: translateY(-1px);\n}\n\n.ar-upload-button[disabled] {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.ar-footer {\n font-size: 0.78rem;\n color: var(--ar-color-muted-foreground);\n text-align: right;\n}\n\n.ar-modal {\n position: fixed;\n inset: 0;\n display: none;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.ar-modal.is-portal {\n position: absolute;\n}\n\n.ar-modal.is-open {\n display: flex;\n}\n\n.ar-modal-backdrop {\n position: absolute;\n inset: 0;\n background: rgba(15, 23, 42, 0.45);\n}\n\n.ar-modal-dialog {\n position: relative;\n background: var(--ar-color-bg);\n border-radius: 16px;\n border: 1px solid var(--ar-color-border);\n box-shadow: 0 32px 80px rgba(15, 23, 42, 0.25);\n width: min(343px, 92vw);\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n padding: 0.5rem 1rem 1rem 1rem;\n}\n\n.ar-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.ar-modal-header.is-inline {\n justify-content: flex-start;\n align-items: center;\n gap: 0.5rem;\n padding-top:0.5rem;\n}\n\n.ar-modal-title {\n margin: 0;\n font-size: 1rem;\n font-weight: 500;\n}\n\n.ar-modal-close {\n border: none;\n background: transparent;\n color: var(--ar-color-muted-foreground);\n cursor: pointer;\n border-radius: 999px;\n padding: 0.3rem;\n transition: color 0.2s ease, background 0.2s ease;\n}\n\n.ar-modal-close:hover {\n background: rgba(148, 163, 184, 0.15);\n color: var(--ar-color-accent);\n}\n\n.ar-modal-close-icon svg {\n width: 1.2rem;\n height: 1.2rem;\n}\n\n.ar-modal-body {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n overflow-y: auto;\n padding-right: 0.25rem;\n}\n\n/* Reduce gap when source list is hidden in inline mode */\n:host([data-trigger='inline']) .ar-modal-body--no-sources {\n gap: 0.5rem;\n}\n\n.ar-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n}\n\n.ar-modal-footer.is-inline {\n padding: 0;\n border-top: none;\n}\n\n.ar-modal-footer.is-inline .ar-modal-footer-actions {\n margin-left: auto;\n}\n\n.ar-modal-footer-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.ar-modal-add-more,\n.ar-modal-clear {\n border-radius: var(--ar-radius);\n padding: 0.55rem 1.25rem;\n font-weight: 600;\n border: 1px solid var(--ar-color-border);\n background: var(--ar-color-bg);\n color: var(--ar-color-text);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.ar-modal-add-more:hover {\n border-color: var(--ar-color-accent-button, var(--ar-color-accent));\n color: var(--ar-color-accent-button, var(--ar-color-accent));\n}\n\n.ar-modal-clear {\n background: rgba(148, 163, 184, 0.12);\n}\n\n.ar-modal-clear[disabled] {\n opacity: 0.45;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.ar-modal-clear:hover {\n border-color: var(--ar-color-accent);\n color: var(--ar-color-accent);\n}\n\n.ar-modal-upload-button,\n.ar-modal-done {\n border-radius: var(--ar-radius);\n padding: 0.55rem 1.25rem;\n font-weight: 600;\n border: none;\n background: var(--ar-color-accent-button, var(--ar-color-accent));\n color: white;\n cursor: pointer;\n transition: filter 0.2s ease;\n}\n\n.ar-modal-upload-button:hover,\n.ar-modal-done:hover {\n filter: brightness(1.05);\n}\n\n.ar-uploaded-summary {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n border-top: 1px solid var(--ar-color-border);\n padding-top: 1rem;\n}\n\n.ar-uploader-root[data-trigger='button'] .ar-uploaded-summary {\n border: 1px solid var(--ar-color-border);\n border-radius: var(--ar-radius);\n padding: 1rem;\n background: var(--ar-color-bg-muted);\n}\n\n.ar-summary-title {\n margin: 0;\n font-size: 0.95rem;\n font-weight: 600;\n}\n\n.ar-summary-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.ar-summary-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.ar-summary-icon {\n width: 38px;\n height: 38px;\n border-radius: 12px;\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n}\n\n.ar-summary-info {\n display: flex;\n flex-direction: column;\n gap: 0.2rem;\n}\n\n.ar-summary-name {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ar-summary-meta {\n font-size: 0.8rem;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-uploader-root.is-uploading .ar-dropzone {\n display: none;\n}\n\n.ar-uploader-root.has-items .ar-file-list {\n display: flex;\n}\n\n.ar-file-list:empty {\n display: none;\n}\n\n.ar-modal-upload {\n display: flex;\n flex-direction: column;\n}\n\n.ar-modal-upload.is-inline {\n gap: 1rem;\n}\n\n.ar-modal-body .ar-file-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n max-height: 220px;\n overflow-y: auto;\n border: none;\n background: transparent;\n padding: 0;\n}\n\nbutton,\n.ar-button-trigger,\n.ar-dropzone-button,\n.ar-upload-button,\n.ar-modal-footer button,\n.ar-actions button,\n.ar-remove-button,\n.ar-modal-header button {\n font-size: 1rem;\n font-weight: 400;\n}\n\n@media (max-width: 640px) {\n .ar-uploader-root {\n padding: 1rem;\n }\n\n .ar-dropzone {\n padding: 2.25rem 1.25rem;\n }\n\n .ar-modal-dialog {\n width: min(90vw, 343px);\n padding: 1.25rem;\n }\n}\n\n.ar-actions-sources,\n.ar-modal-sources {\n display: none;\n}\n\n.ar-actions-sources.is-visible,\n.ar-modal-sources.is-visible {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.ar-source-list {\n display: none;\n flex-direction: column;\n margin: 1rem 0rem;\n}\n\n/* Remove margin when source list is hidden in inline mode */\n:host([data-trigger='inline']) .ar-source-list:not(.ar-source-list--choices) {\n margin: 0;\n}\n\n.ar-source-list--choices {\n display: flex;\n}\n\n.ar-source-option {\n display: flex;\n align-items: center;\n gap: 0.65rem;\n width: 100%;\n border: none;\n border-radius: var(--ar-radius);\n background: transparent;\n padding: 0.55rem 0.75rem;\n text-align: left;\n color: var(--ar-color-text);\n cursor: pointer;\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n\n.ar-source-option.is-primary {\n background: rgba(148, 163, 184, 0.12);\n color: var(--ar-color-muted-foreground);\n}\n\n:host([data-theme='dark']) .ar-source-option.is-primary {\n color: var(--ar-color-text);\n}\n\n.ar-source-option:hover:not([disabled]),\n.ar-source-option:focus-visible {\n background: var(--ar-color-accent-hover);\n}\n\n.ar-source-option[disabled] {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.ar-source-option-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n color: var(--ar-color-muted-foreground);\n}\n\n.ar-source-option-label {\n flex: 1;\n font-size: 0.95rem;\n}\n\n.ar-source-inline {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.ar-source-inline-button {\n width: 36px;\n height: 36px;\n border-radius: 999px;\n border: 1px solid var(--ar-color-border);\n background: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--ar-color-text);\n transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n}\n\n.ar-source-inline-button:hover:not([disabled]) {\n background: var(--ar-color-accent-hover);\n color: var(--ar-color-accent);\n border-color: var(--ar-color-accent);\n}\n\n.ar-source-inline-button svg {\n width: 18px;\n height: 18px;\n display: block;\n}\n\n.ar-modal-cancel {\n background: rgba(148, 163, 184, 0.15);\n border: none;\n color: var(--ar-color-text);\n padding:0.5rem 1rem;\n border-radius: var(--ar-radius);\n}\n\n.ar-modal-cancel:hover:not([disabled]) {\n background: rgba(148, 163, 184, 0.25);\n}\n\n.ar-modal-cancel.is-fullwidth {\n width: 100%;\n justify-content: center;\n border-radius: var(--ar-radius);\n cursor: pointer;\n}\n\n.ar-modal-powered,\n.ar-inline-powered {\n margin-top: 12px;\n font-size: 0.75rem;\n color: var(--ar-color-muted-foreground);\n text-align: center;\n}\n\n/* Reduce margin when sources are empty in inline mode */\n:host([data-trigger='inline']) .ar-inline-upload--no-sources .ar-inline-powered {\n margin-top: 0.5rem;\n}\n\n.ar-duplicate-banner {\n display: none;\n margin: 0.75rem 0;\n padding: 0.75rem;\n border-radius: var(--ar-radius);\n background: rgba(248, 113, 113, 0.12);\n color: #9f1239;\n font-size: 0.85rem;\n line-height: 1.3;\n}\n\n.ar-duplicate-banner[hidden] {\n display: none !important;\n}\n\n`;\n\n","import { UploaderController, type ControllerOptions } from '../core/uploader-controller';\nimport { DEFAULT_ICONS, DEFAULT_LABELS, DEFAULT_THEME } from '../constants/defaults';\nimport type {\n IconSet,\n LabelSet,\n ThemeOptions,\n UploadItem,\n UploadSourceOption,\n UploaderClassNames,\n} from '../types';\nimport { resolveIcon } from '../utils/helpers';\nimport { widgetStyles } from './styles';\n\nconst HTMLElementShim: typeof HTMLElement =\n typeof globalThis === 'undefined' || typeof globalThis.HTMLElement === 'undefined'\n ? (class HTMLElementFallback {} as unknown as typeof HTMLElement)\n : globalThis.HTMLElement;\n\ninterface FilesAddedDetail {\n items: UploadItem[];\n}\n\ninterface FileSystemEntry {\n isFile: boolean;\n isDirectory: boolean;\n name: string;\n fullPath: string;\n}\n\ninterface FileSystemFileEntry extends FileSystemEntry {\n file: (callback: (file: File) => void, errorCallback?: (error: DOMException) => void) => void;\n}\n\ninterface FileSystemDirectoryEntry extends FileSystemEntry {\n createReader: () => FileSystemDirectoryReader;\n}\n\ninterface FileSystemDirectoryReader {\n readEntries: (\n successCallback: (entries: FileSystemEntry[]) => void,\n errorCallback?: (error: DOMException) => void\n ) => void;\n}\n\nexport class AutorenderUploaderElement extends HTMLElementShim {\n static tagName = 'autorender-uploader';\n\n private shadow: ShadowRoot;\n private controller: UploaderController | null = null;\n private options!: ControllerOptions;\n private labels: Required<LabelSet> = DEFAULT_LABELS;\n private icons: Required<IconSet> = DEFAULT_ICONS;\n private classNames: UploaderClassNames = {};\n private sourceOptions: UploadSourceOption[] = [];\n\n private triggerType: 'button' | 'inline' = 'inline';\n private isModalOpen = false;\n private fileLayout: 'list' | 'grid' = 'list';\n private showGridFileName = true;\n\n private rootElement: HTMLElement | null = null;\n private fileInput!: HTMLInputElement;\n private dropzone: HTMLDivElement | null = null;\n private fileList: HTMLUListElement | null = null;\n private sourceLists: HTMLElement[] = [];\n private modalBody: HTMLElement | null = null;\n private inlineUpload: HTMLElement | null = null;\n private uploadButton: HTMLButtonElement | null = null;\n private triggerButton: HTMLButtonElement | null = null;\n private modalElement: HTMLElement | null = null;\n private modalCloseButton: HTMLButtonElement | null = null;\n private modalDoneButton: HTMLButtonElement | null = null;\n private modalClearButton: HTMLButtonElement | null = null;\n private modalUploadButton: HTMLButtonElement | null = null;\n private modalCancelButton: HTMLButtonElement | null = null;\n private modalAddMoreButton: HTMLButtonElement | null = null;\n private modalFooterActions: HTMLElement | null = null;\n private modalSourceContainer: HTMLElement | null = null;\n private actionsSourceContainer: HTMLElement | null = null;\n private modalTitleElement: HTMLElement | null = null;\n private modalHeaderElement: HTMLElement | null = null;\n private modalPoweredElement: HTMLElement | null = null;\n private inlinePoweredElement: HTMLElement | null = null;\n private duplicateBanners: HTMLElement[] = [];\n private errorBannerElement: HTMLElement | null = null;\n private globalErrorMessage: string | null = null;\n private portalContainer: HTMLElement | null = null;\n private portalDiv: HTMLElement | null = null;\n private isInsideContainer: boolean = false;\n\n private isAbortError(error: unknown): boolean {\n if (!error) return false;\n if (error instanceof DOMException && error.name === 'AbortError') return true;\n if (error instanceof Error && error.name === 'AbortError') return true;\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : '';\n return typeof message === 'string' && message.toLowerCase().includes('abort');\n }\n\n private controllerListeners = new Map<string, (event: Event) => void>();\n private handleKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && this.isModalOpen) {\n this.isModalOpen = false;\n this.render();\n }\n };\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback() {\n this.render();\n }\n\n disconnectedCallback() {\n this.detachController();\n window.removeEventListener('keydown', this.handleKeydown);\n this.cleanupPortal();\n }\n\n private setupPortal() {\n if (!this.options.container) {\n this.isInsideContainer = false;\n return;\n }\n\n const container = typeof this.options.container === 'string'\n ? document.querySelector<HTMLElement>(this.options.container)\n : this.options.container;\n\n if (!container) {\n console.warn(`Container \"${this.options.container}\" not found`);\n this.isInsideContainer = false;\n return;\n }\n\n // Check if the widget is already inside the container\n // If so, we don't need a portal - everything is already contained\n let currentParent: Node | null = this.parentNode;\n while (currentParent && currentParent !== document.body) {\n if (currentParent === container) {\n // Widget is already inside container, no portal needed\n // But we need to ensure container has position relative for absolute modal positioning\n const containerStyle = window.getComputedStyle(container);\n if (containerStyle.position === 'static') {\n container.style.position = 'relative';\n }\n this.portalContainer = null;\n this.portalDiv = null;\n this.isInsideContainer = true;\n return;\n }\n currentParent = currentParent.parentNode;\n }\n\n // Widget is not inside container, use portal for modal only\n // Ensure container has position relative or absolute for absolute positioning\n const containerStyle = window.getComputedStyle(container);\n if (containerStyle.position === 'static') {\n container.style.position = 'relative';\n }\n\n this.portalContainer = container;\n this.isInsideContainer = false;\n\n // Create or reuse portal div\n if (!this.portalDiv) {\n this.portalDiv = document.createElement('div');\n this.portalDiv.className = 'ar-sdk-portal';\n this.portalDiv.style.position = 'absolute';\n this.portalDiv.style.inset = '0';\n this.portalDiv.style.zIndex = '1000';\n container.appendChild(this.portalDiv);\n }\n }\n\n private cleanupPortal() {\n if (this.portalDiv) {\n this.portalDiv.remove();\n this.portalDiv = null;\n }\n this.portalContainer = null;\n this.isInsideContainer = false;\n }\n\n setController(controller: UploaderController, options: ControllerOptions) {\n this.detachController();\n this.controller = controller;\n this.globalErrorMessage = null;\n this.applyOptions(options);\n this.attachController();\n this.render();\n }\n\n updateOptions(options: Partial<ControllerOptions>) {\n if (!this.controller) return;\n this.applyOptions({ ...this.options, ...options });\n this.controller.setOptions(this.options);\n this.render();\n }\n\n openFileDialog() {\n if (this.triggerType === 'button' && !this.isModalOpen) {\n this.isModalOpen = true;\n this.render();\n requestAnimationFrame(() => this.fileInput?.click());\n return;\n }\n this.fileInput?.click();\n }\n\n private applyOptions(options: ControllerOptions) {\n const previousOptions = this.options ?? ({} as ControllerOptions);\n const themeInput = (options.theme ?? previousOptions.theme ?? DEFAULT_THEME) as ThemeOptions;\n const resolvedTheme = {\n appearance: themeInput.appearance ?? DEFAULT_THEME.appearance,\n borderRadius: themeInput.borderRadius ?? DEFAULT_THEME.borderRadius,\n dropzoneBackground: themeInput.dropzoneBackground ?? DEFAULT_THEME.dropzoneBackground,\n dropzoneBorder: themeInput.dropzoneBorder ?? DEFAULT_THEME.dropzoneBorder,\n fontFamily: themeInput.fontFamily ?? previousOptions.theme?.fontFamily,\n };\n\n // Sources are already normalized by normalizeOptions (empty array if all disabled)\n const resolvedSources = options.sources ?? previousOptions.sources ?? [];\n const previousSourceIds = this.sourceOptions?.map(s => s.id).sort().join(',') ?? '';\n\n // Resolve container\n const containerChanged = previousOptions.container !== options.container;\n if (containerChanged && this.portalDiv && this.portalContainer) {\n // Clean up old portal\n this.portalDiv.remove();\n this.portalDiv = null;\n this.portalContainer = null;\n }\n\n this.options = {\n ...previousOptions,\n ...options,\n theme: resolvedTheme,\n sources: resolvedSources,\n };\n\n // Setup portal if container is specified and widget is not already inside it\n if (this.options.container) {\n this.setupPortal();\n } else {\n this.cleanupPortal();\n }\n\n this.labels = {\n ...DEFAULT_LABELS,\n ...(this.options.labels ?? {}),\n };\n\n this.icons = DEFAULT_ICONS;\n\n const currentSourceIds = resolvedSources.map(s => s.id).sort().join(',');\n const sourcesChanged = previousSourceIds !== currentSourceIds;\n \n this.sourceOptions = resolvedSources;\n this.options.onSourceSelect = options.onSourceSelect ?? previousOptions.onSourceSelect;\n\n const requestedType = this.options.type ?? 'inline';\n this.triggerType = requestedType === 'button' ? 'button' : 'inline';\n this.fileLayout = this.options.fileLayout ?? 'list';\n this.showGridFileName = this.options.showGridFileName ?? true;\n this.classNames = this.options.classNames ?? {};\n\n if (this.options.autoUpload === undefined && this.triggerType === 'inline') {\n this.options.autoUpload = true;\n }\n\n // Re-render source list if sources changed and widget is already rendered\n if (this.rootElement && sourcesChanged) {\n const hasItems = (this.controller?.getState().items.length ?? 0) > 0;\n this.renderSourceOptions(hasItems);\n }\n }\n\n private attachController() {\n if (!this.controller) return;\n\n const stateListener = () => this.updateState();\n const progressListener = () => this.updateState();\n const filesAddedListener = (event: Event) => {\n const detail = (event as CustomEvent<FilesAddedDetail>).detail;\n if (this.options.autoUpload && detail?.items?.length) {\n void this.controller?.uploadAll();\n }\n };\n const completeListener = () => {\n this.clearGlobalError();\n this.render();\n };\n const errorListener = (event: Event) => {\n const detail = (event as CustomEvent).detail;\n this.handleControllerError(detail);\n };\n\n this.controller.addEventListener('statechange', stateListener);\n this.controller.addEventListener('progress', progressListener);\n this.controller.addEventListener('fileprogress', progressListener);\n this.controller.addEventListener('filesadded', filesAddedListener);\n this.controller.addEventListener('complete', completeListener);\n this.controller.addEventListener('error', errorListener);\n\n this.controllerListeners.set('statechange', stateListener);\n this.controllerListeners.set('progress', progressListener);\n this.controllerListeners.set('fileprogress', progressListener);\n this.controllerListeners.set('filesadded', filesAddedListener);\n this.controllerListeners.set('complete', completeListener);\n this.controllerListeners.set('error', errorListener);\n }\n\n private detachController() {\n if (!this.controller) return;\n for (const [event, handler] of this.controllerListeners.entries()) {\n this.controller.removeEventListener(event, handler);\n }\n this.controllerListeners.clear();\n this.controller = null;\n }\n\n private resolveClassName(key: keyof UploaderClassNames, fallback: string) {\n const extra = this.classNames[key];\n return extra ? `${fallback} ${extra}` : fallback;\n }\n\n private render() {\n if (!this.controller) return;\n\n this.setAttribute('data-trigger', this.triggerType);\n\n const duplicateBannerMarkup = `<div class=\"ar-duplicate-banner\" hidden></div>`;\n const errorBannerMarkup = `<div class=\"ar-error-banner\" role=\"alert\" hidden></div>`;\n\n const dropzoneMarkup = `\n <div class=\"${this.resolveClassName('dropzone', 'ar-dropzone')}\" role=\"button\" tabindex=\"0\">\n <div class=\"ar-dropzone-icon\"></div>\n <p class=\"ar-description\">${this.labels.dropzoneTitle}</p>\n </div>\n `;\n\n const fileListMarkup = `<ul class=\"${this.resolveClassName('fileList', 'ar-file-list')}\"></ul>`;\n const sourceListMarkup = '<div class=\"ar-source-list\"></div>';\n\n const modalHeaderMarkup = `\n <div class=\"ar-modal-header\">\n <h3 class=\"ar-modal-title\">${this.labels.title}</h3>\n <button type=\"button\" class=\"ar-modal-close\" aria-label=\"Close\"><span class=\"ar-modal-close-icon\"></span></button>\n </div>\n `;\n\n const inlineHeaderMarkup = `\n <div class=\"ar-modal-header is-inline\">\n <h3 class=\"ar-modal-title\">${this.labels.title}</h3>\n </div>\n `;\n\n const uploadPanelMarkup = `\n <div class=\"ar-modal-body\">\n <div class=\"ar-modal-upload${this.triggerType === 'inline' ? ' is-inline' : ''}\">\n ${dropzoneMarkup}\n ${errorBannerMarkup}\n ${duplicateBannerMarkup}\n ${sourceListMarkup}\n ${fileListMarkup}\n </div>\n </div>\n `;\n\n const footerMarkup = `\n <div class=\"ar-modal-footer${this.triggerType === 'inline' ? ' is-inline' : ''}\">\n <button type=\"button\" class=\"ar-modal-clear\">${this.labels.clear}</button>\n <button type=\"button\" class=\"ar-modal-cancel\">${this.labels.cancel}</button>\n <div class=\"ar-modal-footer-actions\">\n <div class=\"ar-modal-sources\"></div>\n <button type=\"button\" class=\"ar-modal-add-more\">${this.labels.addMore}</button>\n <button type=\"button\" class=\"ar-modal-upload-button\">${this.labels.uploadButton}</button>\n <button type=\"button\" class=\"ar-modal-done\">${this.labels.done}</button>\n </div>\n </div>\n `;\n\n // Add is-portal class if widget is inside container (for absolute positioning) or if using portal div\n const shouldUsePortalPositioning = this.portalDiv || this.isInsideContainer;\n const modalMarkup = this.triggerType === 'button'\n ? `\n <div class=\"${this.resolveClassName('modal', 'ar-modal')} ${this.isModalOpen ? 'is-open' : ''} ${shouldUsePortalPositioning ? 'is-portal' : ''}\">\n <div class=\"ar-modal-backdrop\"></div>\n <div class=\"ar-modal-dialog\">\n ${modalHeaderMarkup}\n ${uploadPanelMarkup}\n ${footerMarkup}\n <div class=\"ar-modal-powered\">Powered by Autorender</div>\n </div>\n </div>\n `\n : '';\n\n const inlineMarkup = this.triggerType === 'inline'\n ? `\n <div class=\"ar-inline-upload\">\n <div class=\"ar-inline-panel\">\n ${inlineHeaderMarkup}\n ${uploadPanelMarkup}\n ${footerMarkup}\n </div>\n <div class=\"ar-inline-powered\">Powered by Autorender</div>\n </div>\n `\n : '';\n\n const template = document.createElement('template');\n template.innerHTML = `\n <style>${widgetStyles}</style>\n <div class=\"${this.resolveClassName('root', 'ar-uploader-root')}\" data-trigger=\"${this.triggerType}\">\n <input type=\"file\" class=\"ar-file-input\" hidden />\n ${\n this.triggerType === 'button'\n ? `<button type=\"button\" class=\"${this.resolveClassName('triggerButton', 'ar-button-trigger')}\"><span class=\"ar-button-icon\"></span><span>${this.labels.selectButton}</span></button>`\n : inlineMarkup\n }\n ${this.portalDiv ? '' : modalMarkup}\n </div>\n `;\n\n this.shadow.innerHTML = '';\n this.shadow.appendChild(template.content.cloneNode(true));\n\n // Render modal in portal if container is specified\n if (this.portalDiv && this.triggerType === 'button') {\n const portalTemplate = document.createElement('template');\n portalTemplate.innerHTML = `<style>${widgetStyles}</style>${modalMarkup}`;\n this.portalDiv.innerHTML = '';\n this.portalDiv.appendChild(portalTemplate.content.cloneNode(true));\n } else if (this.portalDiv && !this.triggerType) {\n // Clean up portal if not needed\n this.portalDiv.innerHTML = '';\n }\n\n this.captureElements();\n this.applyDimensions();\n this.configureInputs();\n this.bindEvents();\n this.applyThemeVariables();\n this.updateState();\n\n if (this.triggerType === 'button') {\n if (this.isModalOpen) {\n window.addEventListener('keydown', this.handleKeydown);\n } else {\n window.removeEventListener('keydown', this.handleKeydown);\n }\n }\n }\n\n private queryModalElement(selector: string): Element | null {\n // Query from portal first if it exists, otherwise from shadow\n if (this.portalDiv) {\n return this.portalDiv.querySelector(selector) || this.shadow.querySelector(selector);\n }\n return this.shadow.querySelector(selector);\n }\n\n private queryModalElements(selector: string): Element[] {\n // Query from portal first if it exists, otherwise from shadow\n if (this.portalDiv) {\n const portalResults = Array.from(this.portalDiv.querySelectorAll(selector));\n const shadowResults = Array.from(this.shadow.querySelectorAll(selector));\n // Combine results (portal takes precedence)\n const combined: Element[] = [];\n portalResults.forEach(el => combined.push(el));\n shadowResults.forEach(el => {\n if (!combined.includes(el)) combined.push(el);\n });\n return combined;\n }\n return Array.from(this.shadow.querySelectorAll(selector));\n }\n\n private captureElements() {\n this.rootElement = this.shadow.querySelector('.ar-uploader-root');\n this.fileInput = this.shadow.querySelector('.ar-file-input') as HTMLInputElement;\n this.dropzone = this.shadow.querySelector('.ar-dropzone');\n this.fileList = this.shadow.querySelector('.ar-file-list');\n this.sourceLists = Array.from(this.shadow.querySelectorAll('.ar-source-list')) as HTMLElement[];\n this.modalBody = this.queryModalElement('.ar-modal-body') as HTMLElement | null;\n this.inlineUpload = this.shadow.querySelector('.ar-inline-upload');\n this.uploadButton = this.shadow.querySelector('.ar-upload-button');\n this.triggerButton = this.shadow.querySelector('.ar-button-trigger');\n this.modalElement = this.queryModalElement('.ar-modal') as HTMLElement | null;\n this.modalCloseButton = this.queryModalElement('.ar-modal-close') as HTMLButtonElement | null;\n this.modalDoneButton = this.queryModalElement('.ar-modal-done') as HTMLButtonElement | null;\n this.modalClearButton = this.queryModalElement('.ar-modal-clear') as HTMLButtonElement | null;\n this.modalUploadButton = this.queryModalElement('.ar-modal-upload-button') as HTMLButtonElement | null;\n this.modalCancelButton = this.queryModalElement('.ar-modal-cancel') as HTMLButtonElement | null;\n this.modalAddMoreButton = this.queryModalElement('.ar-modal-add-more') as HTMLButtonElement | null;\n this.modalFooterActions = this.queryModalElement('.ar-modal-footer-actions') as HTMLElement | null;\n this.modalSourceContainer = this.queryModalElement('.ar-modal-sources') as HTMLElement | null;\n this.actionsSourceContainer = this.shadow.querySelector('.ar-actions-sources');\n this.modalTitleElement = this.queryModalElement('.ar-modal-title') as HTMLElement | null;\n this.modalHeaderElement = this.queryModalElement('.ar-modal-header') as HTMLElement | null;\n this.modalPoweredElement = this.queryModalElement('.ar-modal-powered') as HTMLElement | null;\n this.inlinePoweredElement = this.shadow.querySelector('.ar-inline-powered');\n this.duplicateBanners = this.queryModalElements('.ar-duplicate-banner') as HTMLElement[];\n this.errorBannerElement = this.queryModalElement('.ar-error-banner') as HTMLElement | null;\n this.updateErrorBanner();\n\n const icon = resolveIcon(this.icons.upload);\n const iconContainer = this.shadow.querySelector('.ar-dropzone-icon');\n if (icon && iconContainer) {\n iconContainer.innerHTML = '';\n iconContainer.appendChild(icon);\n }\n const buttonIcon = resolveIcon(this.icons.upload);\n const triggerIconContainer = this.shadow.querySelector('.ar-button-icon');\n if (buttonIcon && triggerIconContainer) {\n triggerIconContainer.innerHTML = '';\n triggerIconContainer.appendChild(buttonIcon);\n }\n const closeIcon = resolveIcon(this.icons.close);\n const closeIconContainer = this.queryModalElement('.ar-modal-close-icon');\n if (closeIcon && closeIconContainer) {\n closeIconContainer.innerHTML = '';\n closeIconContainer.appendChild(closeIcon);\n }\n }\n\n private applyDimensions() {\n if (!this.rootElement) return;\n\n const requestedWidth = this.options.width;\n\n if (requestedWidth === undefined || requestedWidth === null || requestedWidth === '') {\n if (this.triggerType === 'inline') {\n this.rootElement.style.width = '100%';\n } else {\n this.rootElement.style.removeProperty('width');\n }\n return;\n }\n\n const normalizedWidth =\n typeof requestedWidth === 'number' ? `${requestedWidth}px` : requestedWidth;\n this.rootElement.style.width = normalizedWidth;\n }\n\n private configureInputs() {\n this.fileInput?.removeAttribute('webkitdirectory');\n this.fileInput?.removeAttribute('mozdirectory');\n this.fileInput?.removeAttribute('directory');\n\n if (this.options.allowMultiple === false) {\n this.fileInput?.removeAttribute('multiple');\n } else {\n this.fileInput?.setAttribute('multiple', '');\n }\n\n if (this.options.accept?.length) {\n this.fileInput.accept = this.options.accept.join(',');\n }\n }\n\n private bindEvents() {\n this.triggerButton?.addEventListener('click', () => {\n this.isModalOpen = true;\n this.render();\n });\n\n this.modalCloseButton?.addEventListener('click', () => {\n this.isModalOpen = false;\n this.render();\n });\n\n this.modalElement?.addEventListener('click', event => {\n const target = event.target as HTMLElement;\n if (!target) return;\n if (target === this.modalElement || target.classList.contains('ar-modal-backdrop')) {\n this.isModalOpen = false;\n this.render();\n }\n });\n\n this.modalUploadButton?.addEventListener('click', () => {\n if (!this.controller) return;\n if (this.controller.getState().isUploading) return;\n void this.controller.uploadAll();\n });\n\n this.modalDoneButton?.addEventListener('click', () => {\n if (!this.controller) return;\n const state = this.controller.getState();\n const allCompleted = state.items.length > 0 && state.items.every(item => item.status === 'completed');\n if (this.triggerType === 'inline') {\n if (state.isUploading) {\n return;\n }\n if (allCompleted || state.items.length === 0) {\n this.controller.reset();\n this.updateState();\n }\n return;\n }\n if (state.isUploading) {\n this.closeModal();\n return;\n }\n if (allCompleted) {\n this.closeModal();\n return;\n }\n this.closeModal();\n });\n\n this.modalClearButton?.addEventListener('click', () => {\n if (!this.controller) return;\n const { isUploading } = this.controller.getState();\n if (isUploading) {\n return;\n }\n this.controller.reset();\n this.updateState();\n });\n\n this.modalCancelButton?.addEventListener('click', () => {\n if (!this.controller) return;\n const currentState = this.controller.getState();\n if (currentState.isUploading) return;\n this.controller.reset();\n if (this.triggerType === 'inline') {\n this.updateState();\n return;\n }\n this.isModalOpen = false;\n this.render();\n });\n\n this.modalAddMoreButton?.addEventListener('click', () => {\n this.openFileDialog();\n });\n\n this.dropzone?.addEventListener('click', () => this.openFileDialog());\n this.dropzone?.addEventListener('dragenter', event => {\n event.preventDefault();\n this.dropzone?.classList.add('is-dragging');\n });\n this.dropzone?.addEventListener('dragover', event => {\n event.preventDefault();\n this.dropzone?.classList.add('is-dragging');\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n });\n this.dropzone?.addEventListener('dragleave', event => {\n if (event.target === this.dropzone) {\n this.dropzone?.classList.remove('is-dragging');\n }\n });\n this.dropzone?.addEventListener('drop', async event => {\n event.preventDefault();\n this.dropzone?.classList.remove('is-dragging');\n const files = await this.extractFilesFromEvent(event);\n if (files.length) {\n await this.controller?.addFiles(files);\n }\n if (this.fileInput) {\n this.fileInput.value = '';\n }\n });\n\n this.fileInput?.addEventListener('change', async () => {\n const files = this.fileInput?.files ? Array.from(this.fileInput.files) : [];\n const mapped = files.map(file => ({\n file,\n relativePath: (file as File & { webkitRelativePath?: string }).webkitRelativePath,\n }));\n await this.controller?.addFiles(mapped);\n if (this.fileInput) this.fileInput.value = '';\n });\n\n this.uploadButton?.addEventListener('click', () => {\n if (this.controller?.getState().isUploading) return;\n void this.controller?.uploadAll();\n });\n }\n\n private async extractFilesFromEvent(\n event: DragEvent\n ): Promise<Array<{ file: File; relativePath?: string }>> {\n const items = event.dataTransfer?.items;\n\n if (!items) {\n const files = event.dataTransfer?.files ? Array.from(event.dataTransfer.files) : [];\n return files.map(file => ({\n file,\n relativePath: (file as File & { webkitRelativePath?: string }).webkitRelativePath,\n }));\n }\n\n const entries = Array.from(items)\n .map(item => (item.webkitGetAsEntry ? item.webkitGetAsEntry() : null))\n .filter(Boolean) as FileSystemEntry[];\n\n const collected: Array<{ file: File; relativePath?: string }> = [];\n\n for (const entry of entries) {\n const files = await this.readEntry(entry, '');\n collected.push(...files);\n }\n\n return collected;\n }\n\n private readEntry(entry: FileSystemEntry, path = ''): Promise<Array<{ file: File; relativePath?: string }>> {\n return new Promise(resolve => {\n if (entry.isFile) {\n (entry as FileSystemFileEntry).file(file => {\n resolve([{ file, relativePath: path ? `${path}/${file.name}` : file.name }]);\n });\n } else if (entry.isDirectory) {\n const reader = (entry as FileSystemDirectoryEntry).createReader();\n reader.readEntries(async entries => {\n const results = await Promise.all(\n entries.map(child => this.readEntry(child, path ? `${path}/${entry.name}` : entry.name))\n );\n resolve(results.flat());\n });\n } else {\n resolve([]);\n }\n });\n }\n\n private closeModal() {\n this.isModalOpen = false;\n this.render();\n }\n\n private setGlobalError(message: string | null) {\n this.globalErrorMessage = message;\n this.updateErrorBanner();\n }\n\n private clearGlobalError() {\n this.setGlobalError(null);\n }\n\n private updateErrorBanner() {\n if (!this.errorBannerElement) return;\n if (this.globalErrorMessage) {\n this.errorBannerElement.hidden = false;\n this.errorBannerElement.textContent = this.globalErrorMessage;\n } else {\n this.errorBannerElement.hidden = true;\n this.errorBannerElement.textContent = '';\n }\n }\n\n private handleControllerError(error: unknown) {\n if (this.isAbortError(error)) {\n this.clearGlobalError();\n return;\n }\n\n const status =\n typeof error === 'object' && error !== null && 'status' in error\n ? (error as any).status\n : undefined;\n const messageCandidate =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : typeof error === 'string'\n ? error\n : '';\n\n const normalized = String(messageCandidate ?? '').toLowerCase();\n const isAuthError =\n (typeof status === 'number' && (status === 401 || status === 403)) ||\n normalized.includes('unauthorized') ||\n normalized.includes('forbidden') ||\n normalized.includes('invalid api key');\n\n if (isAuthError) {\n this.setGlobalError(this.labels.invalidApiKey);\n } else if (messageCandidate) {\n this.setGlobalError(String(messageCandidate));\n } else {\n this.setGlobalError(this.labels.uploadFailed);\n }\n }\n\n private updateState() {\n if (!this.controller) return;\n if (!this.fileList) return;\n\n const state = this.controller.getState();\n const { items, isUploading, duplicates } = state;\n const hasItems = items.length > 0;\n const hasAuthError = items.some(item => item.error === 'invalid-api-key');\n\n if (hasAuthError) {\n this.setGlobalError(this.labels.invalidApiKey);\n }\n\n if (this.rootElement) {\n this.rootElement.classList.toggle('is-uploading', isUploading);\n this.rootElement.classList.toggle('has-items', hasItems);\n }\n\n if (this.dropzone) {\n if (hasItems) {\n this.dropzone.style.display = 'none';\n } else {\n this.dropzone.style.display = 'flex';\n }\n }\n\n this.renderFileList(items);\n this.updateErrorBanner();\n this.renderSourceOptions(hasItems);\n this.updateModalTitle(items, isUploading);\n this.updateDuplicateBanners(duplicates);\n\n if (this.modalHeaderElement) {\n this.modalHeaderElement.style.display = hasItems ? '' : 'none';\n }\n if (this.modalPoweredElement) {\n this.modalPoweredElement.style.display = hasItems ? 'none' : '';\n }\n if (this.inlinePoweredElement) {\n this.inlinePoweredElement.style.display = hasItems ? 'none' : '';\n }\n\n if (this.triggerType === 'button' || this.triggerType === 'inline') {\n const completedCount = items.filter(item => item.status === 'completed').length;\n const allCompleted = hasItems && completedCount === items.length && completedCount > 0;\n\n if (this.modalFooterActions) {\n this.modalFooterActions.style.display = hasItems ? '' : 'none';\n }\n\n const uploadButton = this.modalUploadButton;\n const doneButton = this.modalDoneButton;\n const cancelButton = this.modalCancelButton;\n const clearButton = this.modalClearButton;\n const addMoreButton = this.modalAddMoreButton;\n\n const showUpload = hasItems && !isUploading && !allCompleted;\n const showAddMore = hasItems && !isUploading && !allCompleted;\n const showDone = hasItems && (isUploading || allCompleted);\n const showClear = hasItems && (isUploading || allCompleted);\n const showInlineCancel =\n this.triggerType === 'inline' && hasItems && !isUploading && !allCompleted;\n const showButtonCancel =\n this.triggerType === 'button' && !isUploading && (!allCompleted || !hasItems);\n const showCancel = showInlineCancel || showButtonCancel;\n\n if (uploadButton) {\n uploadButton.style.display = showUpload ? '' : 'none';\n uploadButton.toggleAttribute('disabled', !showUpload);\n }\n\n if (doneButton) {\n doneButton.style.display = showDone ? '' : 'none';\n doneButton.textContent = this.labels.done;\n doneButton.toggleAttribute('disabled', !showDone);\n }\n\n if (clearButton) {\n clearButton.style.display = showClear ? '' : 'none';\n clearButton.toggleAttribute('disabled', isUploading);\n }\n\n if (cancelButton) {\n cancelButton.style.display = showCancel ? '' : 'none';\n cancelButton.classList.toggle(\n 'is-fullwidth',\n this.triggerType === 'button' && !hasItems\n );\n }\n\n if (addMoreButton) {\n addMoreButton.style.display = showAddMore ? '' : 'none';\n addMoreButton.toggleAttribute('disabled', !showAddMore);\n }\n }\n }\n\n private renderFileList(items: UploadItem[]) {\n if (!this.fileList) return;\n this.fileList.innerHTML = '';\n if (items.length === 0) {\n this.fileList.style.display = 'none';\n this.fileList.classList.remove('is-grid');\n return;\n }\n\n const isGridLayout = this.fileLayout === 'grid';\n this.fileList.style.display = isGridLayout ? 'grid' : 'flex';\n this.fileList.classList.toggle('is-grid', isGridLayout);\n if (isGridLayout) {\n this.fileList.style.gridTemplateColumns = 'repeat(auto-fill, minmax(140px, 1fr))';\n this.fileList.style.gap = '1rem';\n } else {\n this.fileList.style.removeProperty('grid-template-columns');\n this.fileList.style.removeProperty('gap');\n }\n\n const isUploading = this.controller?.getState().isUploading ?? false;\n\n items.forEach(item => {\n const li = document.createElement('li');\n li.className = 'ar-file-item';\n li.classList.toggle('is-grid', isGridLayout);\n\n const isInvalidApiKeyError = item.error === 'invalid-api-key';\n\n if (item.status === 'uploading' || item.status === 'pending') li.classList.add('is-uploading');\n if (item.status === 'completed') li.classList.add('is-completed');\n if (item.status === 'error' && !isInvalidApiKeyError) li.classList.add('is-error');\n\n const header = document.createElement('div');\n header.className = 'ar-file-header';\n header.classList.toggle('is-grid', isGridLayout);\n\n const thumb = document.createElement('div');\n thumb.className = 'ar-file-thumb';\n thumb.classList.toggle('is-grid', isGridLayout);\n const isImage = item.file.type.startsWith('image/');\n if (item.previewUrl && isImage) {\n const img = document.createElement('img');\n img.src = item.previewUrl;\n img.alt = item.file.name;\n thumb.appendChild(img);\n } else {\n // Show document icon for non-images\n thumb.classList.add('ar-file-thumb-document');\n const documentIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n documentIcon.setAttribute('viewBox', '0 0 24 24');\n documentIcon.setAttribute('width', '24');\n documentIcon.setAttribute('height', '24');\n documentIcon.setAttribute('fill', 'none');\n documentIcon.setAttribute('aria-hidden', 'true');\n const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path1.setAttribute('d', 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6Z');\n path1.setAttribute('stroke', 'currentColor');\n path1.setAttribute('stroke-width', '1.5');\n path1.setAttribute('stroke-linecap', 'round');\n path1.setAttribute('stroke-linejoin', 'round');\n const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path2.setAttribute('d', 'M14 2v6h6');\n path2.setAttribute('stroke', 'currentColor');\n path2.setAttribute('stroke-width', '1.5');\n path2.setAttribute('stroke-linecap', 'round');\n path2.setAttribute('stroke-linejoin', 'round');\n documentIcon.appendChild(path1);\n documentIcon.appendChild(path2);\n thumb.appendChild(documentIcon);\n }\n\n if (item.status === 'completed') {\n const statusOverlay = document.createElement('div');\n statusOverlay.className = 'ar-thumb-status';\n const successIcon = resolveIcon(this.icons.success);\n if (successIcon) {\n statusOverlay.appendChild(successIcon);\n }\n thumb.appendChild(statusOverlay);\n } else if (item.status === 'error' && !isInvalidApiKeyError) {\n const statusOverlay = document.createElement('div');\n statusOverlay.className = 'ar-thumb-status is-error';\n const errorIcon = resolveIcon(this.icons.error);\n if (errorIcon) {\n statusOverlay.appendChild(errorIcon);\n }\n thumb.appendChild(statusOverlay);\n }\n\n const name = document.createElement('span');\n name.className = 'ar-file-name';\n name.textContent = item.file.name;\n if (isGridLayout && !this.showGridFileName) {\n name.style.display = 'none';\n } else {\n name.style.display = '';\n }\n\n const removeButton = document.createElement('button');\n removeButton.type = 'button';\n removeButton.className = 'ar-remove-button';\n const shouldShowRemove =\n (item.status === 'pending' ||\n (item.status === 'error' && isInvalidApiKeyError)) &&\n !isUploading;\n removeButton.disabled = !shouldShowRemove;\n removeButton.hidden = !shouldShowRemove;\n removeButton.style.display = shouldShowRemove ? 'inline-flex' : 'none';\n removeButton.classList.toggle('is-grid', isGridLayout);\n const removeIcon = resolveIcon(this.icons.remove);\n if (removeIcon) {\n removeButton.appendChild(removeIcon);\n }\n removeButton.addEventListener('click', () => {\n if (this.controller?.getState().isUploading) return;\n this.controller?.removeFile(item.id);\n });\n\n header.appendChild(thumb);\n header.appendChild(name);\n header.appendChild(removeButton);\n li.appendChild(header);\n\n // Display info message (not error) if present - show it right after header\n if (item.info) {\n const metaRow = document.createElement('div');\n metaRow.className = 'ar-file-meta';\n const infoText = document.createElement('span');\n infoText.className = 'ar-file-info';\n infoText.textContent = item.info;\n metaRow.appendChild(infoText);\n li.appendChild(metaRow);\n }\n\n const progressBorder = document.createElement('div');\n progressBorder.className = 'ar-progress-border';\n\n const progressFill = document.createElement('div');\n progressFill.className = 'ar-progress-fill';\n\n const isPendingStatus = item.status === 'pending';\n const isUploadingStatus = item.status === 'uploading';\n const isCompleteStatus = item.status === 'completed';\n const rawProgress = Math.max(0, Math.min(100, item.progress ?? 0));\n const calculatedTrain = !isCompleteStatus && rawProgress < 20;\n const shouldAnimateTrain = (isUploadingStatus || (isUploading && isPendingStatus)) && calculatedTrain;\n // Keep indicator active if uploading, even if progress hasn't updated recently\n const isActive = isUploadingStatus || shouldAnimateTrain || (rawProgress > 0 && !isCompleteStatus);\n const stateLabel = isCompleteStatus ? 'complete' : shouldAnimateTrain ? 'train' : rawProgress >= 20 ? 'progress' : isUploadingStatus ? 'progress' : 'idle';\n\n progressBorder.dataset.state = stateLabel;\n progressBorder.dataset.status = item.status;\n progressBorder.dataset.progress = rawProgress.toFixed(0);\n\n progressBorder.classList.toggle('is-active', isActive);\n progressBorder.classList.toggle('is-train', shouldAnimateTrain);\n progressBorder.classList.toggle('is-complete', isCompleteStatus);\n progressBorder.style.display = isCompleteStatus ? 'none' : '';\n\n progressFill.classList.toggle('is-train', shouldAnimateTrain);\n progressFill.classList.toggle('is-animating', shouldAnimateTrain);\n\n if (isCompleteStatus) {\n progressFill.style.width = '100%';\n } else if (shouldAnimateTrain) {\n progressFill.style.width = '100%';\n } else if (isUploadingStatus && rawProgress === 0) {\n // Show minimal progress for uploading items even if progress hasn't started\n progressFill.style.width = '3%';\n } else {\n const computedWidth = Math.max(rawProgress, 3);\n progressFill.style.width = `${Math.min(computedWidth, 100)}%`;\n }\n\n progressBorder.appendChild(progressFill);\n\n li.appendChild(progressBorder);\n\n this.fileList?.appendChild(li);\n });\n }\n\n private renderSourceOptions(hasItems: boolean) {\n // Filter out disabled sources - only show enabled ones\n const enabledSources = this.sourceOptions.filter(option => !option.disabled);\n const hasSourcesConfigured = enabledSources.length > 0;\n\n const renderChoiceList = (container: HTMLElement) => {\n container.innerHTML = '';\n if (!hasSourcesConfigured) {\n container.style.display = 'none';\n container.classList.remove('ar-source-list--choices');\n return;\n }\n\n container.style.display = hasItems ? 'none' : 'flex';\n container.classList.toggle('ar-source-list--choices', !hasItems);\n if (hasItems) return;\n\n // Only render enabled sources\n enabledSources.forEach(option => {\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'ar-source-option';\n\n const icon = resolveIcon(option.icon ?? this.icons.upload);\n if (icon) {\n const iconWrapper = document.createElement('span');\n iconWrapper.className = 'ar-source-option-icon';\n iconWrapper.appendChild(icon);\n button.appendChild(iconWrapper);\n }\n\n const label = document.createElement('span');\n label.className = 'ar-source-option-label';\n label.textContent = option.label;\n button.appendChild(label);\n\n button.addEventListener('click', () => this.handleSourceOption(option));\n container.appendChild(button);\n });\n };\n\n this.sourceLists.forEach(container => {\n renderChoiceList(container);\n });\n\n if (this.modalSourceContainer) {\n this.modalSourceContainer.classList.toggle('is-visible', hasSourcesConfigured && !hasItems);\n this.modalSourceContainer.style.display = hasSourcesConfigured ? '' : 'none';\n this.modalSourceContainer.innerHTML = '';\n }\n if (this.actionsSourceContainer) {\n this.actionsSourceContainer.classList.toggle('is-visible', hasSourcesConfigured && !hasItems);\n this.actionsSourceContainer.style.display = hasSourcesConfigured ? '' : 'none';\n this.actionsSourceContainer.innerHTML = '';\n }\n\n // Add class to modal body and inline upload when sources are empty in inline mode\n if (this.triggerType === 'inline') {\n if (this.modalBody) {\n this.modalBody.classList.toggle('ar-modal-body--no-sources', !hasSourcesConfigured);\n }\n if (this.inlineUpload) {\n this.inlineUpload.classList.toggle('ar-inline-upload--no-sources', !hasSourcesConfigured);\n }\n }\n }\n\n private updateModalTitle(items: UploadItem[], isUploading: boolean) {\n if (!this.modalTitleElement) return;\n if (items.length === 0) {\n this.modalTitleElement.textContent = isUploading\n ? this.labels.uploading\n : this.labels.title;\n this.modalTitleElement.classList.remove('is-dynamic', 'is-success');\n return;\n }\n\n const total = items.length;\n const modalTitle = this.modalTitleElement;\n\n const suffix = total === 1 ? 'file' : 'files';\n const completedCount = items.filter(item => item.status === 'completed').length;\n\n modalTitle.classList.add('is-dynamic');\n modalTitle.classList.toggle('is-success', completedCount === total);\n\n if (isUploading) {\n modalTitle.textContent = `Uploading ${completedCount}/${total} ${suffix}`;\n return;\n }\n\n if (completedCount === total) {\n modalTitle.textContent = `${total} ${suffix} uploaded`;\n return;\n }\n\n modalTitle.textContent = `${total} ${suffix} ready`;\n }\n\n private updateDuplicateBanners(duplicates: string[]) {\n const hasDuplicates = duplicates.length > 0;\n const prefix =\n duplicates.length === 1\n ? this.labels.duplicateFileExists\n : this.labels.duplicateFilesExist;\n const message = hasDuplicates\n ? `${prefix} ${duplicates.join(', ')}`\n : '';\n\n this.duplicateBanners.forEach(banner => {\n banner.hidden = !hasDuplicates;\n banner.textContent = message;\n });\n }\n\n private handleSourceOption(option: UploadSourceOption) {\n if (option.disabled) return;\n\n this.options.onSourceSelect?.(option);\n this.dispatchEvent(new CustomEvent('sourceselect', { detail: option }));\n\n if (option.kind === 'device' && !option.action) {\n this.openFileDialog();\n return;\n }\n\n if (option.action) {\n try {\n option.action();\n } catch (error) {\n console.error('[AutorenderUploader] Source action failed', error);\n }\n return;\n }\n\n console.warn('[AutorenderUploader] No handler configured for source option', option);\n }\n\n private applyThemeVariables() {\n const theme = (this.options.theme ?? {}) as ThemeOptions;\n const borderRadius = theme.borderRadius;\n const accentColor = theme.accentColor;\n const dropzoneBackground = theme.dropzoneBackground ?? DEFAULT_THEME.dropzoneBackground;\n const dropzoneBorder = theme.dropzoneBorder ?? DEFAULT_THEME.dropzoneBorder;\n const fontFamily = theme.fontFamily;\n\n if (borderRadius !== undefined) {\n this.style.setProperty(\n '--ar-radius',\n typeof borderRadius === 'number' ? `${borderRadius}px` : String(borderRadius)\n );\n } else {\n this.style.removeProperty('--ar-radius');\n }\n\n // Only set accent color if explicitly provided; otherwise let palette CSS handle it\n if (accentColor) {\n this.style.setProperty('--ar-color-accent', accentColor);\n } else {\n this.style.removeProperty('--ar-color-accent');\n }\n\n if (dropzoneBackground) {\n this.style.setProperty('--ar-dropzone-bg', dropzoneBackground);\n }\n if (dropzoneBorder) {\n this.style.setProperty('--ar-dropzone-border', dropzoneBorder);\n }\n if (fontFamily) {\n this.style.setProperty('--ar-font-family', fontFamily);\n }\n\n const appearance = theme.appearance ?? DEFAULT_THEME.appearance;\n let resolvedAppearance = appearance;\n if (appearance === 'system' && typeof window !== 'undefined') {\n resolvedAppearance = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n this.setAttribute('data-theme', resolvedAppearance);\n\n // Apply palette\n const palette = this.options.palette;\n if (palette) {\n this.setAttribute('data-palette', palette);\n } else {\n this.removeAttribute('data-palette');\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'autorender-uploader': AutorenderUploaderElement;\n }\n}","/**\n * Device detection utilities for DPR and connection quality\n */\n\nexport function getDPR(): number {\n if (typeof window === 'undefined') return 1;\n const dpr = window.devicePixelRatio || 1;\n // Round to 1 or 2 for most cases (can be extended to 3 for high-DPI)\n return dpr >= 2 ? 2 : 1;\n}\n\n// export function getConnectionQuality(): '2g' | '3g' | '4g' | 'wifi' | 'unknown' {\n\n// if (typeof navigator === 'undefined') return 'unknown';\n \n// // Check for Network Information API\n// const connection = (navigator as any).connection || \n// (navigator as any).mozConnection || \n// (navigator as any).webkitConnection;\n \n// if (!connection) return 'unknown';\n \n// const effectiveType = connection.effectiveType || connection.effectiveConnectionType;\n// const type = connection.type;\n \n// // Use effectiveType if available (Chrome/Edge)\n// if (effectiveType) {\n// if (effectiveType === 'slow-2g' || effectiveType === '2g') return '2g';\n// if (effectiveType === '3g') return '3g';\n// if (effectiveType === '4g') return '4g';\n// }\n \n// // Fallback to type (older API)\n// if (type) {\n// if (type === 'cellular') {\n// // Try to infer from downlink\n// const downlink = connection.downlink;\n// if (downlink) {\n// if (downlink < 0.5) return '2g';\n// if (downlink < 1.5) return '3g';\n// return '4g';\n// }\n// return '3g'; // Default for cellular\n// }\n// if (type === 'wifi' || type === 'ethernet') return 'wifi';\n// }\n \n// return 'unknown';\n// }\n\n// export function getQualityForConnection(connectionQuality: '2g' | '3g' | '4g' | 'wifi' | 'unknown' | 'auto'): string | number {\n// if (connectionQuality === 'auto') {\n// const detected = getConnectionQuality();\n// return getQualityForConnection(detected);\n// }\n \n// switch (connectionQuality) {\n// case '2g':\n// return 50;\n// case '3g':\n// return 70;\n// case '4g':\n// case 'wifi':\n// return 'auto';\n// default:\n// return 'auto';\n// }\n// }\n\n\nexport type ConnectionQuality = '2g' | '3g' | '4g' | 'wifi' | 'unknown';\nexport type QualityMode = 'auto' | 50 | 70 | 75;\n\ntype ConnectionResult = {\n quality: ConnectionQuality;\n reason: string;\n saveData: boolean;\n effectiveType?: string;\n downlinkMbps?: number;\n rttMs?: number;\n};\n\nfunction getNavigatorConnection(): any | null {\n if (typeof navigator === 'undefined') return null;\n const nav: any = navigator;\n return nav.connection || nav.mozConnection || nav.webkitConnection || null;\n}\n\n/**\n * Production-ready connection detection:\n * - \"wifi\" is only returned when the API truly exposes type === 'wifi'/'ethernet'.\n * - Otherwise we stick to effectiveType (2g/3g/4g) or unknown.\n * - saveData is captured as a strong signal.\n */\nexport function getConnectionQualityDetailed(): ConnectionResult {\n if (typeof navigator === 'undefined') {\n return { quality: 'unknown', reason: 'ssr:no-navigator', saveData: false };\n }\n\n const connection = getNavigatorConnection();\n if (!connection) {\n return { quality: 'unknown', reason: 'no-network-info-api', saveData: false };\n }\n\n const saveData = connection.saveData === true;\n\n // Strong hint: user explicitly wants reduced data usage.\n // We still return a \"quality\" label for UI, but you should act on saveData in your quality logic.\n const effectiveType: string | undefined =\n connection.effectiveType || connection.effectiveConnectionType;\n\n const downlinkMbps: number | undefined =\n typeof connection.downlink === 'number' ? connection.downlink : undefined;\n\n const rttMs: number | undefined =\n typeof connection.rtt === 'number' ? connection.rtt : undefined;\n\n // 1) Preferred: effectiveType (Chromium mostly)\n if (effectiveType) {\n if (effectiveType === 'slow-2g' || effectiveType === '2g') {\n return { quality: '2g', reason: `effectiveType:${effectiveType}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n if (effectiveType === '3g') {\n return { quality: '3g', reason: 'effectiveType:3g', saveData, effectiveType, downlinkMbps, rttMs };\n }\n if (effectiveType === '4g') {\n // Note: 4g might still be cellular or wifi; effectiveType doesn't mean wifi.\n return { quality: '4g', reason: 'effectiveType:4g', saveData, effectiveType, downlinkMbps, rttMs };\n }\n }\n\n // 2) Optional: connection.type (rarely available in modern browsers)\n // Only return \"wifi\" if the browser explicitly says so.\n const type: string | undefined = connection.type;\n if (type === 'wifi' || type === 'ethernet') {\n return { quality: 'wifi', reason: `type:${type}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n\n // 3) Soft fallback: infer from downlink IF we have it.\n // Thresholds are conservative and should be treated as a hint.\n if (typeof downlinkMbps === 'number') {\n if (downlinkMbps < 0.7) {\n return { quality: '2g', reason: `downlink<0.7Mbps:${downlinkMbps}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n if (downlinkMbps < 1.8) {\n return { quality: '3g', reason: `downlink<1.8Mbps:${downlinkMbps}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n return { quality: '4g', reason: `downlink>=1.8Mbps:${downlinkMbps}`, saveData, effectiveType, downlinkMbps, rttMs };\n }\n\n return { quality: 'unknown', reason: 'insufficient-signals', saveData, effectiveType, downlinkMbps, rttMs };\n}\n\nexport function getConnectionQuality(): ConnectionQuality {\n return getConnectionQualityDetailed().quality;\n}\n\n/**\n * Production-ready quality selection:\n * - saveData => force low quality (strongest signal)\n * - 2g => q_50\n * - 3g => q_70\n * - 4g/wifi/unknown => 'auto' (your server-side q_auto policy) OR 75 if you want fixed\n */\nexport function getQualityForConnection(\n input: ConnectionQuality | 'auto',\n opts?: {\n // What to do when connection is unknown / high quality:\n // 'auto' means let AutoRender decide (q_auto)\n // 75 means fixed quality\n highQuality?: 'auto' | 75;\n // If user enabled data saver, override everything\n saveDataQuality?: 50 | 70;\n }\n): QualityMode {\n const highQuality = opts?.highQuality ?? 'auto';\n const saveDataQuality = opts?.saveDataQuality ?? 50;\n\n if (input === 'auto') {\n const detected = getConnectionQualityDetailed();\n if (detected.saveData) return saveDataQuality;\n return getQualityForConnection(detected.quality, opts);\n }\n\n switch (input) {\n case '2g':\n return 50;\n case '3g':\n return 70;\n case '4g':\n case 'wifi':\n return highQuality;\n default:\n return highQuality; // unknown -> don't degrade unless you are sure\n }\n}\n\n","/**\n * Browser format detection utilities\n * Detects which image formats the browser supports\n */\n\nlet cachedFormat: string | null = null;\n\n/**\n * Detect the best image format supported by the browser\n * Priority: AVIF > WebP > JPEG\n * Uses synchronous detection for immediate results\n */\nexport function detectBestFormat(): string {\n if (cachedFormat !== null) {\n return cachedFormat;\n }\n\n if (typeof document === 'undefined' || typeof Image === 'undefined') {\n // Server-side or non-browser environment\n cachedFormat = 'webp';\n return cachedFormat;\n }\n\n // Synchronous detection using canvas.toDataURL\n try {\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n cachedFormat = 'webp';\n return cachedFormat;\n }\n\n // Test AVIF\n try {\n const avifDataURL = canvas.toDataURL('image/avif');\n if (avifDataURL && avifDataURL.indexOf('data:image/avif') === 0) {\n cachedFormat = 'avif';\n return cachedFormat;\n }\n } catch (e) {\n // AVIF not supported\n }\n\n // Test WebP\n try {\n const webpDataURL = canvas.toDataURL('image/webp');\n if (webpDataURL && webpDataURL.indexOf('data:image/webp') === 0) {\n cachedFormat = 'webp';\n return cachedFormat;\n }\n } catch (e) {\n // WebP not supported\n }\n\n // Fallback to JPEG\n cachedFormat = 'jpg';\n return cachedFormat;\n } catch (e) {\n // Fallback to WebP if detection fails\n cachedFormat = 'webp';\n return cachedFormat;\n }\n}\n\n\n/**\n * Get the best format synchronously (uses cached value or detects)\n */\nexport function getBestFormatSync(): string {\n if (cachedFormat !== null) {\n return cachedFormat;\n }\n return detectBestFormat();\n}\n\n/**\n * Reset cached format (useful for testing)\n */\nexport function resetFormatCache(): void {\n cachedFormat = null;\n}\n\n","/**\n * Transformation builder - converts TransformOptions to URL transformation string\n * with deterministic sorting\n */\n\nimport type { TransformOptions, LayerOptions } from './types';\nimport { getDPR, getQualityForConnection } from './device';\nimport { getBestFormatSync } from './format-detection';\n\ninterface TransformationPart {\n param: string;\n value: string;\n sortKey: string; // For deterministic sorting\n}\n\n/**\n * Build transformation string from options\n * Transformations are sorted alphabetically by param prefix\n */\nexport function buildTransformString(\n transform: TransformOptions,\n defaults?: { f?: string; q?: string | number; [key: string]: any },\n enableDPR: boolean = true,\n connectionQuality?: 'auto' | '2g' | '3g' | '4g' | 'wifi'\n): string {\n const parts: TransformationPart[] = [];\n \n // Helper to add transformation part\n const addPart = (param: string, value: string | number | boolean) => {\n if (value === undefined || value === null) return;\n \n let valueStr: string;\n if (typeof value === 'boolean') {\n valueStr = value ? '' : '';\n if (!value) return; // Skip false booleans\n } else {\n valueStr = String(value);\n }\n \n // Create sort key: param prefix determines order\n // Special handling: dpr_ should come early, but after basic size params\n let sortKey = param;\n if (param.startsWith('dpr_')) {\n sortKey = 'dpr_' + param; // Keep dpr early\n } else if (param.startsWith('a_')) {\n sortKey = 'a_' + param; // Text rotation\n } else if (param.startsWith('ar_')) {\n sortKey = 'ar_' + param;\n } else if (param.startsWith('bg_')) {\n sortKey = 'bg_' + param;\n } else if (param.startsWith('c_')) {\n sortKey = 'c_' + param;\n } else if (param.startsWith('co_')) {\n sortKey = 'co_' + param; // Text color\n } else if (param.startsWith('e_')) {\n sortKey = 'e_' + param;\n } else if (param.startsWith('f_')) {\n sortKey = 'f_' + param;\n } else if (param.startsWith('fl_')) {\n sortKey = 'fl_' + param;\n } else if (param.startsWith('fo_')) {\n sortKey = 'fo_' + param;\n } else if (param.startsWith('flip_')) {\n sortKey = 'flip_' + param;\n } else if (param.startsWith('h_')) {\n sortKey = 'h_' + param;\n } else if (param.startsWith('ip_')) {\n sortKey = 'ip_' + param; // Image layer placement\n } else if (param.startsWith('k_')) {\n sortKey = 'k_' + param;\n } else if (param.startsWith('l_')) {\n sortKey = 'l_' + param;\n } else if (param.startsWith('la_')) {\n sortKey = 'la_' + param;\n } else if (param.startsWith('lar_')) {\n sortKey = 'lar_' + param;\n } else if (param.startsWith('lbg_')) {\n sortKey = 'lbg_' + param;\n } else if (param.startsWith('lc_')) {\n sortKey = 'lc_' + param;\n } else if (param.startsWith('le_')) {\n sortKey = 'le_' + param;\n } else if (param.startsWith('lf_')) {\n sortKey = 'lf_' + param;\n } else if (param.startsWith('lflip_')) {\n sortKey = 'lflip_' + param;\n } else if (param.startsWith('lh_')) {\n sortKey = 'lh_' + param;\n } else if (param.startsWith('lp_')) {\n sortKey = 'lp_' + param;\n } else if (param.startsWith('lq_')) {\n sortKey = 'lq_' + param;\n } else if (param.startsWith('lr_')) {\n sortKey = 'lr_' + param;\n } else if (param.startsWith('ltype_')) {\n sortKey = 'ltype_' + param;\n } else if (param.startsWith('lw_')) {\n sortKey = 'lw_' + param;\n } else if (param.startsWith('lzoom_')) {\n sortKey = 'lzoom_' + param;\n } else if (param.startsWith('lbr_')) {\n sortKey = 'lbr_' + param;\n } else if (param.startsWith('o_')) {\n sortKey = 'o_' + param; // Opacity\n } else if (param.startsWith('p_')) {\n sortKey = 'p_' + param;\n } else if (param.startsWith('ps_')) {\n sortKey = 'ps_' + param;\n } else if (param.startsWith('q_')) {\n sortKey = 'q_' + param;\n } else if (param.startsWith('r_')) {\n sortKey = 'r_' + param;\n } else if (param.startsWith('tp_')) {\n sortKey = 'tp_' + param; // Text placement\n } else if (param.startsWith('w_')) {\n sortKey = 'w_' + param;\n } else if (param.startsWith('x_')) {\n sortKey = 'x_' + param;\n } else if (param.startsWith('y_')) {\n sortKey = 'y_' + param;\n } else if (param.startsWith('z_')) {\n sortKey = 'z_' + param;\n } else if (param.startsWith('br_')) {\n sortKey = 'br_' + param;\n }\n \n parts.push({ param, value: valueStr, sortKey });\n };\n \n // Size & Crop\n if (transform.w !== undefined) addPart('w_', transform.w);\n if (transform.h !== undefined) addPart('h_', transform.h);\n if (transform.fit) {\n const fitMap: Record<string, string> = {\n crop: 'crop',\n fill: 'fill',\n fit: 'fit',\n scale: 'scale'\n };\n addPart('c_', fitMap[transform.fit] || transform.fit);\n }\n if (transform.ar) addPart('ar_', transform.ar);\n if (transform.p) addPart('p_', transform.p);\n if (transform.ps) addPart('ps_', transform.ps);\n if (transform.focus) addPart('fo_', transform.focus);\n \n // Transform\n if (transform.r !== undefined) addPart('r_', transform.r);\n if (transform.z !== undefined) addPart('z_', transform.z);\n if (transform.flip) addPart('flip_', transform.flip);\n if (transform.br !== undefined) addPart('br_', transform.br);\n \n // Format & Quality\n let format = transform.f ?? defaults?.f;\n // If format is 'auto', detect browser support\n if (format === 'auto' || format === undefined) {\n format = getBestFormatSync();\n }\n if (format) addPart('f_', format);\n \n // Quality: use connection quality if auto, otherwise use transform or default\n let quality = transform.q;\n \n // If quality is explicitly set to a number, use it\n // If quality is 'auto' or undefined, resolve using connection quality\n if (quality === 'auto' || quality === undefined) {\n const defaultQuality = defaults?.q;\n \n // If transform doesn't specify quality, use default\n if (quality === undefined) {\n quality = defaultQuality;\n }\n \n // If quality is 'auto' (from transform or defaults), resolve using connection quality\n if (quality === 'auto' || quality === undefined) {\n if (connectionQuality) {\n // Resolve 'auto' to actual quality based on connection\n // connectionQuality is already resolved (not 'auto') when passed from createAR\n const resolvedQuality = getQualityForConnection(connectionQuality);\n quality = resolvedQuality;\n } else {\n // No connection info available, keep as 'auto'\n quality = 'auto';\n }\n }\n }\n // If quality is explicitly set to a number, use it as-is (no connection-based adjustment)\n \n if (quality !== undefined) addPart('q_', quality);\n \n // Background\n if (transform.bg) {\n if (transform.bg.startsWith('rgb:')) {\n addPart('bg_rgb:', transform.bg.replace('rgb:', ''));\n } else {\n addPart('bg_', transform.bg);\n }\n }\n \n // Kernel\n if (transform.k) addPart('k_', transform.k);\n \n // DPR (auto-inject if enabled and not explicitly set)\n if (enableDPR && transform.dpr === undefined) {\n const dpr = getDPR();\n if (dpr !== 1) addPart('dpr_', dpr);\n } else if (transform.dpr !== undefined) {\n addPart('dpr_', transform.dpr);\n }\n \n // Effects (e_*)\n if (transform.improve !== undefined) {\n if (typeof transform.improve === 'boolean' && transform.improve) {\n addPart('e_improve', '');\n } else if (typeof transform.improve === 'string') {\n addPart('e_improve', transform.improve);\n } else if (typeof transform.improve === 'object') {\n const { mode, blend } = transform.improve;\n let value = mode || '';\n if (blend !== undefined) value += `:${blend}`;\n addPart('e_improve', value);\n }\n }\n if (transform.unsharpMask !== undefined) addPart('e_unsharp_mask:', transform.unsharpMask);\n if (transform.saturation !== undefined) addPart('e_saturation:', transform.saturation);\n if (transform.contrast !== undefined) addPart('e_contrast:', transform.contrast);\n if (transform.brightness !== undefined) addPart('e_brightness:', transform.brightness);\n if (transform.gamma !== undefined) addPart('e_gamma:', transform.gamma);\n if (transform.sharpen !== undefined) {\n if (typeof transform.sharpen === 'boolean' && transform.sharpen) {\n addPart('e_sharpen', '');\n } else {\n addPart('e_sharpen:', transform.sharpen);\n }\n }\n if (transform.grayscale) addPart('e_grayscale', '');\n if (transform.blackwhite !== undefined) addPart('e_blackwhite:', transform.blackwhite);\n if (transform.hue !== undefined) addPart('e_hue:', transform.hue);\n if (transform.warmth !== undefined) addPart('e_warmth:', transform.warmth);\n if (transform.tint !== undefined) addPart('e_tint:', transform.tint);\n if (transform.normalize) addPart('e_normalize', '');\n if (transform.invert) addPart('e_invert', '');\n if (transform.fade !== undefined) addPart('e_fade:', transform.fade);\n if (transform.vignette !== undefined) addPart('e_vignette:', transform.vignette);\n if (transform.highlights !== undefined) addPart('e_highlights:', transform.highlights);\n if (transform.shadows !== undefined) addPart('e_shadows:', transform.shadows);\n if (transform.exposure !== undefined) addPart('e_exposure:', transform.exposure);\n if (transform.structure !== undefined) addPart('e_structure:', transform.structure);\n if (transform.autoEnhance) addPart('e_auto_enhance', '');\n if (transform.temperature !== undefined) addPart('e_temperature:', transform.temperature);\n if (transform.linear) addPart('e_linear:', transform.linear);\n if (transform.recomb) addPart('e_recomb:', transform.recomb);\n if (transform.threshold !== undefined) addPart('e_threshold:', transform.threshold);\n if (transform.convolve) addPart('e_convolve:', transform.convolve);\n if (transform.unflatten) addPart('e_unflatten', '');\n if (transform.flatten) addPart('e_flatten', '');\n if (transform.median !== undefined) addPart('e_median:', transform.median);\n if (transform.blur !== undefined) addPart('e_blur:', transform.blur);\n if (transform.extend) addPart('e_extend:', transform.extend);\n if (transform.affine) addPart('e_affine:', transform.affine);\n if (transform.extract) addPart('e_extract:', transform.extract);\n if (transform.ensureAlpha) addPart('e_ensure_alpha', '');\n if (transform.removeAlpha) addPart('e_remove_alpha:', transform.removeAlpha);\n \n // Blend mode (for layers)\n if (transform.blend) addPart('e_', transform.blend);\n \n // Raw transformations (for advanced users)\n Object.keys(transform).forEach(key => {\n if (key.startsWith('_') || \n ['w', 'h', 'fit', 'ar', 'p', 'ps', 'focus', 'r', 'z', 'flip', 'br', 'f', 'q', 'bg', 'k', 'dpr',\n 'improve', 'unsharpMask', 'saturation', 'contrast', 'brightness', 'gamma', 'sharpen',\n 'grayscale', 'blackwhite', 'hue', 'warmth', 'tint', 'normalize', 'invert', 'fade',\n 'vignette', 'highlights', 'shadows', 'exposure', 'structure', 'autoEnhance', 'temperature',\n 'linear', 'recomb', 'threshold', 'convolve', 'unflatten', 'flatten', 'median', 'blur',\n 'extend', 'affine', 'extract', 'ensureAlpha', 'removeAlpha', 'blend', 'layers'].includes(key)) {\n return; // Skip already processed keys\n }\n \n // Allow raw transformation strings\n if (typeof transform[key] === 'string' || typeof transform[key] === 'number' || typeof transform[key] === 'boolean') {\n addPart(key, transform[key] as any);\n }\n });\n \n // Sort base transformation parts deterministically by param prefix\n parts.sort((a, b) => {\n // Extract prefix for comparison\n const prefixA = a.param.split('_')[0] + '_';\n const prefixB = b.param.split('_')[0] + '_';\n \n if (prefixA !== prefixB) {\n return prefixA.localeCompare(prefixB);\n }\n \n // Same prefix, compare full param\n return a.param.localeCompare(b.param);\n });\n \n // Build base transformation string\n const baseTransform = parts.map(p => {\n if (p.value === '') {\n return p.param; // Boolean flags without values\n }\n return `${p.param}${p.value}`;\n }).join(',');\n \n // Build layers separately - each layer must end with fl_layer_apply\n const layerParts: string[] = [];\n if (transform.layers && transform.layers.length > 0) {\n transform.layers.forEach(layer => {\n const layerTransformParts: TransformationPart[] = [];\n \n const addLayerPart = (param: string, value: string | number | boolean) => {\n if (value === undefined || value === null) return;\n \n let valueStr: string;\n if (typeof value === 'boolean') {\n valueStr = value ? '' : '';\n if (!value) return; // Skip false booleans\n } else {\n valueStr = String(value);\n }\n \n layerTransformParts.push({\n param,\n value: valueStr,\n sortKey: param\n });\n };\n \n buildLayerTransform(layer, addLayerPart);\n \n // Sort layer parts with specific order (not alphabetical)\n // Order: l_image/l_text first, then ip_/tp_, then other params, then fl_layer_apply\n const applyFlag = layerTransformParts.find(p => p.param === 'fl_layer_apply');\n const regularParts = layerTransformParts.filter(p => p.param !== 'fl_layer_apply');\n \n // Define order priority for layer parameters\n const getLayerParamOrder = (param: string): number => {\n // l_image or l_text must be first\n if (param.startsWith('l_image:') || param.startsWith('l_text:')) return 0;\n // ip_ (image placement) or tp_ (text placement) comes right after l_image/l_text\n if (param.startsWith('ip_') || param.startsWith('tp_')) return 1;\n // l_type comes after placement\n if (param.startsWith('l_type:')) return 2;\n // lw_, lh_ come after l_type\n if (param.startsWith('lw_')) return 3;\n if (param.startsWith('lh_')) return 4;\n // o_ (opacity) comes after dimensions\n if (param.startsWith('o_')) return 5;\n // Other layer params\n if (param.startsWith('l')) return 6;\n // co_ (color) for text\n if (param.startsWith('co_')) return 7;\n // a_ (rotation) for text\n if (param.startsWith('a_')) return 8;\n // lr_ (rotation) for image\n if (param.startsWith('lr_')) return 8;\n // x_, y_ offsets\n if (param.startsWith('x_') || param.startsWith('y_')) return 9;\n // le_ (layer enhancements)\n if (param.startsWith('le_')) return 10;\n // e_ (blend mode)\n if (param.startsWith('e_')) return 11;\n // Everything else\n return 100;\n };\n \n regularParts.sort((a, b) => {\n const orderA = getLayerParamOrder(a.param);\n const orderB = getLayerParamOrder(b.param);\n \n if (orderA !== orderB) {\n return orderA - orderB;\n }\n \n // Same order priority, sort alphabetically\n return a.param.localeCompare(b.param);\n });\n \n // Build layer string: regular parts + fl_layer_apply at the end\n const layerString = [\n ...regularParts.map(p => p.value === '' ? p.param : `${p.param}${p.value}`),\n ...(applyFlag ? [applyFlag.param] : [])\n ].join(',');\n \n if (layerString) {\n layerParts.push(layerString);\n }\n });\n }\n \n // Combine: base transformations + layers\n const allParts = baseTransform ? [baseTransform, ...layerParts] : layerParts;\n return allParts.join(',');\n}\n\nfunction buildLayerTransform(layer: LayerOptions, addPart: (param: string, value: string | number | boolean) => void) {\n if (layer.type === 'text') {\n // Build text layer: l_text:fontFamily_fontSize_style:text\n // Example: l_text:arial_24_bold:Demo\n const parts: string[] = [];\n if (layer.fontFamily) parts.push(layer.fontFamily);\n if (layer.fontSize !== undefined) parts.push(String(layer.fontSize));\n if (layer.fontStyle) parts.push(layer.fontStyle);\n if (layer.align) parts.push(layer.align);\n \n const text = layer.text ? encodeURIComponent(layer.text) : '';\n const layerSpec = parts.length > 0 ? `${parts.join('_')}:${text}` : text;\n addPart('l_text:', layerSpec);\n \n // Text layer modifiers (after l_text)\n if (layer.fontColor) {\n // Remove # if present, convert to hex without #\n const color = layer.fontColor.replace('#', '');\n addPart('co_', color);\n }\n if (layer.placement) {\n // Convert placement to short form if needed\n const placement = normalizePlacement(layer.placement);\n if (placement) addPart('tp_', placement);\n }\n if (layer.rotation !== undefined) addPart('a_', layer.rotation);\n if (layer.x !== undefined) addPart('x_', layer.x);\n if (layer.y !== undefined) addPart('y_', layer.y);\n } else if (layer.type === 'image') {\n // Image layer: l_image:imagePath\n // Order: l_image, l_type, lw, lh, ip, o, fl_layer_apply\n // Example: l_image:fav.png,l_type:overlay,lw_200,lh_200,ip_ne,o_100,fl_layer_apply\n if (layer.imagePath) {\n addPart('l_image:', layer.imagePath);\n }\n \n // Image layer modifiers in correct order\n if (layer.layerType) addPart('l_type:', layer.layerType);\n if (layer.width !== undefined) addPart('lw_', layer.width);\n if (layer.height !== undefined) addPart('lh_', layer.height);\n if (layer.placement) {\n // Convert placement to short form if needed\n const placement = normalizePlacement(layer.placement);\n if (placement) addPart('ip_', placement);\n }\n if (layer.opacity !== undefined) addPart('o_', layer.opacity);\n if (layer.rotation !== undefined) addPart('lr_', layer.rotation);\n if (layer.crop) addPart('lc_', layer.crop);\n if (layer.aspectRatio) addPart('lar_', layer.aspectRatio);\n if (layer.quality !== undefined) addPart('lq_', layer.quality);\n if (layer.format) addPart('lf_', layer.format);\n if (layer.background) addPart('lbg_', layer.background);\n if (layer.position) addPart('lp_', layer.position);\n if (layer.borderRadius !== undefined) addPart('lbr_', layer.borderRadius);\n if (layer.flip) addPart('lflip_', layer.flip);\n if (layer.zoom !== undefined) addPart('lzoom_', layer.zoom);\n if (layer.x !== undefined) addPart('x_', layer.x);\n if (layer.y !== undefined) addPart('y_', layer.y);\n if (layer.blendMode) addPart('e_', layer.blendMode);\n \n // Layer enhancements (le_*)\n if (layer.enhance) {\n const enhance = layer.enhance;\n if (enhance.improve !== undefined) {\n if (typeof enhance.improve === 'boolean' && enhance.improve) {\n addPart('le_improve', '');\n } else if (typeof enhance.improve === 'string') {\n addPart('le_improve', enhance.improve);\n }\n }\n if (enhance.sharpen !== undefined) addPart('le_sharpen:', enhance.sharpen);\n if (enhance.brightness !== undefined) addPart('le_brightness:', enhance.brightness);\n if (enhance.saturation !== undefined) addPart('le_saturation:', enhance.saturation);\n if (enhance.contrast !== undefined) addPart('le_contrast:', enhance.contrast);\n if (enhance.hue !== undefined) addPart('le_hue:', enhance.hue);\n if (enhance.warmth !== undefined) addPart('le_warmth:', enhance.warmth);\n if (enhance.tint !== undefined) addPart('le_tint:', enhance.tint);\n if (enhance.normalize) addPart('le_normalize', '');\n if (enhance.invert) addPart('le_invert', '');\n if (enhance.fade !== undefined) addPart('le_fade:', enhance.fade);\n if (enhance.vignette !== undefined) addPart('le_vignette:', enhance.vignette);\n if (enhance.highlights !== undefined) addPart('le_highlights:', enhance.highlights);\n if (enhance.shadows !== undefined) addPart('le_shadows:', enhance.shadows);\n if (enhance.exposure !== undefined) addPart('le_exposure:', enhance.exposure);\n if (enhance.structure !== undefined) addPart('le_structure:', enhance.structure);\n if (enhance.autoEnhance) addPart('le_auto_enhance', '');\n if (enhance.temperature !== undefined) addPart('le_temperature:', enhance.temperature);\n if (enhance.blackwhite !== undefined) addPart('le_blackwhite:', enhance.blackwhite);\n if (enhance.gamma !== undefined) addPart('le_gamma:', enhance.gamma);\n if (enhance.unsharpMask !== undefined) addPart('le_unsharp_mask:', enhance.unsharpMask);\n if (enhance.grayscale) addPart('le_grayscale', '');\n }\n }\n \n // Layer apply flag (always at the end)\n addPart('fl_layer_apply', '');\n}\n\n/**\n * Normalize placement values to short form\n * north -> n, north-east -> ne, etc.\n */\nfunction normalizePlacement(placement: string): string {\n const mapping: Record<string, string> = {\n 'north': 'n',\n 'south': 's',\n 'east': 'e',\n 'west': 'w',\n 'center': 'c',\n 'north-west': 'nw',\n 'north-east': 'ne',\n 'south-west': 'sw',\n 'south-east': 'se',\n 'none': 'none'\n };\n return mapping[placement.toLowerCase()] || placement.toLowerCase();\n}\n\n","/**\n * URL builder for AutoRender image URLs\n */\n\nimport { buildTransformString } from './transform';\nimport type { TransformOptions } from './types';\n\nexport function buildImageUrl(\n baseUrl: string,\n workspace: string,\n src: string,\n transform?: TransformOptions,\n defaults?: { f?: string; q?: string | number; [key: string]: any },\n enableDPR: boolean = true,\n connectionQuality?: 'auto' | '2g' | '3g' | '4g' | 'wifi'\n): string {\n // Normalize base URL (remove trailing slashes)\n const normalizedBase = baseUrl.replace(/\\/+$/, '');\n \n // Build transformation string\n const transformStr = buildTransformString(transform || {}, defaults, enableDPR, connectionQuality);\n \n // Encode file path safely (encode each segment separately)\n const encodedPath = src\n .split('/')\n .filter(Boolean)\n .map(segment => encodeURIComponent(segment))\n .join('/');\n \n // Build URL: baseUrl/workspace/transformations/file_path\n if (transformStr) {\n return `${normalizedBase}/${workspace}/${transformStr}/${encodedPath}`;\n } else {\n return `${normalizedBase}/${workspace}/${encodedPath}`;\n }\n}\n\n","/**\n * Responsive image attributes generator\n * Implements three strategies based on input options\n */\n\nimport { buildImageUrl } from './url-builder';\nimport type { ResponsiveOptions, ResponsiveAttributes, TransformOptions } from './types';\nimport { getDPR } from './device';\n\nconst DEFAULT_DEVICE_BREAKPOINTS = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];\nconst DEFAULT_IMAGE_BREAKPOINTS = [16, 32, 48, 64, 96, 128, 256, 384];\n\n/**\n * Parse sizes attribute to extract minimum viewport width\n * Returns the smallest vw value found, or null if none found\n */\nfunction parseMinVWFromSizes(sizes: string): number | null {\n // Match patterns like \"33vw\", \"100vw\", \"(min-width: 800px) 33vw\"\n const vwMatches = sizes.match(/(\\d+(?:\\.\\d+)?)vw/g);\n if (!vwMatches || vwMatches.length === 0) return null;\n \n const vwValues = vwMatches.map(m => parseFloat(m));\n return Math.min(...vwValues);\n}\n\n/**\n * Find nearest breakpoint to a given width\n */\nfunction findNearestBreakpoint(width: number, breakpoints: number[]): number {\n return breakpoints.reduce((prev, curr) => {\n return Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev;\n });\n}\n\n/**\n * Generate responsive image attributes\n * \n * Rule 1: width only → DPR strategy (1x and 2x)\n * Rule 2: sizes provided → width-based strategy\n * Rule 3: neither → all device breakpoints\n */\nexport function generateResponsiveAttributes(\n baseUrl: string,\n workspace: string,\n options: ResponsiveOptions,\n defaults?: { f?: string; q?: string | number; [key: string]: any },\n deviceBreakpoints: number[] = DEFAULT_DEVICE_BREAKPOINTS,\n imageBreakpoints: number[] = DEFAULT_IMAGE_BREAKPOINTS,\n enableDPR: boolean = true,\n connectionQuality?: 'auto' | '2g' | '3g' | '4g' | 'wifi'\n): ResponsiveAttributes {\n const { src, width, sizes, transform, breakpoints } = options;\n \n // Use custom breakpoints if provided, otherwise use defaults\n const effectiveBreakpoints = breakpoints || deviceBreakpoints;\n \n // Rule 1: width only → DPR strategy\n if (width !== undefined && !sizes) {\n const dpr = enableDPR ? getDPR() : 1;\n const baseWidth = width;\n \n // Generate 1x and 2x URLs\n const srcSetParts: string[] = [];\n \n // 1x URL\n const transform1x: TransformOptions = {\n ...transform,\n w: baseWidth,\n dpr: 1\n };\n const url1x = buildImageUrl(baseUrl, workspace, src, transform1x, defaults, false, connectionQuality);\n srcSetParts.push(`${url1x} 1x`);\n \n // 2x URL (only if device DPR is actually >= 2)\n if (dpr >= 2) {\n const transform2x: TransformOptions = {\n ...transform,\n w: baseWidth,\n dpr: 2\n };\n const url2x = buildImageUrl(baseUrl, workspace, src, transform2x, defaults, false, connectionQuality);\n srcSetParts.push(`${url2x} 2x`);\n }\n \n // Base URL (1x)\n const baseTransform: TransformOptions = {\n ...transform,\n w: baseWidth\n };\n const baseSrc = buildImageUrl(baseUrl, workspace, src, baseTransform, defaults, enableDPR, connectionQuality);\n \n return {\n src: baseSrc,\n srcSet: srcSetParts.join(', '),\n width: baseWidth\n };\n }\n \n // Rule 2: sizes provided → width-based strategy\n if (sizes) {\n const minVW = parseMinVWFromSizes(sizes);\n \n // Filter breakpoints: only include those >= minimum required width\n // If we have a viewport width, calculate minimum pixel width needed\n // For simplicity, we'll use all breakpoints that make sense\n // In practice, you'd calculate based on viewport width\n const filteredBreakpoints = effectiveBreakpoints.filter(bp => {\n // Include all breakpoints for now\n // Could be optimized based on minVW calculation\n return true;\n });\n \n // Generate srcset with w descriptors\n const srcSetParts = filteredBreakpoints.map(bp => {\n const transformWithWidth: TransformOptions = {\n ...transform,\n w: bp\n };\n const url = buildImageUrl(baseUrl, workspace, src, transformWithWidth, defaults, enableDPR, connectionQuality);\n return `${url} ${bp}w`;\n });\n \n // Base URL (use smallest breakpoint or provided width)\n const baseWidth = width || filteredBreakpoints[0] || effectiveBreakpoints[0];\n const baseTransform: TransformOptions = {\n ...transform,\n w: baseWidth\n };\n const baseSrc = buildImageUrl(baseUrl, workspace, src, baseTransform, defaults, enableDPR, connectionQuality);\n \n return {\n src: baseSrc,\n srcSet: srcSetParts.join(', '),\n sizes: sizes,\n width: baseWidth\n };\n }\n \n // Rule 3: neither width nor sizes → all device breakpoints\n // Use all breakpoints with w descriptors\n const srcSetParts = effectiveBreakpoints.map(bp => {\n const transformWithWidth: TransformOptions = {\n ...transform,\n w: bp\n };\n const url = buildImageUrl(baseUrl, workspace, src, transformWithWidth, defaults, enableDPR, connectionQuality);\n return `${url} ${bp}w`;\n });\n \n // Base URL (use smallest breakpoint)\n const baseWidth = effectiveBreakpoints[0];\n const baseTransform: TransformOptions = {\n ...transform,\n w: baseWidth\n };\n const baseSrc = buildImageUrl(baseUrl, workspace, src, baseTransform, defaults, enableDPR, connectionQuality);\n \n return {\n src: baseSrc,\n srcSet: srcSetParts.join(', '),\n sizes: '100vw',\n width: baseWidth\n };\n}\n\n","/**\n * Main AutoRender client factory\n * Creates an AR instance with URL building and responsive image capabilities\n */\n\nimport { buildImageUrl } from './url-builder';\nimport { buildTransformString } from './transform';\nimport { generateResponsiveAttributes } from './responsive';\nimport { getDPR, getConnectionQuality } from './device';\nimport type {\n CreateARConfig,\n ARInstance,\n TransformOptions,\n ResponsiveOptions,\n ResponsiveAttributes\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://assets.autorender.io';\nconst DEFAULT_DEVICE_BREAKPOINTS = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];\nconst DEFAULT_IMAGE_BREAKPOINTS = [16, 32, 48, 64, 96, 128, 256, 384];\n\nexport function createAR(config: CreateARConfig): ARInstance {\n const {\n baseUrl = DEFAULT_BASE_URL,\n workspace,\n defaults = {},\n deviceBreakpoints = DEFAULT_DEVICE_BREAKPOINTS,\n imageBreakpoints = DEFAULT_IMAGE_BREAKPOINTS,\n enableDPR = true,\n connectionQuality: configConnectionQuality = 'auto'\n } = config;\n \n if (!workspace) {\n throw new Error('workspace is required');\n }\n \n // Normalize defaults - preserve 'auto' for q if not explicitly set\n const normalizedDefaults = {\n f: defaults.f || 'auto',\n q: defaults.q !== undefined ? defaults.q : 'auto',\n ...defaults\n };\n \n // Get connection quality for quality adjustment\n // If configConnectionQuality is 'auto', detect from browser\n // Otherwise, use the provided value directly\n const effectiveConnectionQuality: '2g' | '3g' | '4g' | 'wifi' = \n configConnectionQuality === 'auto' \n ? (() => {\n const detected = getConnectionQuality();\n console.log('detected', detected);\n return detected === 'unknown' ? 'wifi' : detected;\n })()\n : configConnectionQuality;\n \n const instance: ARInstance = {\n /**\n * Generate image URL with transformations\n */\n url(src: string, transform?: TransformOptions): string {\n return buildImageUrl(\n baseUrl,\n workspace,\n src,\n transform,\n normalizedDefaults,\n enableDPR,\n effectiveConnectionQuality\n );\n },\n \n /**\n * Generate transformation string only (without URL)\n */\n transformString(transform: TransformOptions): string {\n return buildTransformString(\n transform,\n normalizedDefaults,\n enableDPR,\n effectiveConnectionQuality\n );\n },\n \n /**\n * Generate responsive image attributes\n */\n responsiveImageAttributes(options: ResponsiveOptions): ResponsiveAttributes {\n // Allow per-call breakpoint override\n const effectiveDeviceBreakpoints = options.breakpoints || deviceBreakpoints;\n \n return generateResponsiveAttributes(\n baseUrl,\n workspace,\n options,\n normalizedDefaults,\n effectiveDeviceBreakpoints,\n imageBreakpoints,\n enableDPR,\n effectiveConnectionQuality\n );\n },\n \n /**\n * Get current device pixel ratio\n */\n getDPR(): number {\n return getDPR();\n },\n \n /**\n * Get current connection quality\n */\n getConnectionQuality(): '2g' | '3g' | '4g' | 'wifi' | 'unknown' {\n return getConnectionQuality();\n }\n };\n \n return instance;\n}\n\n"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["item","message","containerStyle","baseWidth","srcSetParts","baseTransform","baseSrc","DEFAULT_BASE_URL","DEFAULT_DEVICE_BREAKPOINTS","DEFAULT_IMAGE_BREAKPOINTS"]}