@primestyleai/tryon 5.10.173 → 5.10.175
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/api-client.d.ts +8 -3
- package/dist/image-utils.d.ts +1 -0
- package/dist/{index-B1_VQgps.js → index-D4yjnBvO.js} +147 -82
- package/dist/index-D4yjnBvO.js.map +1 -0
- package/dist/primestyle-tryon.js +6 -5
- package/dist/primestyle-tryon.js.map +1 -1
- package/dist/react/PrimeStyleTryonInner.d.ts +7 -2
- package/dist/react/components/LangSwitcher.d.ts +2 -1
- package/dist/react/components/ProfileDetailModal.d.ts +2 -1
- package/dist/react/icons.d.ts +3 -0
- package/dist/react/index.js +9334 -6250
- package/dist/react/index.js.map +1 -1
- package/dist/react/recommendForProduct.d.ts +6 -0
- package/dist/react/styles.d.ts +1 -1
- package/dist/react/types.d.ts +56 -0
- package/dist/react/utils/locale.d.ts +3 -1
- package/dist/react/utils/product-fit.d.ts +19 -0
- package/dist/react/utils/profile-auth.d.ts +10 -0
- package/dist/react/utils/profile-image.d.ts +3 -0
- package/dist/react/utils/remote-profiles.d.ts +7 -0
- package/dist/react/utils/shoe-reference.d.ts +39 -0
- package/dist/react/views/AccessorySizeView.d.ts +1 -0
- package/dist/react/views/BasicsStepMobile.d.ts +3 -1
- package/dist/react/views/BodyProfileView.d.ts +11 -3
- package/dist/react/views/CreateProfileWizard.d.ts +4 -2
- package/dist/react/views/ErrorView.d.ts +4 -3
- package/dist/react/views/FootSizeView.d.ts +1 -0
- package/dist/react/views/MobileScanningView.d.ts +5 -1
- package/dist/react/views/MultiSectionMobile.d.ts +7 -2
- package/dist/react/views/MySizingProfilesView.d.ts +5 -2
- package/dist/react/views/PhotoGuideView.d.ts +1 -1
- package/dist/react/views/PhotoStepMobile.d.ts +3 -1
- package/dist/react/views/ProductPhotoCarouselCard.d.ts +8 -2
- package/dist/react/views/SizeResultView.d.ts +8 -2
- package/dist/react/views/SocialProfileAuthView.d.ts +10 -0
- package/dist/react/views/WristSizeView.d.ts +28 -0
- package/dist/sizing/fit-compute.d.ts +8 -0
- package/dist/storefront/cart-hook.d.ts +4 -4
- package/dist/storefront/events.d.ts +6 -0
- package/dist/storefront/primestyle-tryon.js +4755 -1046
- package/dist/types.d.ts +5 -0
- package/package.json +2 -3
- package/dist/index-B1_VQgps.js.map +0 -1
package/dist/primestyle-tryon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { c as l, A as c, S as h, i as u, a as m } from "./index-
|
|
3
|
-
import { P as x, b as w, T as C, d as k, e as U, r as S } from "./index-
|
|
2
|
+
import { c as l, A as c, S as h, i as u, a as m } from "./index-D4yjnBvO.js";
|
|
3
|
+
import { P as x, b as w, T as C, d as k, e as U, r as S } from "./index-D4yjnBvO.js";
|
|
4
4
|
function d() {
|
|
5
5
|
const i = document.querySelector(
|
|
6
6
|
'meta[property="og:image"]'
|
|
@@ -521,9 +521,7 @@ class b extends HTMLElement {
|
|
|
521
521
|
s && (this.t = l(s)), this.productImageUrl = this.getAttribute("product-image") || null, this.productImageUrl || (this.productImageUrl = d(), this.productImageUrl && this.emit("ps:product-detected", { imageUrl: this.productImageUrl })), this.initApi();
|
|
522
522
|
}
|
|
523
523
|
initApi() {
|
|
524
|
-
const t = this.getAttribute("api-key");
|
|
525
|
-
if (!t) return;
|
|
526
|
-
const e = this.getAttribute("api-url") || void 0;
|
|
524
|
+
const t = this.getAttribute("api-key") || void 0, e = this.getAttribute("api-url") || void 0;
|
|
527
525
|
this.apiClient = new c(t, e), this.sseClient = new h(this.apiClient.getStreamUrl());
|
|
528
526
|
}
|
|
529
527
|
cleanup() {
|
|
@@ -755,6 +753,7 @@ class b extends HTMLElement {
|
|
|
755
753
|
fontSize: "--ps-btn-font-size",
|
|
756
754
|
fontFamily: "--ps-btn-font",
|
|
757
755
|
fontWeight: "--ps-btn-font-weight",
|
|
756
|
+
textDecoration: "--ps-btn-text-decoration",
|
|
758
757
|
padding: "--ps-btn-padding",
|
|
759
758
|
paddingLeft: "--ps-btn-padding-left",
|
|
760
759
|
paddingRight: "--ps-btn-padding-right",
|
|
@@ -762,6 +761,8 @@ class b extends HTMLElement {
|
|
|
762
761
|
paddingBottom: "--ps-btn-padding-bottom",
|
|
763
762
|
border: "--ps-btn-border",
|
|
764
763
|
width: "--ps-btn-width",
|
|
764
|
+
minWidth: "--ps-btn-min-width",
|
|
765
|
+
maxWidth: "--ps-btn-max-width",
|
|
765
766
|
height: "--ps-btn-height",
|
|
766
767
|
hoverBackgroundColor: "--ps-btn-hover-bg",
|
|
767
768
|
hoverTextColor: "--ps-btn-hover-color",
|
|
@@ -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\");\n if (!apiKey) return;\n\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: 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 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 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\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,2 +1,7 @@
|
|
|
1
|
-
import type { PrimeStyleTryonProps } from "./types";
|
|
2
|
-
|
|
1
|
+
import type { PrimeStyleTryonProps, ViewState } from "./types";
|
|
2
|
+
type PrimeStyleTryonInnerProps = PrimeStyleTryonProps & {
|
|
3
|
+
initialView?: ViewState;
|
|
4
|
+
initialBodyProfileStep?: "photo" | "basics";
|
|
5
|
+
};
|
|
6
|
+
export declare function PrimeStyleTryonInner({ productImage, productImages, productCarouselItems, garmentReferenceImage, productTitle, productId, productCategory, productGender, productSubcategory, productFitType, productType, productVendor, productTags, productDescription, productMaterial, buttonText, apiUrl, showPoweredBy, showIcon, buttonIcon, locale, buttonStyles: btnS, modalStyles: mdlS, classNames: cn, className, style, portalContainer, onOpen, onClose, onUpload, onProcessing, onComplete, onError, sizeGuideData, initialView, initialBodyProfileStep, }: PrimeStyleTryonInnerProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export declare function LangSwitcher({ activeLocale: current, onSelect }: {
|
|
1
|
+
export declare function LangSwitcher({ activeLocale: current, onSelect, portalContainer, }: {
|
|
2
2
|
activeLocale: string;
|
|
3
3
|
onSelect: (code: string) => void;
|
|
4
|
+
portalContainer?: Element | DocumentFragment;
|
|
4
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -8,11 +8,12 @@ import type { Profile } from "../types";
|
|
|
8
8
|
*
|
|
9
9
|
* Portaled to document.body so parent stacking contexts can't clip it.
|
|
10
10
|
*/
|
|
11
|
-
export declare function ProfileDetailModal({ profileDetail, setProfileDetail, setProfiles, activeProfileId, setActiveProfileId, t, }: {
|
|
11
|
+
export declare function ProfileDetailModal({ profileDetail, setProfileDetail, setProfiles, activeProfileId, setActiveProfileId, t, portalContainer, }: {
|
|
12
12
|
profileDetail: Profile | null;
|
|
13
13
|
setProfileDetail: (p: Profile | null) => void;
|
|
14
14
|
setProfiles: React.Dispatch<React.SetStateAction<Profile[]>>;
|
|
15
15
|
activeProfileId: string | null;
|
|
16
16
|
setActiveProfileId: (id: string | null) => void;
|
|
17
17
|
t: TranslateFn;
|
|
18
|
+
portalContainer?: Element | DocumentFragment;
|
|
18
19
|
}): import("react").ReactPortal | null;
|
package/dist/react/icons.d.ts
CHANGED
|
@@ -33,6 +33,9 @@ export declare function TrashIcon({ size }: {
|
|
|
33
33
|
size?: number;
|
|
34
34
|
}): import("react/jsx-runtime").JSX.Element;
|
|
35
35
|
export declare function ChevronRightIcon(): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
export declare function ChevronDownIcon({ size }: {
|
|
37
|
+
size?: number;
|
|
38
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
36
39
|
export declare function CheckIcon({ size }: {
|
|
37
40
|
size?: number;
|
|
38
41
|
}): import("react/jsx-runtime").JSX.Element;
|