@primestyleai/tryon 5.10.193 → 5.10.195
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PrimeStyleTryon.d.ts +5 -0
- package/dist/api-client.d.ts +30 -1
- package/dist/{index-D9sdGV4C.js → index-D_9-KLXy.js} +198 -142
- package/dist/index-D_9-KLXy.js.map +1 -0
- package/dist/primestyle-tryon.js +232 -164
- package/dist/primestyle-tryon.js.map +1 -1
- package/dist/react/index.js +6010 -5609
- package/dist/react/index.js.map +1 -1
- package/dist/react/recommendForProduct.d.ts +4 -4
- package/dist/react/styles.d.ts +1 -1
- package/dist/react/usePrimeStyleSize.d.ts +2 -2
- package/dist/react/views/SizeResultView.d.ts +2 -1
- package/dist/storefront/primestyle-tryon.js +683 -201
- package/package.json +1 -1
- package/dist/index-D9sdGV4C.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primestyle-tryon.js","sources":["../src/product-detector.ts","../src/styles.ts","../src/PrimeStyleTryon.ts","../src/index.ts"],"sourcesContent":["/** Attempts to auto-detect the main product image on the current page. */\nexport function detectProductImage(): string | null {\n // 1. OG image meta tag\n const ogImage = document.querySelector<HTMLMetaElement>(\n 'meta[property=\"og:image\"]'\n );\n if (ogImage?.content) return ogImage.content;\n\n // 2. Schema.org Product JSON-LD\n const jsonLdScripts = document.querySelectorAll<HTMLScriptElement>(\n 'script[type=\"application/ld+json\"]'\n );\n for (const script of jsonLdScripts) {\n try {\n const data = JSON.parse(script.textContent || \"\");\n const image = extractSchemaImage(data);\n if (image) return image;\n } catch {\n // ignore invalid JSON-LD\n }\n }\n\n // 3. Common product image selectors\n const selectors = [\n \"[data-product-image] img\",\n \"[data-product-image]\",\n \".product-image img\",\n \".product-gallery img\",\n \"#product-image\",\n \".product__media img\",\n \".product-single__photo img\",\n \".woocommerce-product-gallery img\",\n \".product-media img\",\n ];\n\n for (const selector of selectors) {\n const el = document.querySelector<HTMLImageElement>(selector);\n if (el) {\n const src = el.src || el.dataset.src || el.dataset.zoom;\n if (src) return src;\n }\n }\n\n return null;\n}\n\nfunction extractSchemaImage(data: unknown): string | null {\n if (!data || typeof data !== \"object\") return null;\n\n if (Array.isArray(data)) {\n for (const item of data) {\n const result = extractSchemaImage(item);\n if (result) return result;\n }\n return null;\n }\n\n const obj = data as Record<string, unknown>;\n\n if (\n obj[\"@type\"] === \"Product\" ||\n obj[\"@type\"] === \"IndividualProduct\"\n ) {\n const image = obj.image;\n if (typeof image === \"string\") return image;\n if (Array.isArray(image) && typeof image[0] === \"string\") return image[0];\n if (image && typeof image === \"object\") {\n const imgObj = image as Record<string, unknown>;\n if (typeof imgObj.url === \"string\") return imgObj.url;\n if (typeof imgObj.contentUrl === \"string\") return imgObj.contentUrl;\n }\n }\n\n // Check @graph\n if (Array.isArray(obj[\"@graph\"])) {\n return extractSchemaImage(obj[\"@graph\"]);\n }\n\n return null;\n}\n","export function getStyles(): string {\n return `\n :host {\n display: inline-block;\n --ps-primary: #bb945c;\n --ps-primary-hover: #a07d4e;\n --ps-text: #ffffff;\n --ps-text-secondary: #999999;\n --ps-bg: #111211;\n --ps-bg-secondary: #1a1b1a;\n --ps-border: #333333;\n --ps-radius: 12px;\n --ps-font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --ps-overlay: rgba(0, 0, 0, 0.6);\n --ps-error: #ef4444;\n --ps-success: #22c55e;\n }\n\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ── Button ─────────────────────────────── */\n .ps-button {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: var(--ps-btn-padding, 12px 24px);\n background: var(--ps-btn-bg, var(--ps-primary));\n color: var(--ps-btn-color, #111211);\n font-family: var(--ps-btn-font, var(--ps-font));\n font-size: var(--ps-btn-font-size, 14px);\n font-weight: var(--ps-btn-font-weight, 600);\n border: var(--ps-btn-border, none);\n border-radius: var(--ps-btn-radius, 8px);\n cursor: pointer;\n transition: all 0.2s ease;\n width: var(--ps-btn-width, auto);\n height: var(--ps-btn-height, auto);\n box-shadow: var(--ps-btn-shadow, none);\n line-height: 1;\n white-space: nowrap;\n }\n\n .ps-button:hover {\n background: var(--ps-btn-hover-bg, var(--ps-primary-hover));\n color: var(--ps-btn-hover-color, var(--ps-btn-color, #111211));\n transform: translateY(-1px);\n }\n\n .ps-button:active {\n transform: translateY(0);\n }\n\n .ps-button svg {\n width: var(--ps-btn-icon-size, 18px);\n height: var(--ps-btn-icon-size, 18px);\n fill: none;\n stroke: var(--ps-btn-icon-color, currentColor);\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n\n /* ── Modal Overlay ──────────────────────── */\n .ps-overlay {\n position: fixed;\n inset: 0;\n background: var(--ps-modal-overlay, var(--ps-overlay));\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.25s ease, visibility 0.25s ease;\n padding: 16px;\n }\n\n .ps-overlay.ps-open {\n opacity: 1;\n visibility: visible;\n }\n\n /* ── Modal ──────────────────────────────── */\n .ps-modal {\n background: var(--ps-modal-bg, var(--ps-bg));\n color: var(--ps-modal-color, var(--ps-text));\n border-radius: var(--ps-modal-radius, var(--ps-radius));\n width: var(--ps-modal-width, 100%);\n max-width: var(--ps-modal-max-width, 480px);\n max-height: 90vh;\n overflow-y: auto;\n font-family: var(--ps-modal-font, var(--ps-font));\n position: relative;\n transform: translateY(20px) scale(0.97);\n transition: transform 0.25s ease;\n box-shadow: 0 25px 50px rgba(0, 0, 0, 0.4);\n }\n\n .ps-open .ps-modal {\n transform: translateY(0) scale(1);\n }\n\n /* ── Modal Header ───────────────────────── */\n .ps-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--ps-modal-header-bg, var(--ps-bg-secondary));\n border-bottom: 1px solid var(--ps-border);\n border-radius: var(--ps-modal-radius, var(--ps-radius)) var(--ps-modal-radius, var(--ps-radius)) 0 0;\n }\n\n .ps-header-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--ps-modal-header-color, var(--ps-text));\n }\n\n .ps-close {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n color: var(--ps-modal-close-color, var(--ps-text-secondary));\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s;\n }\n\n .ps-close:hover {\n background: rgba(255, 255, 255, 0.1);\n }\n\n .ps-close svg {\n width: 20px;\n height: 20px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n /* ── Modal Body ─────────────────────────── */\n .ps-body {\n padding: 24px;\n }\n\n /* ── Upload Zone ─────────────────────────── */\n .ps-upload-zone {\n border: 2px dashed var(--ps-upload-border, var(--ps-border));\n border-radius: var(--ps-radius);\n padding: 40px 24px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s ease;\n background: var(--ps-upload-bg, transparent);\n }\n\n .ps-upload-zone:hover,\n .ps-upload-zone.ps-drag-over {\n border-color: var(--ps-primary);\n background: rgba(187, 148, 92, 0.05);\n }\n\n .ps-upload-zone input {\n display: none;\n }\n\n .ps-upload-icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 12px;\n stroke: var(--ps-upload-icon-color, var(--ps-primary));\n fill: none;\n stroke-width: 1.5;\n }\n\n .ps-upload-text {\n font-size: 14px;\n color: var(--ps-upload-color, var(--ps-text));\n margin-bottom: 4px;\n }\n\n .ps-upload-hint {\n font-size: 12px;\n color: var(--ps-text-secondary);\n }\n\n /* ── Preview ────────────────────────────── */\n .ps-preview {\n margin-top: 16px;\n position: relative;\n }\n\n .ps-preview img {\n width: 100%;\n border-radius: var(--ps-radius);\n display: block;\n }\n\n .ps-preview-remove {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n border: none;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n }\n\n .ps-preview-remove:hover {\n background: rgba(0, 0, 0, 0.8);\n }\n\n /* ── Submit Button ──────────────────────── */\n .ps-submit {\n width: 100%;\n padding: 14px;\n margin-top: 20px;\n background: var(--ps-modal-primary-bg, var(--ps-primary));\n color: var(--ps-modal-primary-color, #111211);\n font-family: var(--ps-modal-font, var(--ps-font));\n font-size: 14px;\n font-weight: 600;\n border: none;\n border-radius: var(--ps-modal-primary-radius, 8px);\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n }\n\n .ps-submit:hover:not(:disabled) {\n opacity: 0.9;\n transform: translateY(-1px);\n }\n\n .ps-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* ── Processing State ───────────────────── */\n .ps-processing {\n text-align: center;\n padding: 40px 24px;\n }\n\n .ps-spinner {\n width: 48px;\n height: 48px;\n border: 3px solid var(--ps-border);\n border-top-color: var(--ps-loader, var(--ps-primary));\n border-radius: 50%;\n animation: ps-spin 0.8s linear infinite;\n margin: 0 auto 16px;\n }\n\n @keyframes ps-spin {\n to { transform: rotate(360deg); }\n }\n\n .ps-processing-text {\n font-size: 14px;\n color: var(--ps-text);\n margin-bottom: 4px;\n }\n\n .ps-processing-sub {\n font-size: 12px;\n color: var(--ps-text-secondary);\n }\n\n /* ── Result ─────────────────────────────── */\n .ps-result {\n text-align: center;\n }\n\n .ps-result img {\n width: 100%;\n border-radius: var(--ps-result-radius, var(--ps-radius));\n display: block;\n margin-bottom: 16px;\n }\n\n .ps-result-actions {\n display: flex;\n gap: 8px;\n }\n\n .ps-result-actions button {\n flex: 1;\n padding: 12px;\n font-family: var(--ps-modal-font, var(--ps-font));\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n border: none;\n }\n\n .ps-btn-download {\n background: var(--ps-primary);\n color: #111211;\n }\n\n .ps-btn-download:hover {\n opacity: 0.9;\n }\n\n .ps-btn-retry {\n background: rgba(255, 255, 255, 0.1);\n color: var(--ps-text);\n border: 1px solid var(--ps-border) !important;\n }\n\n .ps-btn-retry:hover {\n background: rgba(255, 255, 255, 0.15);\n }\n\n /* ── Error State ────────────────────────── */\n .ps-error {\n text-align: center;\n padding: 24px;\n }\n\n .ps-error-icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 12px;\n stroke: var(--ps-error);\n fill: none;\n stroke-width: 1.5;\n }\n\n .ps-error-text {\n font-size: 14px;\n color: var(--ps-error);\n margin-bottom: 16px;\n }\n\n /* ── Powered By ─────────────────────────── */\n .ps-powered {\n text-align: center;\n padding: 12px 24px 16px;\n font-size: 11px;\n color: var(--ps-text-secondary);\n }\n\n .ps-powered a {\n color: var(--ps-primary);\n text-decoration: none;\n }\n\n .ps-powered a:hover {\n text-decoration: underline;\n }\n `;\n}\n","import { ApiClient } from \"./api-client\";\nimport { SseClient } from \"./sse-client\";\nimport { detectProductImage } from \"./product-detector\";\nimport { compressImage, isValidImageFile } from \"./image-utils\";\nimport { getStyles } from \"./styles\";\nimport type { ButtonStyles, ModalStyles, VtoUpdate } from \"./types\";\nimport { createT, type TranslateFn } from \"./i18n\";\n\ntype ViewState = \"idle\" | \"upload\" | \"processing\" | \"result\" | \"error\";\n\n// SVG icons as template strings\nconst ICONS = {\n camera: `<svg viewBox=\"0 0 24 24\"><path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\"/><circle cx=\"12\" cy=\"13\" r=\"4\"/></svg>`,\n upload: `<svg viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/></svg>`,\n x: `<svg viewBox=\"0 0 24 24\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`,\n alert: `<svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/></svg>`,\n};\n\nexport class PrimeStyleTryon extends HTMLElement {\n private shadow: ShadowRoot;\n private apiClient: ApiClient | null = null;\n private sseClient: SseClient | null = null;\n private sseUnsubscribe: (() => void) | null = null;\n\n private state: ViewState = \"idle\";\n private selectedFile: File | null = null;\n private previewUrl: string | null = null;\n private resultImageUrl: string | null = null;\n private errorMessage: string | null = null;\n private currentJobId: string | null = null;\n private productImageUrl: string | null = null;\n\n // i18n\n private t: TranslateFn = createT();\n\n // Custom style configs\n private buttonStyles: ButtonStyles = {};\n private modalStyles: ModalStyles = {};\n\n static get observedAttributes(): string[] {\n return [\n \"api-key\",\n \"api-url\",\n \"product-image\",\n \"button-text\",\n \"locale\",\n \"show-powered-by\",\n \"button-styles\",\n \"modal-styles\",\n ];\n }\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: \"open\" });\n }\n\n connectedCallback(): void {\n this.init();\n this.render();\n }\n\n disconnectedCallback(): void {\n this.cleanup();\n }\n\n attributeChangedCallback(name: string, _old: string, val: string): void {\n if (name === \"api-key\" || name === \"api-url\") {\n this.initApi();\n }\n if (name === \"locale\") {\n this.t = createT(val || undefined);\n }\n if (name === \"product-image\") {\n this.productImageUrl = val;\n }\n if (name === \"button-styles\") {\n try { this.buttonStyles = JSON.parse(val); } catch { /* ignore */ }\n }\n if (name === \"modal-styles\") {\n try { this.modalStyles = JSON.parse(val); } catch { /* ignore */ }\n }\n if (this.isConnected) this.render();\n }\n\n // ── Public API ──────────────────────────────\n\n /** Configure button appearance programmatically */\n setButtonStyles(styles: ButtonStyles): void {\n this.buttonStyles = { ...this.buttonStyles, ...styles };\n this.applyButtonStyles();\n }\n\n /** Configure modal appearance programmatically */\n setModalStyles(styles: ModalStyles): void {\n this.modalStyles = { ...this.modalStyles, ...styles };\n this.applyModalStyles();\n }\n\n private savedScrollY = 0;\n\n private lockBodyScroll(): void {\n this.savedScrollY = window.scrollY;\n document.body.style.overflow = \"hidden\";\n document.body.style.position = \"fixed\";\n document.body.style.top = `-${this.savedScrollY}px`;\n document.body.style.left = \"0\";\n document.body.style.right = \"0\";\n }\n\n private unlockBodyScroll(): void {\n document.body.style.overflow = \"\";\n document.body.style.position = \"\";\n document.body.style.top = \"\";\n document.body.style.left = \"\";\n document.body.style.right = \"\";\n window.scrollTo(0, this.savedScrollY);\n }\n\n /** Open the try-on modal */\n open(): void {\n this.state = \"upload\";\n this.lockBodyScroll();\n this.render();\n this.emit(\"ps:open\");\n }\n\n /** Close the try-on modal */\n close(): void {\n this.state = \"idle\";\n this.unlockBodyScroll();\n this.resetUpload();\n this.render();\n this.emit(\"ps:close\");\n }\n\n /** Detect product image from the current page */\n detectProduct(): string | null {\n const image = detectProductImage();\n if (image) {\n this.productImageUrl = image;\n this.emit(\"ps:product-detected\", { imageUrl: image });\n }\n return image;\n }\n\n // ── Private ─────────────────────────────────\n\n private init(): void {\n // Parse attribute-based styles\n const btnStylesAttr = this.getAttribute(\"button-styles\");\n if (btnStylesAttr) {\n try { this.buttonStyles = JSON.parse(btnStylesAttr); } catch { /* ignore */ }\n }\n const modalStylesAttr = this.getAttribute(\"modal-styles\");\n if (modalStylesAttr) {\n try { this.modalStyles = JSON.parse(modalStylesAttr); } catch { /* ignore */ }\n }\n\n // Init locale\n const localeAttr = this.getAttribute(\"locale\");\n if (localeAttr) this.t = createT(localeAttr);\n\n this.productImageUrl = this.getAttribute(\"product-image\") || null;\n\n // Auto-detect product image if not provided\n if (!this.productImageUrl) {\n this.productImageUrl = detectProductImage();\n if (this.productImageUrl) {\n this.emit(\"ps:product-detected\", { imageUrl: this.productImageUrl });\n }\n }\n\n this.initApi();\n }\n\n private initApi(): void {\n const apiKey = this.getAttribute(\"api-key\") || undefined;\n const apiUrl = this.getAttribute(\"api-url\") || undefined;\n this.apiClient = new ApiClient(apiKey, apiUrl);\n this.sseClient = new SseClient(this.apiClient.getStreamUrl());\n }\n\n private cleanup(): void {\n if (this.state !== \"idle\") {\n this.unlockBodyScroll();\n }\n if (this.sseUnsubscribe) {\n this.sseUnsubscribe();\n this.sseUnsubscribe = null;\n }\n if (this.sseClient) {\n this.sseClient.disconnect();\n this.sseClient = null;\n }\n if (this.previewUrl) {\n URL.revokeObjectURL(this.previewUrl);\n }\n }\n\n private emit(name: string, detail?: unknown): void {\n this.dispatchEvent(\n new CustomEvent(name, { bubbles: true, composed: true, detail })\n );\n }\n\n private get buttonText(): string {\n return this.getAttribute(\"button-text\") || this.t(\"Virtual Try-On\");\n }\n\n private get showPoweredBy(): boolean {\n const attr = this.getAttribute(\"show-powered-by\");\n return attr !== \"false\";\n }\n\n // ── Rendering ───────────────────────────────\n\n private render(): void {\n this.shadow.innerHTML = \"\";\n\n const style = document.createElement(\"style\");\n style.textContent = getStyles();\n this.shadow.appendChild(style);\n\n // Button (always visible)\n const button = this.createButton();\n this.shadow.appendChild(button);\n\n // Modal overlay\n if (this.state !== \"idle\") {\n const overlay = this.createModal();\n this.shadow.appendChild(overlay);\n // Trigger open animation\n requestAnimationFrame(() => overlay.classList.add(\"ps-open\"));\n }\n\n this.applyButtonStyles();\n this.applyModalStyles();\n }\n\n private createButton(): HTMLButtonElement {\n const btn = document.createElement(\"button\");\n btn.className = \"ps-button\";\n btn.innerHTML = `${ICONS.camera}<span>${this.buttonText}</span>`;\n btn.addEventListener(\"click\", () => this.open());\n return btn;\n }\n\n private createModal(): HTMLDivElement {\n const overlay = document.createElement(\"div\");\n overlay.className = \"ps-overlay\";\n overlay.addEventListener(\"click\", (e) => {\n if (e.target === overlay) this.close();\n });\n\n const modal = document.createElement(\"div\");\n modal.className = \"ps-modal\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"ps-header\";\n header.innerHTML = `\n <span class=\"ps-header-title\">${this.t(\"Virtual Try-On\")}</span>\n `;\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"ps-close\";\n closeBtn.innerHTML = ICONS.x;\n closeBtn.addEventListener(\"click\", () => this.close());\n header.appendChild(closeBtn);\n modal.appendChild(header);\n\n // Body\n const body = document.createElement(\"div\");\n body.className = \"ps-body\";\n\n switch (this.state) {\n case \"upload\":\n body.appendChild(this.createUploadView());\n break;\n case \"processing\":\n body.appendChild(this.createProcessingView());\n break;\n case \"result\":\n body.appendChild(this.createResultView());\n break;\n case \"error\":\n body.appendChild(this.createErrorView());\n break;\n }\n\n modal.appendChild(body);\n\n // Powered by\n if (this.showPoweredBy) {\n const powered = document.createElement(\"div\");\n powered.className = \"ps-powered\";\n powered.innerHTML = `${this.t(\"Powered by\")} <a href=\"https://myaifitting.com\" target=\"_blank\" rel=\"noopener\">PrimeStyle AI</a>`;\n modal.appendChild(powered);\n }\n\n overlay.appendChild(modal);\n return overlay;\n }\n\n private createUploadView(): DocumentFragment {\n const frag = document.createDocumentFragment();\n\n if (this.selectedFile && this.previewUrl) {\n // Show preview\n const preview = document.createElement(\"div\");\n preview.className = \"ps-preview\";\n\n const img = document.createElement(\"img\");\n img.src = this.previewUrl;\n img.alt = this.t(\"Your photo\");\n preview.appendChild(img);\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"ps-preview-remove\";\n removeBtn.textContent = \"\\u00d7\";\n removeBtn.addEventListener(\"click\", () => {\n this.resetUpload();\n this.render();\n });\n preview.appendChild(removeBtn);\n\n frag.appendChild(preview);\n\n // Submit button\n const submit = document.createElement(\"button\");\n submit.className = \"ps-submit\";\n submit.textContent = this.t(\"Try It On\");\n submit.addEventListener(\"click\", () => this.handleSubmit());\n frag.appendChild(submit);\n } else {\n // Upload zone\n const zone = document.createElement(\"div\");\n zone.className = \"ps-upload-zone\";\n\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/jpeg,image/png,image/webp\";\n input.addEventListener(\"change\", (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) this.handleFileSelect(file);\n });\n\n zone.innerHTML = `\n <svg class=\"ps-upload-icon\" viewBox=\"0 0 24 24\">${ICONS.upload.replace(/<\\/?svg[^>]*>/g, \"\")}</svg>\n <p class=\"ps-upload-text\">${this.t(\"Drop your photo here or click to upload\")}</p>\n <p class=\"ps-upload-hint\">${this.t(\"JPEG, PNG or WebP (max 10MB)\")}</p>\n `;\n zone.appendChild(input);\n\n zone.addEventListener(\"click\", () => input.click());\n zone.addEventListener(\"dragover\", (e) => {\n e.preventDefault();\n zone.classList.add(\"ps-drag-over\");\n });\n zone.addEventListener(\"dragleave\", () => {\n zone.classList.remove(\"ps-drag-over\");\n });\n zone.addEventListener(\"drop\", (e) => {\n e.preventDefault();\n zone.classList.remove(\"ps-drag-over\");\n const file = e.dataTransfer?.files?.[0];\n if (file) this.handleFileSelect(file);\n });\n\n frag.appendChild(zone);\n }\n\n return frag;\n }\n\n private createProcessingView(): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = \"ps-processing\";\n div.innerHTML = `\n <div class=\"ps-spinner\"></div>\n <p class=\"ps-processing-text\">${this.t(\"Generating virtual try-on...\")}</p>\n <p class=\"ps-processing-sub\">${this.t(\"This usually takes 15-20 seconds\")}</p>\n `;\n return div;\n }\n\n private createResultView(): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = \"ps-result\";\n\n if (this.resultImageUrl) {\n const img = document.createElement(\"img\");\n img.src = this.resultImageUrl;\n img.alt = this.t(\"Try-on result\");\n div.appendChild(img);\n }\n\n const actions = document.createElement(\"div\");\n actions.className = \"ps-result-actions\";\n\n const downloadBtn = document.createElement(\"button\");\n downloadBtn.className = \"ps-btn-download\";\n downloadBtn.textContent = this.t(\"Download\");\n downloadBtn.addEventListener(\"click\", () => this.handleDownload());\n actions.appendChild(downloadBtn);\n\n const retryBtn = document.createElement(\"button\");\n retryBtn.className = \"ps-btn-retry\";\n retryBtn.textContent = this.t(\"Try Another\");\n retryBtn.addEventListener(\"click\", () => {\n this.resetUpload();\n this.state = \"upload\";\n this.render();\n });\n actions.appendChild(retryBtn);\n\n div.appendChild(actions);\n return div;\n }\n\n private createErrorView(): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = \"ps-error\";\n div.innerHTML = `\n <svg class=\"ps-error-icon\" viewBox=\"0 0 24 24\">${ICONS.alert.replace(/<\\/?svg[^>]*>/g, \"\")}</svg>\n <p class=\"ps-error-text\">${this.errorMessage || this.t(\"Something went wrong\")}</p>\n `;\n\n const retryBtn = document.createElement(\"button\");\n retryBtn.className = \"ps-submit\";\n retryBtn.textContent = this.t(\"Try Again\");\n retryBtn.addEventListener(\"click\", () => {\n this.state = \"upload\";\n this.errorMessage = null;\n this.render();\n });\n div.appendChild(retryBtn);\n\n return div;\n }\n\n // ── Handlers ────────────────────────────────\n\n private handleFileSelect(file: File): void {\n if (!isValidImageFile(file)) {\n this.errorMessage = this.t(\"Please upload a JPEG, PNG, or WebP image.\");\n this.state = \"error\";\n this.render();\n return;\n }\n\n if (file.size > 10 * 1024 * 1024) {\n this.errorMessage = this.t(\"Image must be under 10MB.\");\n this.state = \"error\";\n this.render();\n return;\n }\n\n this.selectedFile = file;\n this.previewUrl = URL.createObjectURL(file);\n this.emit(\"ps:upload\", { file });\n this.render();\n }\n\n private async handleSubmit(): Promise<void> {\n if (!this.selectedFile || !this.apiClient || !this.sseClient) {\n this.errorMessage = this.t(\"SDK not configured. Please provide an API key.\");\n this.state = \"error\";\n this.render();\n return;\n }\n\n if (!this.productImageUrl) {\n this.errorMessage = this.t(\"No product image found. Please set the product-image attribute.\");\n this.state = \"error\";\n this.render();\n return;\n }\n\n this.state = \"processing\";\n this.render();\n\n try {\n const modelImage = await compressImage(this.selectedFile);\n\n const response = await this.apiClient.submitTryOn(\n modelImage,\n this.productImageUrl\n );\n\n this.currentJobId = response.jobId;\n this.emit(\"ps:processing\", { jobId: response.jobId });\n\n // Subscribe to SSE updates for this job\n this.sseUnsubscribe = this.sseClient.onJob(\n response.jobId,\n (update: VtoUpdate) => this.handleVtoUpdate(update)\n );\n\n // Fallback polling in case SSE misses\n this.startPolling(response.jobId);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : this.t(\"Failed to start try-on\");\n this.errorMessage = message;\n this.state = \"error\";\n this.emit(\"ps:error\", { message, code: (err as { code?: string })?.code });\n this.render();\n }\n }\n\n private handleVtoUpdate(update: VtoUpdate): void {\n if (update.status === \"completed\" && update.imageUrl) {\n // Prefer CDN URL over base64, but show whatever we get first\n if (\n this.state !== \"result\" ||\n (this.resultImageUrl?.startsWith(\"data:\") && !update.imageUrl.startsWith(\"data:\"))\n ) {\n this.resultImageUrl = update.imageUrl;\n this.state = \"result\";\n this.emit(\"ps:complete\", {\n jobId: update.galleryId,\n imageUrl: update.imageUrl,\n });\n this.render();\n }\n } else if (update.status === \"failed\") {\n this.errorMessage = update.error || this.t(\"Try-on generation failed\");\n this.state = \"error\";\n this.emit(\"ps:error\", { message: this.errorMessage });\n this.render();\n }\n }\n\n private startPolling(jobId: string): void {\n let attempts = 0;\n const maxAttempts = 60; // 2 minutes at 2s intervals\n const interval = setInterval(async () => {\n attempts++;\n if (attempts > maxAttempts || this.state === \"result\" || this.state === \"idle\") {\n clearInterval(interval);\n return;\n }\n if (!this.apiClient) {\n clearInterval(interval);\n return;\n }\n\n try {\n const status = await this.apiClient.getStatus(jobId);\n if (status.status === \"completed\" && status.imageUrl) {\n // Only use polling result if SSE hasn't delivered yet\n if (this.state === \"processing\") {\n this.handleVtoUpdate({\n galleryId: jobId,\n status: \"completed\",\n imageUrl: status.imageUrl,\n error: null,\n timestamp: Date.now(),\n });\n }\n clearInterval(interval);\n } else if (status.status === \"failed\") {\n if (this.state === \"processing\") {\n this.handleVtoUpdate({\n galleryId: jobId,\n status: \"failed\",\n imageUrl: null,\n error: status.message,\n timestamp: Date.now(),\n });\n }\n clearInterval(interval);\n }\n } catch {\n // polling error — continue trying\n }\n }, 2000);\n }\n\n private handleDownload(): void {\n if (!this.resultImageUrl) return;\n\n const link = document.createElement(\"a\");\n link.href = this.resultImageUrl;\n link.download = `primestyle-tryon-${Date.now()}.png`;\n link.target = \"_blank\";\n\n // For base64 URLs, download directly. For CDN URLs, open in new tab.\n if (this.resultImageUrl.startsWith(\"data:\")) {\n link.click();\n } else {\n // Fetch and create blob for cross-origin download\n fetch(this.resultImageUrl)\n .then((r) => r.blob())\n .then((blob) => {\n const url = URL.createObjectURL(blob);\n link.href = url;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 100);\n })\n .catch(() => {\n // Fallback: open in new tab\n window.open(this.resultImageUrl!, \"_blank\");\n });\n }\n }\n\n private resetUpload(): void {\n if (this.previewUrl) {\n URL.revokeObjectURL(this.previewUrl);\n }\n this.selectedFile = null;\n this.previewUrl = null;\n this.resultImageUrl = null;\n this.errorMessage = null;\n this.currentJobId = null;\n\n if (this.sseUnsubscribe) {\n this.sseUnsubscribe();\n this.sseUnsubscribe = null;\n }\n }\n\n // ── Custom Style Application ────────────────\n\n private applyButtonStyles(): void {\n const btn = this.shadow.querySelector<HTMLElement>(\".ps-button\");\n if (!btn) return;\n\n const map: Partial<Record<keyof ButtonStyles, string>> = {\n backgroundColor: \"--ps-btn-bg\",\n textColor: \"--ps-btn-color\",\n borderRadius: \"--ps-btn-radius\",\n fontSize: \"--ps-btn-font-size\",\n fontFamily: \"--ps-btn-font\",\n fontWeight: \"--ps-btn-font-weight\",\n textDecoration: \"--ps-btn-text-decoration\",\n padding: \"--ps-btn-padding\",\n paddingLeft: \"--ps-btn-padding-left\",\n paddingRight: \"--ps-btn-padding-right\",\n paddingTop: \"--ps-btn-padding-top\",\n paddingBottom: \"--ps-btn-padding-bottom\",\n border: \"--ps-btn-border\",\n width: \"--ps-btn-width\",\n minWidth: \"--ps-btn-min-width\",\n maxWidth: \"--ps-btn-max-width\",\n height: \"--ps-btn-height\",\n hoverBackgroundColor: \"--ps-btn-hover-bg\",\n hoverTextColor: \"--ps-btn-hover-color\",\n iconSize: \"--ps-btn-icon-size\",\n iconColor: \"--ps-btn-icon-color\",\n boxShadow: \"--ps-btn-shadow\",\n };\n\n for (const [key, cssVar] of Object.entries(map)) {\n const value = this.buttonStyles[key as keyof ButtonStyles];\n if (value) {\n this.style.setProperty(cssVar, value);\n }\n }\n }\n\n private applyModalStyles(): void {\n const map: Record<keyof ModalStyles, string> = {\n overlayColor: \"--ps-modal-overlay\",\n backgroundColor: \"--ps-modal-bg\",\n textColor: \"--ps-modal-color\",\n borderRadius: \"--ps-modal-radius\",\n width: \"--ps-modal-width\",\n maxWidth: \"--ps-modal-max-width\",\n fontFamily: \"--ps-modal-font\",\n headerBackgroundColor: \"--ps-modal-header-bg\",\n headerTextColor: \"--ps-modal-header-color\",\n closeButtonColor: \"--ps-modal-close-color\",\n uploadBorderColor: \"--ps-upload-border\",\n uploadBackgroundColor: \"--ps-upload-bg\",\n uploadTextColor: \"--ps-upload-color\",\n uploadIconColor: \"--ps-upload-icon-color\",\n primaryButtonBackgroundColor: \"--ps-modal-primary-bg\",\n primaryButtonTextColor: \"--ps-modal-primary-color\",\n primaryButtonBorderRadius: \"--ps-modal-primary-radius\",\n loaderColor: \"--ps-loader\",\n resultBorderRadius: \"--ps-result-radius\",\n accentColor: \"--ps-accent\",\n accentHoverColor: \"--ps-accent-hover\",\n accentLightColor: \"--ps-accent-light\",\n textPrimaryColor: \"--ps-text-primary\",\n textSecondaryColor: \"--ps-text-secondary\",\n textMutedColor: \"--ps-text-muted\",\n borderColor: \"--ps-border-color\",\n secondaryBackgroundColor: \"--ps-bg-secondary\",\n errorColor: \"--ps-error-color\",\n successColor: \"--ps-success-color\",\n logoHeight: \"--ps-logo-height\",\n };\n\n for (const [key, cssVar] of Object.entries(map)) {\n const value = this.modalStyles[key as keyof ModalStyles];\n if (value) {\n this.style.setProperty(cssVar, value);\n }\n }\n }\n}\n","import { PrimeStyleTryon } from \"./PrimeStyleTryon\";\nimport \"./locales\"; // Auto-register all built-in translations\n\n// Register the custom element\nif (\n typeof window !== \"undefined\" &&\n !customElements.get(\"primestyle-tryon\")\n) {\n customElements.define(\"primestyle-tryon\", PrimeStyleTryon);\n}\n\n// Re-export everything for programmatic usage\nexport { PrimeStyleTryon } from \"./PrimeStyleTryon\";\nexport { ApiClient, PrimeStyleError } from \"./api-client\";\nexport { SseClient } from \"./sse-client\";\nexport { detectProductImage } from \"./product-detector\";\nexport { compressImage, isValidImageFile, checkAgeBeforeUpload } from \"./image-utils\";\nexport type {\n PrimeStyleConfig,\n ButtonStyles,\n ModalStyles,\n TryOnResponse,\n TryOnStatus,\n VtoUpdate,\n PrimeStyleEvents,\n FitAreaInfo,\n} from \"./types\";\nexport { registerLocale, createT, SUPPORTED_LOCALES, TRANSLATION_KEYS, detectLanguage } from \"./i18n\";\nexport type { TranslateFn } from \"./i18n\";\n"],"names":["detectProductImage","ogImage","jsonLdScripts","script","data","image","extractSchemaImage","selectors","selector","el","src","item","result","obj","imgObj","getStyles","ICONS","PrimeStyleTryon","createT","name","_old","val","styles","btnStylesAttr","modalStylesAttr","localeAttr","apiKey","apiUrl","ApiClient","SseClient","detail","style","button","overlay","btn","e","modal","header","closeBtn","body","powered","frag","preview","img","removeBtn","submit","zone","input","file","div","actions","downloadBtn","retryBtn","isValidImageFile","modelImage","compressImage","response","update","err","message","jobId","attempts","maxAttempts","interval","status","link","r","blob","url","map","key","cssVar","value"],"mappings":";;;AACO,SAASA,IAAoC;AAElD,QAAMC,IAAU,SAAS;AAAA,IACvB;AAAA,EAAA;AAEF,MAAIA,GAAS,QAAS,QAAOA,EAAQ;AAGrC,QAAMC,IAAgB,SAAS;AAAA,IAC7B;AAAA,EAAA;AAEF,aAAWC,KAAUD;AACnB,QAAI;AACF,YAAME,IAAO,KAAK,MAAMD,EAAO,eAAe,EAAE,GAC1CE,IAAQC,EAAmBF,CAAI;AACrC,UAAIC,EAAO,QAAOA;AAAA,IACpB,QAAQ;AAAA,IAER;AAIF,QAAME,IAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,aAAWC,KAAYD,GAAW;AAChC,UAAME,IAAK,SAAS,cAAgCD,CAAQ;AAC5D,QAAIC,GAAI;AACN,YAAMC,IAAMD,EAAG,OAAOA,EAAG,QAAQ,OAAOA,EAAG,QAAQ;AACnD,UAAIC,EAAK,QAAOA;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASJ,EAAmBF,GAA8B;AACxD,MAAI,CAACA,KAAQ,OAAOA,KAAS,SAAU,QAAO;AAE9C,MAAI,MAAM,QAAQA,CAAI,GAAG;AACvB,eAAWO,KAAQP,GAAM;AACvB,YAAMQ,IAASN,EAAmBK,CAAI;AACtC,UAAIC,EAAQ,QAAOA;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AAEA,QAAMC,IAAMT;AAEZ,MACES,EAAI,OAAO,MAAM,aACjBA,EAAI,OAAO,MAAM,qBACjB;AACA,UAAMR,IAAQQ,EAAI;AAClB,QAAI,OAAOR,KAAU,SAAU,QAAOA;AACtC,QAAI,MAAM,QAAQA,CAAK,KAAK,OAAOA,EAAM,CAAC,KAAM,SAAU,QAAOA,EAAM,CAAC;AACxE,QAAIA,KAAS,OAAOA,KAAU,UAAU;AACtC,YAAMS,IAAST;AACf,UAAI,OAAOS,EAAO,OAAQ,iBAAiBA,EAAO;AAClD,UAAI,OAAOA,EAAO,cAAe,iBAAiBA,EAAO;AAAA,IAC3D;AAAA,EACF;AAGA,SAAI,MAAM,QAAQD,EAAI,QAAQ,CAAC,IACtBP,EAAmBO,EAAI,QAAQ,CAAC,IAGlC;AACT;AC/EO,SAASE,IAAoB;AAClC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
|
|
1
|
+
{"version":3,"file":"primestyle-tryon.js","sources":["../src/product-detector.ts","../src/styles.ts","../src/PrimeStyleTryon.ts","../src/index.ts"],"sourcesContent":["/** Attempts to auto-detect the main product image on the current page. */\nexport function detectProductImage(): string | null {\n // 1. OG image meta tag\n const ogImage = document.querySelector<HTMLMetaElement>(\n 'meta[property=\"og:image\"]'\n );\n if (ogImage?.content) return ogImage.content;\n\n // 2. Schema.org Product JSON-LD\n const jsonLdScripts = document.querySelectorAll<HTMLScriptElement>(\n 'script[type=\"application/ld+json\"]'\n );\n for (const script of jsonLdScripts) {\n try {\n const data = JSON.parse(script.textContent || \"\");\n const image = extractSchemaImage(data);\n if (image) return image;\n } catch {\n // ignore invalid JSON-LD\n }\n }\n\n // 3. Common product image selectors\n const selectors = [\n \"[data-product-image] img\",\n \"[data-product-image]\",\n \".product-image img\",\n \".product-gallery img\",\n \"#product-image\",\n \".product__media img\",\n \".product-single__photo img\",\n \".woocommerce-product-gallery img\",\n \".product-media img\",\n ];\n\n for (const selector of selectors) {\n const el = document.querySelector<HTMLImageElement>(selector);\n if (el) {\n const src = el.src || el.dataset.src || el.dataset.zoom;\n if (src) return src;\n }\n }\n\n return null;\n}\n\nfunction extractSchemaImage(data: unknown): string | null {\n if (!data || typeof data !== \"object\") return null;\n\n if (Array.isArray(data)) {\n for (const item of data) {\n const result = extractSchemaImage(item);\n if (result) return result;\n }\n return null;\n }\n\n const obj = data as Record<string, unknown>;\n\n if (\n obj[\"@type\"] === \"Product\" ||\n obj[\"@type\"] === \"IndividualProduct\"\n ) {\n const image = obj.image;\n if (typeof image === \"string\") return image;\n if (Array.isArray(image) && typeof image[0] === \"string\") return image[0];\n if (image && typeof image === \"object\") {\n const imgObj = image as Record<string, unknown>;\n if (typeof imgObj.url === \"string\") return imgObj.url;\n if (typeof imgObj.contentUrl === \"string\") return imgObj.contentUrl;\n }\n }\n\n // Check @graph\n if (Array.isArray(obj[\"@graph\"])) {\n return extractSchemaImage(obj[\"@graph\"]);\n }\n\n return null;\n}\n","export function getStyles(): string {\n return `\n :host {\n display: inline-block;\n --ps-primary: #bb945c;\n --ps-primary-hover: #a07d4e;\n --ps-text: #ffffff;\n --ps-text-secondary: #999999;\n --ps-bg: #111211;\n --ps-bg-secondary: #1a1b1a;\n --ps-border: #333333;\n --ps-radius: 12px;\n --ps-font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --ps-overlay: rgba(0, 0, 0, 0.6);\n --ps-error: #ef4444;\n --ps-success: #22c55e;\n }\n\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ── Button ─────────────────────────────── */\n .ps-button {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: var(--ps-btn-padding, 12px 24px);\n background: var(--ps-btn-bg, var(--ps-primary));\n color: var(--ps-btn-color, #111211);\n font-family: var(--ps-btn-font, var(--ps-font));\n font-size: var(--ps-btn-font-size, 14px);\n font-weight: var(--ps-btn-font-weight, 600);\n border: var(--ps-btn-border, none);\n border-radius: var(--ps-btn-radius, 8px);\n cursor: pointer;\n transition: all 0.2s ease;\n width: var(--ps-btn-width, auto);\n height: var(--ps-btn-height, auto);\n box-shadow: var(--ps-btn-shadow, none);\n line-height: 1;\n white-space: nowrap;\n }\n\n .ps-button:hover {\n background: var(--ps-btn-hover-bg, var(--ps-primary-hover));\n color: var(--ps-btn-hover-color, var(--ps-btn-color, #111211));\n transform: translateY(-1px);\n }\n\n .ps-button:active {\n transform: translateY(0);\n }\n\n .ps-button svg {\n width: var(--ps-btn-icon-size, 18px);\n height: var(--ps-btn-icon-size, 18px);\n fill: none;\n stroke: var(--ps-btn-icon-color, currentColor);\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n\n /* ── Modal Overlay ──────────────────────── */\n .ps-overlay {\n position: fixed;\n inset: 0;\n background: var(--ps-modal-overlay, var(--ps-overlay));\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.25s ease, visibility 0.25s ease;\n padding: 16px;\n }\n\n .ps-overlay.ps-open {\n opacity: 1;\n visibility: visible;\n }\n\n /* ── Modal ──────────────────────────────── */\n .ps-modal {\n background: var(--ps-modal-bg, var(--ps-bg));\n color: var(--ps-modal-color, var(--ps-text));\n border-radius: var(--ps-modal-radius, var(--ps-radius));\n width: var(--ps-modal-width, 100%);\n max-width: var(--ps-modal-max-width, 480px);\n max-height: 90vh;\n overflow-y: auto;\n font-family: var(--ps-modal-font, var(--ps-font));\n position: relative;\n transform: translateY(20px) scale(0.97);\n transition: transform 0.25s ease;\n box-shadow: 0 25px 50px rgba(0, 0, 0, 0.4);\n }\n\n .ps-open .ps-modal {\n transform: translateY(0) scale(1);\n }\n\n /* ── Modal Header ───────────────────────── */\n .ps-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--ps-modal-header-bg, var(--ps-bg-secondary));\n border-bottom: 1px solid var(--ps-border);\n border-radius: var(--ps-modal-radius, var(--ps-radius)) var(--ps-modal-radius, var(--ps-radius)) 0 0;\n }\n\n .ps-header-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--ps-modal-header-color, var(--ps-text));\n }\n\n .ps-close {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n color: var(--ps-modal-close-color, var(--ps-text-secondary));\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s;\n }\n\n .ps-close:hover {\n background: rgba(255, 255, 255, 0.1);\n }\n\n .ps-close svg {\n width: 20px;\n height: 20px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n /* ── Modal Body ─────────────────────────── */\n .ps-body {\n padding: 24px;\n }\n\n /* ── Upload Zone ─────────────────────────── */\n .ps-upload-zone {\n border: 2px dashed var(--ps-upload-border, var(--ps-border));\n border-radius: var(--ps-radius);\n padding: 40px 24px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s ease;\n background: var(--ps-upload-bg, transparent);\n }\n\n .ps-upload-zone:hover,\n .ps-upload-zone.ps-drag-over {\n border-color: var(--ps-primary);\n background: rgba(187, 148, 92, 0.05);\n }\n\n .ps-upload-zone input {\n display: none;\n }\n\n .ps-upload-icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 12px;\n stroke: var(--ps-upload-icon-color, var(--ps-primary));\n fill: none;\n stroke-width: 1.5;\n }\n\n .ps-upload-text {\n font-size: 14px;\n color: var(--ps-upload-color, var(--ps-text));\n margin-bottom: 4px;\n }\n\n .ps-upload-hint {\n font-size: 12px;\n color: var(--ps-text-secondary);\n }\n\n /* ── Preview ────────────────────────────── */\n .ps-preview {\n margin-top: 16px;\n position: relative;\n }\n\n .ps-preview img {\n width: 100%;\n border-radius: var(--ps-radius);\n display: block;\n }\n\n .ps-preview-remove {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n border: none;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n }\n\n .ps-preview-remove:hover {\n background: rgba(0, 0, 0, 0.8);\n }\n\n /* ── Submit Button ──────────────────────── */\n .ps-submit {\n width: 100%;\n padding: 14px;\n margin-top: 20px;\n background: var(--ps-modal-primary-bg, var(--ps-primary));\n color: var(--ps-modal-primary-color, #111211);\n font-family: var(--ps-modal-font, var(--ps-font));\n font-size: 14px;\n font-weight: 600;\n border: none;\n border-radius: var(--ps-modal-primary-radius, 8px);\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n }\n\n .ps-submit:hover:not(:disabled) {\n opacity: 0.9;\n transform: translateY(-1px);\n }\n\n .ps-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* ── Processing State ───────────────────── */\n .ps-processing {\n text-align: center;\n padding: 40px 24px;\n }\n\n .ps-spinner {\n width: 48px;\n height: 48px;\n border: 3px solid var(--ps-border);\n border-top-color: var(--ps-loader, var(--ps-primary));\n border-radius: 50%;\n animation: ps-spin 0.8s linear infinite;\n margin: 0 auto 16px;\n }\n\n @keyframes ps-spin {\n to { transform: rotate(360deg); }\n }\n\n .ps-processing-text {\n font-size: 14px;\n color: var(--ps-text);\n margin-bottom: 4px;\n }\n\n .ps-processing-sub {\n font-size: 12px;\n color: var(--ps-text-secondary);\n }\n\n /* ── Result ─────────────────────────────── */\n .ps-result {\n text-align: center;\n }\n\n .ps-result img {\n width: 100%;\n border-radius: var(--ps-result-radius, var(--ps-radius));\n display: block;\n margin-bottom: 16px;\n }\n\n .ps-result-actions {\n display: flex;\n gap: 8px;\n }\n\n .ps-result-actions button {\n flex: 1;\n padding: 12px;\n font-family: var(--ps-modal-font, var(--ps-font));\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n border: none;\n }\n\n .ps-btn-download {\n background: var(--ps-primary);\n color: #111211;\n }\n\n .ps-btn-download:hover {\n opacity: 0.9;\n }\n\n .ps-btn-retry {\n background: rgba(255, 255, 255, 0.1);\n color: var(--ps-text);\n border: 1px solid var(--ps-border) !important;\n }\n\n .ps-btn-retry:hover {\n background: rgba(255, 255, 255, 0.15);\n }\n\n /* ── Error State ────────────────────────── */\n .ps-error {\n text-align: center;\n padding: 24px;\n }\n\n .ps-error-icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 12px;\n stroke: var(--ps-error);\n fill: none;\n stroke-width: 1.5;\n }\n\n .ps-error-text {\n font-size: 14px;\n color: var(--ps-error);\n margin-bottom: 16px;\n }\n\n /* ── Powered By ─────────────────────────── */\n .ps-powered {\n text-align: center;\n padding: 12px 24px 16px;\n font-size: 11px;\n color: var(--ps-text-secondary);\n }\n\n .ps-powered a {\n color: var(--ps-primary);\n text-decoration: none;\n }\n\n .ps-powered a:hover {\n text-decoration: underline;\n }\n `;\n}\n","import { ApiClient } from \"./api-client\";\nimport { SseClient } from \"./sse-client\";\nimport { detectProductImage } from \"./product-detector\";\nimport { compressImage, isValidImageFile } from \"./image-utils\";\nimport { getStyles } from \"./styles\";\nimport type { ButtonStyles, ModalStyles, VtoUpdate } from \"./types\";\nimport { createT, type TranslateFn } from \"./i18n\";\n\ntype ViewState = \"idle\" | \"upload\" | \"processing\" | \"result\" | \"error\";\n\n// SVG icons as template strings\nconst ICONS = {\n camera: `<svg viewBox=\"0 0 24 24\"><path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\"/><circle cx=\"12\" cy=\"13\" r=\"4\"/></svg>`,\n upload: `<svg viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/></svg>`,\n x: `<svg viewBox=\"0 0 24 24\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`,\n alert: `<svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/></svg>`,\n};\n\nexport class PrimeStyleTryon extends HTMLElement {\n private shadow: ShadowRoot;\n private apiClient: ApiClient | null = null;\n private sseClient: SseClient | null = null;\n private sseUnsubscribe: (() => void) | null = null;\n\n private state: ViewState = \"idle\";\n private selectedFile: File | null = null;\n private previewUrl: string | null = null;\n private resultImageUrl: string | null = null;\n private errorMessage: string | null = null;\n private currentJobId: string | null = null;\n private productImageUrl: string | null = null;\n private productViewReportedFor: string | null = null;\n\n // i18n\n private t: TranslateFn = createT();\n\n // Custom style configs\n private buttonStyles: ButtonStyles = {};\n private modalStyles: ModalStyles = {};\n\n static get observedAttributes(): string[] {\n return [\n \"api-key\",\n \"api-url\",\n \"product-image\",\n \"button-text\",\n \"locale\",\n \"show-powered-by\",\n \"button-styles\",\n \"modal-styles\",\n ];\n }\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: \"open\" });\n }\n\n connectedCallback(): void {\n this.init();\n this.render();\n }\n\n disconnectedCallback(): void {\n this.cleanup();\n }\n\n attributeChangedCallback(name: string, _old: string, val: string): void {\n if (name === \"api-key\" || name === \"api-url\") {\n this.initApi();\n }\n if (name === \"locale\") {\n this.t = createT(val || undefined);\n }\n if (name === \"product-image\") {\n this.productImageUrl = val;\n }\n if (name === \"button-styles\") {\n try { this.buttonStyles = JSON.parse(val); } catch { /* ignore */ }\n }\n if (name === \"modal-styles\") {\n try { this.modalStyles = JSON.parse(val); } catch { /* ignore */ }\n }\n if (this.isConnected) this.render();\n }\n\n // ── Public API ──────────────────────────────\n\n /** Configure button appearance programmatically */\n setButtonStyles(styles: ButtonStyles): void {\n this.buttonStyles = { ...this.buttonStyles, ...styles };\n this.applyButtonStyles();\n }\n\n /** Configure modal appearance programmatically */\n setModalStyles(styles: ModalStyles): void {\n this.modalStyles = { ...this.modalStyles, ...styles };\n this.applyModalStyles();\n }\n\n private savedScrollY = 0;\n\n private lockBodyScroll(): void {\n this.savedScrollY = window.scrollY;\n document.body.style.overflow = \"hidden\";\n document.body.style.position = \"fixed\";\n document.body.style.top = `-${this.savedScrollY}px`;\n document.body.style.left = \"0\";\n document.body.style.right = \"0\";\n }\n\n private unlockBodyScroll(): void {\n document.body.style.overflow = \"\";\n document.body.style.position = \"\";\n document.body.style.top = \"\";\n document.body.style.left = \"\";\n document.body.style.right = \"\";\n window.scrollTo(0, this.savedScrollY);\n }\n\n /** Open the try-on modal */\n open(): void {\n this.reportEvent(\"SDK_OPENED\", { metadata: { component: \"PrimeStyleTryonElement\" } });\n this.state = \"upload\";\n this.lockBodyScroll();\n this.render();\n this.emit(\"ps:open\");\n }\n\n /** Close the try-on modal */\n close(): void {\n this.state = \"idle\";\n this.unlockBodyScroll();\n this.resetUpload();\n this.render();\n this.emit(\"ps:close\");\n }\n\n /** Detect product image from the current page */\n detectProduct(): string | null {\n const image = detectProductImage();\n if (image) {\n this.productImageUrl = image;\n this.emit(\"ps:product-detected\", { imageUrl: image });\n }\n return image;\n }\n\n // ── Private ─────────────────────────────────\n\n private init(): void {\n // Parse attribute-based styles\n const btnStylesAttr = this.getAttribute(\"button-styles\");\n if (btnStylesAttr) {\n try { this.buttonStyles = JSON.parse(btnStylesAttr); } catch { /* ignore */ }\n }\n const modalStylesAttr = this.getAttribute(\"modal-styles\");\n if (modalStylesAttr) {\n try { this.modalStyles = JSON.parse(modalStylesAttr); } catch { /* ignore */ }\n }\n\n // Init locale\n const localeAttr = this.getAttribute(\"locale\");\n if (localeAttr) this.t = createT(localeAttr);\n\n this.productImageUrl = this.getAttribute(\"product-image\") || null;\n\n // Auto-detect product image if not provided\n if (!this.productImageUrl) {\n this.productImageUrl = detectProductImage();\n if (this.productImageUrl) {\n this.emit(\"ps:product-detected\", { imageUrl: this.productImageUrl });\n }\n }\n\n this.initApi();\n this.reportProductView();\n }\n\n private initApi(): void {\n const apiKey = this.getAttribute(\"api-key\") || undefined;\n const apiUrl = this.getAttribute(\"api-url\") || undefined;\n this.apiClient = new ApiClient(apiKey, apiUrl);\n this.sseClient = null;\n }\n\n private cleanup(): void {\n if (this.state !== \"idle\") {\n this.unlockBodyScroll();\n }\n if (this.sseUnsubscribe) {\n this.sseUnsubscribe();\n this.sseUnsubscribe = null;\n }\n if (this.sseClient) {\n this.sseClient.disconnect();\n this.sseClient = null;\n }\n if (this.previewUrl) {\n URL.revokeObjectURL(this.previewUrl);\n }\n }\n\n private emit(name: string, detail?: unknown): void {\n this.dispatchEvent(\n new CustomEvent(name, { bubbles: true, composed: true, detail })\n );\n }\n\n private get eventProductContext(): {\n productId?: string;\n productTitle?: string;\n productUrl?: string;\n } {\n return {\n productId: this.getAttribute(\"product-id\") || this.productImageUrl || undefined,\n productTitle: this.getAttribute(\"product-title\") || document.title || undefined,\n productUrl: typeof window !== \"undefined\" ? window.location.href : undefined,\n };\n }\n\n private reportProductView(): void {\n const key = `${this.eventProductContext.productId || \"\"}|${this.eventProductContext.productUrl || \"\"}`;\n if (!key.trim() || this.productViewReportedFor === key) return;\n this.productViewReportedFor = key;\n this.reportEvent(\"PRODUCT_VIEW\", { metadata: { component: \"PrimeStyleTryonElement\" } });\n }\n\n private reportEvent(\n eventType: Parameters<ApiClient[\"reportEvent\"]>[0][\"eventType\"],\n input: Omit<Parameters<ApiClient[\"reportEvent\"]>[0], \"eventType\" | \"productId\" | \"productTitle\" | \"productUrl\"> = {},\n ): void {\n void this.apiClient?.reportEvent({\n eventType,\n ...this.eventProductContext,\n ...input,\n }).catch(() => {});\n }\n\n private reportClientError(\n input: Omit<Parameters<ApiClient[\"reportClientError\"]>[0], \"productId\" | \"productTitle\" | \"productUrl\">,\n ): void {\n void this.apiClient?.reportClientError({\n ...this.eventProductContext,\n ...input,\n }).catch(() => {});\n }\n\n private get buttonText(): string {\n return this.getAttribute(\"button-text\") || this.t(\"Virtual Try-On\");\n }\n\n private get showPoweredBy(): boolean {\n const attr = this.getAttribute(\"show-powered-by\");\n return attr !== \"false\";\n }\n\n // ── Rendering ───────────────────────────────\n\n private render(): void {\n this.shadow.innerHTML = \"\";\n\n const style = document.createElement(\"style\");\n style.textContent = getStyles();\n this.shadow.appendChild(style);\n\n // Button (always visible)\n const button = this.createButton();\n this.shadow.appendChild(button);\n\n // Modal overlay\n if (this.state !== \"idle\") {\n const overlay = this.createModal();\n this.shadow.appendChild(overlay);\n // Trigger open animation\n requestAnimationFrame(() => overlay.classList.add(\"ps-open\"));\n }\n\n this.applyButtonStyles();\n this.applyModalStyles();\n }\n\n private createButton(): HTMLButtonElement {\n const btn = document.createElement(\"button\");\n btn.className = \"ps-button\";\n btn.innerHTML = `${ICONS.camera}<span>${this.buttonText}</span>`;\n btn.addEventListener(\"click\", () => this.open());\n return btn;\n }\n\n private createModal(): HTMLDivElement {\n const overlay = document.createElement(\"div\");\n overlay.className = \"ps-overlay\";\n overlay.addEventListener(\"click\", (e) => {\n if (e.target === overlay) this.close();\n });\n\n const modal = document.createElement(\"div\");\n modal.className = \"ps-modal\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"ps-header\";\n header.innerHTML = `\n <span class=\"ps-header-title\">${this.t(\"Virtual Try-On\")}</span>\n `;\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"ps-close\";\n closeBtn.innerHTML = ICONS.x;\n closeBtn.addEventListener(\"click\", () => this.close());\n header.appendChild(closeBtn);\n modal.appendChild(header);\n\n // Body\n const body = document.createElement(\"div\");\n body.className = \"ps-body\";\n\n switch (this.state) {\n case \"upload\":\n body.appendChild(this.createUploadView());\n break;\n case \"processing\":\n body.appendChild(this.createProcessingView());\n break;\n case \"result\":\n body.appendChild(this.createResultView());\n break;\n case \"error\":\n body.appendChild(this.createErrorView());\n break;\n }\n\n modal.appendChild(body);\n\n // Powered by\n if (this.showPoweredBy) {\n const powered = document.createElement(\"div\");\n powered.className = \"ps-powered\";\n powered.innerHTML = `${this.t(\"Powered by\")} <a href=\"https://myaifitting.com\" target=\"_blank\" rel=\"noopener\">PrimeStyle AI</a>`;\n modal.appendChild(powered);\n }\n\n overlay.appendChild(modal);\n return overlay;\n }\n\n private createUploadView(): DocumentFragment {\n const frag = document.createDocumentFragment();\n\n if (this.selectedFile && this.previewUrl) {\n // Show preview\n const preview = document.createElement(\"div\");\n preview.className = \"ps-preview\";\n\n const img = document.createElement(\"img\");\n img.src = this.previewUrl;\n img.alt = this.t(\"Your photo\");\n preview.appendChild(img);\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"ps-preview-remove\";\n removeBtn.textContent = \"\\u00d7\";\n removeBtn.addEventListener(\"click\", () => {\n this.resetUpload();\n this.render();\n });\n preview.appendChild(removeBtn);\n\n frag.appendChild(preview);\n\n // Submit button\n const submit = document.createElement(\"button\");\n submit.className = \"ps-submit\";\n submit.textContent = this.t(\"Try It On\");\n submit.addEventListener(\"click\", () => this.handleSubmit());\n frag.appendChild(submit);\n } else {\n // Upload zone\n const zone = document.createElement(\"div\");\n zone.className = \"ps-upload-zone\";\n\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/jpeg,image/png,image/webp\";\n input.addEventListener(\"change\", (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) this.handleFileSelect(file);\n });\n\n zone.innerHTML = `\n <svg class=\"ps-upload-icon\" viewBox=\"0 0 24 24\">${ICONS.upload.replace(/<\\/?svg[^>]*>/g, \"\")}</svg>\n <p class=\"ps-upload-text\">${this.t(\"Drop your photo here or click to upload\")}</p>\n <p class=\"ps-upload-hint\">${this.t(\"JPEG, PNG or WebP (max 10MB)\")}</p>\n `;\n zone.appendChild(input);\n\n zone.addEventListener(\"click\", () => input.click());\n zone.addEventListener(\"dragover\", (e) => {\n e.preventDefault();\n zone.classList.add(\"ps-drag-over\");\n });\n zone.addEventListener(\"dragleave\", () => {\n zone.classList.remove(\"ps-drag-over\");\n });\n zone.addEventListener(\"drop\", (e) => {\n e.preventDefault();\n zone.classList.remove(\"ps-drag-over\");\n const file = e.dataTransfer?.files?.[0];\n if (file) this.handleFileSelect(file);\n });\n\n frag.appendChild(zone);\n }\n\n return frag;\n }\n\n private createProcessingView(): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = \"ps-processing\";\n div.innerHTML = `\n <div class=\"ps-spinner\"></div>\n <p class=\"ps-processing-text\">${this.t(\"Generating virtual try-on...\")}</p>\n <p class=\"ps-processing-sub\">${this.t(\"This usually takes 15-20 seconds\")}</p>\n `;\n return div;\n }\n\n private createResultView(): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = \"ps-result\";\n\n if (this.resultImageUrl) {\n const img = document.createElement(\"img\");\n img.src = this.resultImageUrl;\n img.alt = this.t(\"Try-on result\");\n div.appendChild(img);\n }\n\n const actions = document.createElement(\"div\");\n actions.className = \"ps-result-actions\";\n\n const downloadBtn = document.createElement(\"button\");\n downloadBtn.className = \"ps-btn-download\";\n downloadBtn.textContent = this.t(\"Download\");\n downloadBtn.addEventListener(\"click\", () => this.handleDownload());\n actions.appendChild(downloadBtn);\n\n const retryBtn = document.createElement(\"button\");\n retryBtn.className = \"ps-btn-retry\";\n retryBtn.textContent = this.t(\"Try Another\");\n retryBtn.addEventListener(\"click\", () => {\n this.resetUpload();\n this.state = \"upload\";\n this.render();\n });\n actions.appendChild(retryBtn);\n\n div.appendChild(actions);\n return div;\n }\n\n private createErrorView(): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = \"ps-error\";\n div.innerHTML = `\n <svg class=\"ps-error-icon\" viewBox=\"0 0 24 24\">${ICONS.alert.replace(/<\\/?svg[^>]*>/g, \"\")}</svg>\n <p class=\"ps-error-text\">${this.errorMessage || this.t(\"Something went wrong\")}</p>\n `;\n\n const retryBtn = document.createElement(\"button\");\n retryBtn.className = \"ps-submit\";\n retryBtn.textContent = this.t(\"Try Again\");\n retryBtn.addEventListener(\"click\", () => {\n this.state = \"upload\";\n this.errorMessage = null;\n this.render();\n });\n div.appendChild(retryBtn);\n\n return div;\n }\n\n // ── Handlers ────────────────────────────────\n\n private handleFileSelect(file: File): void {\n if (!isValidImageFile(file)) {\n this.errorMessage = this.t(\"Please upload a JPEG, PNG, or WebP image.\");\n this.state = \"error\";\n this.reportClientError({\n message: \"Invalid image file type\",\n code: \"INVALID_FILE\",\n component: \"PrimeStyleTryonElement\",\n view: \"upload\",\n severity: \"low\",\n metadata: { fileType: file.type, fileSize: file.size },\n });\n this.render();\n return;\n }\n\n if (file.size > 10 * 1024 * 1024) {\n this.errorMessage = this.t(\"Image must be under 10MB.\");\n this.state = \"error\";\n this.reportClientError({\n message: \"Image file too large\",\n code: \"FILE_TOO_LARGE\",\n component: \"PrimeStyleTryonElement\",\n view: \"upload\",\n severity: \"low\",\n metadata: { fileType: file.type, fileSize: file.size },\n });\n this.render();\n return;\n }\n\n this.selectedFile = file;\n this.previewUrl = URL.createObjectURL(file);\n this.reportEvent(\"PHOTO_UPLOADED\", {\n metadata: { fileType: file.type, fileSize: file.size, component: \"PrimeStyleTryonElement\" },\n });\n this.emit(\"ps:upload\", { file });\n this.render();\n }\n\n private async handleSubmit(): Promise<void> {\n if (!this.selectedFile || !this.apiClient) {\n this.errorMessage = this.t(\"SDK not configured. Please provide an API key.\");\n this.state = \"error\";\n this.reportClientError({\n message: this.errorMessage,\n code: !this.apiClient ? \"SDK_NOT_CONFIGURED\" : \"PHOTO_MISSING\",\n component: \"PrimeStyleTryonElement\",\n view: \"upload\",\n severity: !this.apiClient ? \"high\" : \"low\",\n });\n this.render();\n return;\n }\n\n if (!this.productImageUrl) {\n this.errorMessage = this.t(\"No product image found. Please set the product-image attribute.\");\n this.state = \"error\";\n this.reportClientError({\n message: this.errorMessage,\n code: \"PRODUCT_IMAGE_MISSING\",\n component: \"PrimeStyleTryonElement\",\n view: \"upload\",\n severity: \"medium\",\n });\n this.render();\n return;\n }\n\n this.state = \"processing\";\n this.render();\n\n try {\n const modelImage = await compressImage(this.selectedFile);\n\n const response = await this.apiClient.submitTryOn(\n modelImage,\n this.productImageUrl\n );\n\n this.currentJobId = response.jobId;\n this.emit(\"ps:processing\", { jobId: response.jobId });\n\n // Subscribe to SSE updates for this job\n this.sseClient?.disconnect();\n this.sseClient = new SseClient(response.streamUrl || this.apiClient.getStreamUrl(response.jobId));\n this.sseUnsubscribe = this.sseClient.onJob(\n response.jobId,\n (update: VtoUpdate) => this.handleVtoUpdate(update)\n );\n\n // Fallback polling in case SSE misses\n this.startPolling(response.jobId);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : this.t(\"Failed to start try-on\");\n this.errorMessage = message;\n this.state = \"error\";\n this.reportClientError({\n message,\n code: (err as { code?: string })?.code || \"TRYON_SUBMIT_FAILED\",\n stack: err instanceof Error ? err.stack : undefined,\n component: \"PrimeStyleTryonElement\",\n view: \"processing\",\n severity: \"medium\",\n });\n this.emit(\"ps:error\", { message, code: (err as { code?: string })?.code });\n this.render();\n }\n }\n\n private handleVtoUpdate(update: VtoUpdate): void {\n if (update.status === \"completed\" && update.imageUrl) {\n // Prefer CDN URL over base64, but show whatever we get first\n if (\n this.state !== \"result\" ||\n (this.resultImageUrl?.startsWith(\"data:\") && !update.imageUrl.startsWith(\"data:\"))\n ) {\n this.resultImageUrl = update.imageUrl;\n this.state = \"result\";\n this.emit(\"ps:complete\", {\n jobId: update.galleryId,\n imageUrl: update.imageUrl,\n });\n this.render();\n }\n } else if (update.status === \"failed\") {\n this.errorMessage = update.error || this.t(\"Try-on generation failed\");\n this.state = \"error\";\n this.reportClientError({\n message: this.errorMessage,\n code: \"TRYON_GENERATION_FAILED\",\n component: \"PrimeStyleTryonElement\",\n view: \"processing\",\n severity: \"medium\",\n jobId: update.galleryId,\n });\n this.emit(\"ps:error\", { message: this.errorMessage });\n this.render();\n }\n }\n\n private startPolling(jobId: string): void {\n let attempts = 0;\n const maxAttempts = 60; // 2 minutes at 2s intervals\n const interval = setInterval(async () => {\n attempts++;\n if (attempts > maxAttempts || this.state === \"result\" || this.state === \"idle\") {\n clearInterval(interval);\n return;\n }\n if (!this.apiClient) {\n clearInterval(interval);\n return;\n }\n\n try {\n const status = await this.apiClient.getStatus(jobId);\n if (status.status === \"completed\" && status.imageUrl) {\n // Only use polling result if SSE hasn't delivered yet\n if (this.state === \"processing\") {\n this.handleVtoUpdate({\n galleryId: jobId,\n status: \"completed\",\n imageUrl: status.imageUrl,\n error: null,\n timestamp: Date.now(),\n });\n }\n clearInterval(interval);\n } else if (status.status === \"failed\") {\n if (this.state === \"processing\") {\n this.handleVtoUpdate({\n galleryId: jobId,\n status: \"failed\",\n imageUrl: null,\n error: status.message,\n timestamp: Date.now(),\n });\n }\n clearInterval(interval);\n }\n } catch {\n // polling error — continue trying\n }\n }, 2000);\n }\n\n private handleDownload(): void {\n if (!this.resultImageUrl) return;\n\n const link = document.createElement(\"a\");\n link.href = this.resultImageUrl;\n link.download = `primestyle-tryon-${Date.now()}.png`;\n link.target = \"_blank\";\n\n // For base64 URLs, download directly. For CDN URLs, open in new tab.\n if (this.resultImageUrl.startsWith(\"data:\")) {\n link.click();\n } else {\n // Fetch and create blob for cross-origin download\n fetch(this.resultImageUrl)\n .then((r) => r.blob())\n .then((blob) => {\n const url = URL.createObjectURL(blob);\n link.href = url;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 100);\n })\n .catch(() => {\n // Fallback: open in new tab\n window.open(this.resultImageUrl!, \"_blank\");\n });\n }\n }\n\n private resetUpload(): void {\n if (this.previewUrl) {\n URL.revokeObjectURL(this.previewUrl);\n }\n this.selectedFile = null;\n this.previewUrl = null;\n this.resultImageUrl = null;\n this.errorMessage = null;\n this.currentJobId = null;\n\n if (this.sseUnsubscribe) {\n this.sseUnsubscribe();\n this.sseUnsubscribe = null;\n }\n }\n\n // ── Custom Style Application ────────────────\n\n private applyButtonStyles(): void {\n const btn = this.shadow.querySelector<HTMLElement>(\".ps-button\");\n if (!btn) return;\n\n const map: Partial<Record<keyof ButtonStyles, string>> = {\n backgroundColor: \"--ps-btn-bg\",\n textColor: \"--ps-btn-color\",\n borderRadius: \"--ps-btn-radius\",\n fontSize: \"--ps-btn-font-size\",\n fontFamily: \"--ps-btn-font\",\n fontWeight: \"--ps-btn-font-weight\",\n textDecoration: \"--ps-btn-text-decoration\",\n padding: \"--ps-btn-padding\",\n paddingLeft: \"--ps-btn-padding-left\",\n paddingRight: \"--ps-btn-padding-right\",\n paddingTop: \"--ps-btn-padding-top\",\n paddingBottom: \"--ps-btn-padding-bottom\",\n border: \"--ps-btn-border\",\n width: \"--ps-btn-width\",\n minWidth: \"--ps-btn-min-width\",\n maxWidth: \"--ps-btn-max-width\",\n height: \"--ps-btn-height\",\n hoverBackgroundColor: \"--ps-btn-hover-bg\",\n hoverTextColor: \"--ps-btn-hover-color\",\n iconSize: \"--ps-btn-icon-size\",\n iconColor: \"--ps-btn-icon-color\",\n boxShadow: \"--ps-btn-shadow\",\n };\n\n for (const [key, cssVar] of Object.entries(map)) {\n const value = this.buttonStyles[key as keyof ButtonStyles];\n if (value) {\n this.style.setProperty(cssVar, value);\n }\n }\n }\n\n private applyModalStyles(): void {\n const map: Record<keyof ModalStyles, string> = {\n overlayColor: \"--ps-modal-overlay\",\n backgroundColor: \"--ps-modal-bg\",\n textColor: \"--ps-modal-color\",\n borderRadius: \"--ps-modal-radius\",\n width: \"--ps-modal-width\",\n maxWidth: \"--ps-modal-max-width\",\n fontFamily: \"--ps-modal-font\",\n headerBackgroundColor: \"--ps-modal-header-bg\",\n headerTextColor: \"--ps-modal-header-color\",\n closeButtonColor: \"--ps-modal-close-color\",\n uploadBorderColor: \"--ps-upload-border\",\n uploadBackgroundColor: \"--ps-upload-bg\",\n uploadTextColor: \"--ps-upload-color\",\n uploadIconColor: \"--ps-upload-icon-color\",\n primaryButtonBackgroundColor: \"--ps-modal-primary-bg\",\n primaryButtonTextColor: \"--ps-modal-primary-color\",\n primaryButtonBorderRadius: \"--ps-modal-primary-radius\",\n loaderColor: \"--ps-loader\",\n resultBorderRadius: \"--ps-result-radius\",\n accentColor: \"--ps-accent\",\n accentHoverColor: \"--ps-accent-hover\",\n accentLightColor: \"--ps-accent-light\",\n textPrimaryColor: \"--ps-text-primary\",\n textSecondaryColor: \"--ps-text-secondary\",\n textMutedColor: \"--ps-text-muted\",\n borderColor: \"--ps-border-color\",\n secondaryBackgroundColor: \"--ps-bg-secondary\",\n errorColor: \"--ps-error-color\",\n successColor: \"--ps-success-color\",\n logoHeight: \"--ps-logo-height\",\n };\n\n for (const [key, cssVar] of Object.entries(map)) {\n const value = this.modalStyles[key as keyof ModalStyles];\n if (value) {\n this.style.setProperty(cssVar, value);\n }\n }\n }\n}\n","import { PrimeStyleTryon } from \"./PrimeStyleTryon\";\nimport \"./locales\"; // Auto-register all built-in translations\n\n// Register the custom element\nif (\n typeof window !== \"undefined\" &&\n !customElements.get(\"primestyle-tryon\")\n) {\n customElements.define(\"primestyle-tryon\", PrimeStyleTryon);\n}\n\n// Re-export everything for programmatic usage\nexport { PrimeStyleTryon } from \"./PrimeStyleTryon\";\nexport { ApiClient, PrimeStyleError } from \"./api-client\";\nexport { SseClient } from \"./sse-client\";\nexport { detectProductImage } from \"./product-detector\";\nexport { compressImage, isValidImageFile, checkAgeBeforeUpload } from \"./image-utils\";\nexport type {\n PrimeStyleConfig,\n ButtonStyles,\n ModalStyles,\n TryOnResponse,\n TryOnStatus,\n VtoUpdate,\n PrimeStyleEvents,\n FitAreaInfo,\n} from \"./types\";\nexport { registerLocale, createT, SUPPORTED_LOCALES, TRANSLATION_KEYS, detectLanguage } from \"./i18n\";\nexport type { TranslateFn } from \"./i18n\";\n"],"names":["detectProductImage","ogImage","jsonLdScripts","script","data","image","extractSchemaImage","selectors","selector","el","src","item","result","obj","imgObj","getStyles","ICONS","PrimeStyleTryon","createT","name","_old","val","styles","btnStylesAttr","modalStylesAttr","localeAttr","apiKey","apiUrl","ApiClient","detail","key","eventType","input","style","button","overlay","btn","e","modal","header","closeBtn","body","powered","frag","preview","img","removeBtn","submit","zone","file","div","actions","downloadBtn","retryBtn","isValidImageFile","modelImage","compressImage","response","SseClient","update","err","message","jobId","attempts","maxAttempts","interval","status","link","r","blob","url","map","cssVar","value"],"mappings":";;;AACO,SAASA,IAAoC;AAElD,QAAMC,IAAU,SAAS;AAAA,IACvB;AAAA,EAAA;AAEF,MAAIA,GAAS,QAAS,QAAOA,EAAQ;AAGrC,QAAMC,IAAgB,SAAS;AAAA,IAC7B;AAAA,EAAA;AAEF,aAAWC,KAAUD;AACnB,QAAI;AACF,YAAME,IAAO,KAAK,MAAMD,EAAO,eAAe,EAAE,GAC1CE,IAAQC,EAAmBF,CAAI;AACrC,UAAIC,EAAO,QAAOA;AAAA,IACpB,QAAQ;AAAA,IAER;AAIF,QAAME,IAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,aAAWC,KAAYD,GAAW;AAChC,UAAME,IAAK,SAAS,cAAgCD,CAAQ;AAC5D,QAAIC,GAAI;AACN,YAAMC,IAAMD,EAAG,OAAOA,EAAG,QAAQ,OAAOA,EAAG,QAAQ;AACnD,UAAIC,EAAK,QAAOA;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASJ,EAAmBF,GAA8B;AACxD,MAAI,CAACA,KAAQ,OAAOA,KAAS,SAAU,QAAO;AAE9C,MAAI,MAAM,QAAQA,CAAI,GAAG;AACvB,eAAWO,KAAQP,GAAM;AACvB,YAAMQ,IAASN,EAAmBK,CAAI;AACtC,UAAIC,EAAQ,QAAOA;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AAEA,QAAMC,IAAMT;AAEZ,MACES,EAAI,OAAO,MAAM,aACjBA,EAAI,OAAO,MAAM,qBACjB;AACA,UAAMR,IAAQQ,EAAI;AAClB,QAAI,OAAOR,KAAU,SAAU,QAAOA;AACtC,QAAI,MAAM,QAAQA,CAAK,KAAK,OAAOA,EAAM,CAAC,KAAM,SAAU,QAAOA,EAAM,CAAC;AACxE,QAAIA,KAAS,OAAOA,KAAU,UAAU;AACtC,YAAMS,IAAST;AACf,UAAI,OAAOS,EAAO,OAAQ,iBAAiBA,EAAO;AAClD,UAAI,OAAOA,EAAO,cAAe,iBAAiBA,EAAO;AAAA,IAC3D;AAAA,EACF;AAGA,SAAI,MAAM,QAAQD,EAAI,QAAQ,CAAC,IACtBP,EAAmBO,EAAI,QAAQ,CAAC,IAGlC;AACT;AC/EO,SAASE,IAAoB;AAClC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
|