@primestyleai/tryon 5.9.0 → 5.10.0
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/react/components/ConfirmMeasurementsModal.d.ts +22 -0
- package/dist/react/index.js +350 -55
- package/dist/react/recommendForProduct.d.ts +4 -0
- package/dist/react/styles.d.ts +1 -1
- package/dist/react/utils/units.d.ts +6 -0
- package/dist/react/views/MobileScanningView.d.ts +4 -1
- package/dist/storefront/primestyle-tryon.js +350 -55
- package/dist/types.d.ts +7 -0
- package/package.json +1 -1
|
@@ -10080,7 +10080,8 @@ async function recommendForProduct(input) {
|
|
|
10080
10080
|
sections: sectionsMap,
|
|
10081
10081
|
profileId: profile.id,
|
|
10082
10082
|
fromCache: false,
|
|
10083
|
-
raw: result
|
|
10083
|
+
raw: result,
|
|
10084
|
+
found: result.found
|
|
10084
10085
|
};
|
|
10085
10086
|
}
|
|
10086
10087
|
async function estimateFullMeasurements(args) {
|
|
@@ -10139,6 +10140,12 @@ async function estimateFullMeasurements(args) {
|
|
|
10139
10140
|
function isImperial(locale) {
|
|
10140
10141
|
return ["US", "UK", "AU"].includes(locale);
|
|
10141
10142
|
}
|
|
10143
|
+
function getUnitLabel(unit) {
|
|
10144
|
+
if (unit === "in" || unit === "inches" || unit === "lbs") return "Imperial";
|
|
10145
|
+
if (unit === "cm" || unit === "kg") return "Metric";
|
|
10146
|
+
if (unit === "mm") return "mm";
|
|
10147
|
+
return "";
|
|
10148
|
+
}
|
|
10142
10149
|
function cx(base, override) {
|
|
10143
10150
|
return override ? `${base} ${override}` : base;
|
|
10144
10151
|
}
|
|
@@ -10913,12 +10920,22 @@ const STYLES$1 = `
|
|
|
10913
10920
|
}
|
|
10914
10921
|
.ps-tryon-v2-processing-label {
|
|
10915
10922
|
position: absolute; bottom: 1vw; left: 50%; transform: translateX(-50%);
|
|
10916
|
-
z-index: 5; font-size: 0.
|
|
10917
|
-
color:
|
|
10918
|
-
background: rgba(0,0,0,0.
|
|
10919
|
-
padding: 0.
|
|
10923
|
+
z-index: 5; font-size: 0.7vw; font-weight: 600;
|
|
10924
|
+
color: #fff; letter-spacing: 0.05em;
|
|
10925
|
+
background: rgba(0,0,0,0.72); backdrop-filter: blur(10px);
|
|
10926
|
+
padding: 0.6vw 0.9vw; border-radius: 0.6vw;
|
|
10927
|
+
display: flex; flex-direction: column; align-items: center; gap: 0.5vw;
|
|
10928
|
+
min-width: 14vw;
|
|
10929
|
+
box-shadow: 0 0.4vw 1.5vw rgba(0,0,0,0.35);
|
|
10930
|
+
}
|
|
10931
|
+
.ps-tryon-v2-processing-label > span:first-child {
|
|
10920
10932
|
animation: ps-loading-pulse 2s ease-in-out infinite;
|
|
10921
10933
|
}
|
|
10934
|
+
.ps-tryon-v2-processing-label .ps-tryon-progress-ring-track { stroke: rgba(255,255,255,0.18); }
|
|
10935
|
+
.ps-tryon-v2-processing-label .ps-tryon-progress-ring-fill { stroke: var(--ps-accent-light); }
|
|
10936
|
+
.ps-tryon-v2-processing-label .ps-tryon-progress-eta { color: #fff; }
|
|
10937
|
+
.ps-tryon-v2-processing-label .ps-tryon-progress-bar-wrap { background: rgba(255,255,255,0.18); }
|
|
10938
|
+
.ps-tryon-v2-processing-label .ps-tryon-progress-pct { color: var(--ps-accent-light); }
|
|
10922
10939
|
|
|
10923
10940
|
/* "I don't know" link */
|
|
10924
10941
|
.ps-tryon-v2-dontknow {
|
|
@@ -11511,6 +11528,26 @@ const STYLES$1 = `
|
|
|
11511
11528
|
.ps-tryon-progress-section {
|
|
11512
11529
|
display: flex; align-items: center; gap: 0.63vw; width: 100%; max-width: 18vw; margin-bottom: 0.83vw;
|
|
11513
11530
|
}
|
|
11531
|
+
/* Shared progress layout used inside StageCycler (desktop) and
|
|
11532
|
+
MobileScanningView — row of ring + bar + percent, same tokens. */
|
|
11533
|
+
.ps-tryon-progress-wrap {
|
|
11534
|
+
display: flex; align-items: center; gap: 12px;
|
|
11535
|
+
width: 100%; max-width: 360px; margin-top: 18px;
|
|
11536
|
+
}
|
|
11537
|
+
.ps-tryon-progress-wrap .ps-tryon-progress-bar-wrap {
|
|
11538
|
+
flex: 1; height: 6px; border-radius: 4px; overflow: hidden;
|
|
11539
|
+
position: relative; background: var(--ps-border-color);
|
|
11540
|
+
}
|
|
11541
|
+
.ps-tryon-progress-wrap .ps-tryon-progress-bar-fill {
|
|
11542
|
+
height: 100%; width: 0%;
|
|
11543
|
+
background: linear-gradient(90deg, var(--ps-accent), var(--ps-accent-light));
|
|
11544
|
+
border-radius: 4px; transition: width 0.3s ease;
|
|
11545
|
+
}
|
|
11546
|
+
.ps-tryon-progress-wrap .ps-tryon-progress-pct {
|
|
11547
|
+
font-size: 13px; font-weight: 700; color: var(--ps-accent);
|
|
11548
|
+
min-width: 36px; text-align: right;
|
|
11549
|
+
font-variant-numeric: tabular-nums;
|
|
11550
|
+
}
|
|
11514
11551
|
.ps-tryon-progress-bar-wrap {
|
|
11515
11552
|
flex: 1; height: 0.31vw; background: var(--ps-border-color); border-radius: 3px; overflow: hidden;
|
|
11516
11553
|
position: relative;
|
|
@@ -11536,25 +11573,25 @@ const STYLES$1 = `
|
|
|
11536
11573
|
font-variant-numeric: tabular-nums;
|
|
11537
11574
|
}
|
|
11538
11575
|
|
|
11539
|
-
/* Circular ETA ring —
|
|
11576
|
+
/* Circular ETA ring — 64×64 px SVG with a track + progress circle; ETA
|
|
11540
11577
|
text centered. strokeDashoffset is driven by the ticker in
|
|
11541
11578
|
PrimeStyleTryonInner, so CSS only styles the appearance. */
|
|
11542
11579
|
.ps-tryon-progress-ring {
|
|
11543
|
-
position: relative; width:
|
|
11580
|
+
position: relative; width: 64px; height: 64px; flex: 0 0 64px;
|
|
11544
11581
|
display: flex; align-items: center; justify-content: center;
|
|
11545
11582
|
}
|
|
11546
11583
|
.ps-tryon-progress-ring svg { transform: rotate(-90deg); }
|
|
11547
11584
|
.ps-tryon-progress-ring-track {
|
|
11548
|
-
fill: none; stroke: var(--ps-border-color); stroke-width:
|
|
11585
|
+
fill: none; stroke: var(--ps-border-color); stroke-width: 5;
|
|
11549
11586
|
}
|
|
11550
11587
|
.ps-tryon-progress-ring-fill {
|
|
11551
|
-
fill: none; stroke: var(--ps-accent); stroke-width:
|
|
11588
|
+
fill: none; stroke: var(--ps-accent); stroke-width: 5;
|
|
11552
11589
|
stroke-linecap: round;
|
|
11553
11590
|
transition: stroke-dashoffset 0.3s ease;
|
|
11554
11591
|
}
|
|
11555
11592
|
.ps-tryon-progress-eta {
|
|
11556
11593
|
position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
|
|
11557
|
-
font-size:
|
|
11594
|
+
font-size: 13px; font-weight: 700; color: var(--ps-accent);
|
|
11558
11595
|
font-variant-numeric: tabular-nums; letter-spacing: 0.01em;
|
|
11559
11596
|
pointer-events: none;
|
|
11560
11597
|
}
|
|
@@ -16641,6 +16678,92 @@ function ProfileDetailModal({
|
|
|
16641
16678
|
document.body
|
|
16642
16679
|
);
|
|
16643
16680
|
}
|
|
16681
|
+
function ConfirmMeasurementsModal({
|
|
16682
|
+
profile,
|
|
16683
|
+
onProceed,
|
|
16684
|
+
onEdit,
|
|
16685
|
+
t: t2
|
|
16686
|
+
}) {
|
|
16687
|
+
const heightUnit = profile.heightUnit === "in" || profile.heightUnit === "ft" ? "in" : "cm";
|
|
16688
|
+
const weightUnit = profile.weightUnit === "lbs" ? "lbs" : "kg";
|
|
16689
|
+
const systemLabel = getUnitLabel(heightUnit);
|
|
16690
|
+
const formatHeight = (h) => {
|
|
16691
|
+
if (!h) return "—";
|
|
16692
|
+
if (heightUnit === "in") {
|
|
16693
|
+
const ft = Math.floor(h / 12);
|
|
16694
|
+
const inches = Math.round(h % 12);
|
|
16695
|
+
return `${ft}'${inches}"`;
|
|
16696
|
+
}
|
|
16697
|
+
return `${Math.round(h)} cm`;
|
|
16698
|
+
};
|
|
16699
|
+
const formatWeight = (w2) => {
|
|
16700
|
+
if (!w2) return "—";
|
|
16701
|
+
return `${Math.round(w2)} ${weightUnit}`;
|
|
16702
|
+
};
|
|
16703
|
+
const height = profile.height ?? profile.heightCm;
|
|
16704
|
+
const weight = profile.weight ?? profile.weightKg;
|
|
16705
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-confirm-overlay", onClick: onEdit, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-confirm-modal", onClick: (e) => e.stopPropagation(), children: [
|
|
16706
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16707
|
+
"button",
|
|
16708
|
+
{
|
|
16709
|
+
type: "button",
|
|
16710
|
+
"aria-label": t2("Close"),
|
|
16711
|
+
onClick: onEdit,
|
|
16712
|
+
style: {
|
|
16713
|
+
position: "absolute",
|
|
16714
|
+
top: "0.75vw",
|
|
16715
|
+
right: "0.75vw",
|
|
16716
|
+
width: "1.8vw",
|
|
16717
|
+
height: "1.8vw",
|
|
16718
|
+
borderRadius: "50%",
|
|
16719
|
+
background: "transparent",
|
|
16720
|
+
border: "none",
|
|
16721
|
+
cursor: "pointer",
|
|
16722
|
+
display: "flex",
|
|
16723
|
+
alignItems: "center",
|
|
16724
|
+
justifyContent: "center",
|
|
16725
|
+
color: "var(--ps-text-muted)"
|
|
16726
|
+
},
|
|
16727
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", width: "16", height: "16", children: [
|
|
16728
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
16729
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
16730
|
+
] })
|
|
16731
|
+
}
|
|
16732
|
+
),
|
|
16733
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { fontWeight: 700, marginBottom: "0.4vw" }, children: t2("Confirm your measurements") }),
|
|
16734
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { style: { color: "var(--ps-text-muted)" }, children: systemLabel ? t2("You chose") + " " + systemLabel + ". " + t2("Review before continuing.") : t2("Review before continuing.") }),
|
|
16735
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { style: {
|
|
16736
|
+
listStyle: "none",
|
|
16737
|
+
padding: 0,
|
|
16738
|
+
margin: "0.8vw 0 0.2vw 0",
|
|
16739
|
+
width: "100%",
|
|
16740
|
+
textAlign: "left",
|
|
16741
|
+
fontSize: "0.78vw",
|
|
16742
|
+
lineHeight: 1.6
|
|
16743
|
+
}, children: [
|
|
16744
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { style: { display: "flex", justifyContent: "space-between", gap: "1vw" }, children: [
|
|
16745
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--ps-text-muted)" }, children: t2("Height") }),
|
|
16746
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontWeight: 600 }, children: formatHeight(height) })
|
|
16747
|
+
] }),
|
|
16748
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { style: { display: "flex", justifyContent: "space-between", gap: "1vw" }, children: [
|
|
16749
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--ps-text-muted)" }, children: t2("Weight") }),
|
|
16750
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontWeight: 600 }, children: formatWeight(weight) })
|
|
16751
|
+
] }),
|
|
16752
|
+
profile.age ? /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { style: { display: "flex", justifyContent: "space-between", gap: "1vw" }, children: [
|
|
16753
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--ps-text-muted)" }, children: t2("Age") }),
|
|
16754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontWeight: 600 }, children: profile.age })
|
|
16755
|
+
] }) : null,
|
|
16756
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { style: { display: "flex", justifyContent: "space-between", gap: "1vw" }, children: [
|
|
16757
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--ps-text-muted)" }, children: t2("Gender") }),
|
|
16758
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontWeight: 600 }, children: profile.gender === "female" ? t2("Female") : t2("Male") })
|
|
16759
|
+
] })
|
|
16760
|
+
] }),
|
|
16761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-confirm-actions", children: [
|
|
16762
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-confirm-cancel", onClick: onEdit, children: t2("Edit") }),
|
|
16763
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-confirm-delete", onClick: onProceed, children: t2("Proceed") })
|
|
16764
|
+
] })
|
|
16765
|
+
] }) });
|
|
16766
|
+
}
|
|
16644
16767
|
function WelcomeView({
|
|
16645
16768
|
productImage,
|
|
16646
16769
|
setView,
|
|
@@ -16876,17 +16999,71 @@ function MobileSkeleton({ landmarks, w: w2, h }) {
|
|
|
16876
16999
|
}
|
|
16877
17000
|
);
|
|
16878
17001
|
}
|
|
17002
|
+
const MSC_TRYON_TARGET_SECONDS = 22;
|
|
17003
|
+
const MSC_RING_RADIUS = 27;
|
|
17004
|
+
const MSC_RING_CIRC = 2 * Math.PI * MSC_RING_RADIUS;
|
|
17005
|
+
function MscTryOnProgress({ t: t2 }) {
|
|
17006
|
+
const startRef = reactExports.useRef(Date.now());
|
|
17007
|
+
const ringRef = reactExports.useRef(null);
|
|
17008
|
+
const barRef = reactExports.useRef(null);
|
|
17009
|
+
const etaRef = reactExports.useRef(null);
|
|
17010
|
+
const pctRef = reactExports.useRef(null);
|
|
17011
|
+
reactExports.useEffect(() => {
|
|
17012
|
+
startRef.current = Date.now();
|
|
17013
|
+
const id2 = setInterval(() => {
|
|
17014
|
+
const elapsed = (Date.now() - startRef.current) / 1e3;
|
|
17015
|
+
const pct = Math.min(95, elapsed / MSC_TRYON_TARGET_SECONDS * 100);
|
|
17016
|
+
const val = Math.round(pct);
|
|
17017
|
+
if (barRef.current) barRef.current.style.width = `${val}%`;
|
|
17018
|
+
if (pctRef.current) pctRef.current.textContent = `${val}%`;
|
|
17019
|
+
if (ringRef.current) ringRef.current.style.strokeDashoffset = String(MSC_RING_CIRC * (1 - pct / 100));
|
|
17020
|
+
if (etaRef.current) {
|
|
17021
|
+
const remaining = Math.max(0, MSC_TRYON_TARGET_SECONDS - Math.floor(elapsed));
|
|
17022
|
+
etaRef.current.textContent = elapsed >= MSC_TRYON_TARGET_SECONDS ? t2("Finalizing...") : `~${remaining}s`;
|
|
17023
|
+
}
|
|
17024
|
+
}, 200);
|
|
17025
|
+
return () => clearInterval(id2);
|
|
17026
|
+
}, []);
|
|
17027
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-progress-wrap", children: [
|
|
17028
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-progress-ring", children: [
|
|
17029
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "64", height: "64", viewBox: "0 0 64 64", "aria-hidden": "true", children: [
|
|
17030
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "32", cy: "32", r: MSC_RING_RADIUS, className: "ps-tryon-progress-ring-track" }),
|
|
17031
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17032
|
+
"circle",
|
|
17033
|
+
{
|
|
17034
|
+
ref: ringRef,
|
|
17035
|
+
cx: "32",
|
|
17036
|
+
cy: "32",
|
|
17037
|
+
r: MSC_RING_RADIUS,
|
|
17038
|
+
className: "ps-tryon-progress-ring-fill",
|
|
17039
|
+
strokeDasharray: MSC_RING_CIRC,
|
|
17040
|
+
strokeDashoffset: MSC_RING_CIRC
|
|
17041
|
+
}
|
|
17042
|
+
)
|
|
17043
|
+
] }),
|
|
17044
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { ref: etaRef, className: "ps-tryon-progress-eta", children: `~${MSC_TRYON_TARGET_SECONDS}s` })
|
|
17045
|
+
] }),
|
|
17046
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-progress-bar-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: barRef, className: "ps-tryon-progress-bar-fill" }) }),
|
|
17047
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { ref: pctRef, className: "ps-tryon-progress-pct", children: "0%" })
|
|
17048
|
+
] });
|
|
17049
|
+
}
|
|
16879
17050
|
function MobileScanningView({
|
|
16880
17051
|
previewUrl,
|
|
16881
17052
|
productImage,
|
|
16882
17053
|
bodyLandmarks,
|
|
16883
17054
|
sizingDone,
|
|
17055
|
+
tryOnProcessing,
|
|
16884
17056
|
onSwitchToManual,
|
|
16885
17057
|
t: t2
|
|
16886
17058
|
}) {
|
|
16887
17059
|
const displayImage = previewUrl || productImage || "";
|
|
16888
17060
|
const isPhotoMode = !!previewUrl;
|
|
16889
|
-
const stages =
|
|
17061
|
+
const stages = tryOnProcessing ? [
|
|
17062
|
+
{ title: t2("GENERATING TRY-ON"), desc: t2("Rendering the garment on your photo."), viewfinderText: t2("GENERATING") },
|
|
17063
|
+
{ title: t2("REFINING DETAILS"), desc: t2("Fine-tuning fit, drape and shadows."), viewfinderText: t2("REFINING") },
|
|
17064
|
+
{ title: t2("ALMOST THERE"), desc: t2("Final compositing in progress."), viewfinderText: t2("COMPOSITING") },
|
|
17065
|
+
{ title: t2("FINISHING TOUCHES"), desc: t2("Polishing the result."), viewfinderText: t2("FINISHING") }
|
|
17066
|
+
] : isPhotoMode ? [
|
|
16890
17067
|
{ title: t2("DETECTING POSE"), desc: t2("Identifying body landmarks from your photo."), viewfinderText: t2("DETECTING POSE") },
|
|
16891
17068
|
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions to calculate the perfect fit."), viewfinderText: t2("SCANNING FRAME") },
|
|
16892
17069
|
{ title: t2("ANALYZING BODY"), desc: t2("Measuring shoulders, chest, waist and hips."), viewfinderText: t2("ANALYZING") },
|
|
@@ -16905,11 +17082,12 @@ function MobileScanningView({
|
|
|
16905
17082
|
};
|
|
16906
17083
|
const [stageIdx, setStageIdx] = reactExports.useState(0);
|
|
16907
17084
|
reactExports.useEffect(() => {
|
|
17085
|
+
const intervalMs = tryOnProcessing ? 2200 : 1500;
|
|
16908
17086
|
const id2 = setInterval(() => {
|
|
16909
17087
|
setStageIdx((i) => (i + 1) % stages.length);
|
|
16910
|
-
},
|
|
17088
|
+
}, intervalMs);
|
|
16911
17089
|
return () => clearInterval(id2);
|
|
16912
|
-
}, [stages.length]);
|
|
17090
|
+
}, [stages.length, tryOnProcessing]);
|
|
16913
17091
|
reactExports.useEffect(() => {
|
|
16914
17092
|
if (isPhotoMode && bodyLandmarks && stageIdx === 0) {
|
|
16915
17093
|
setStageIdx(1);
|
|
@@ -16929,10 +17107,13 @@ function MobileScanningView({
|
|
|
16929
17107
|
),
|
|
16930
17108
|
isPhotoMode && bodyLandmarks && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msc-pose-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MobileSkeleton, { landmarks: bodyLandmarks, w: dims.w, h: dims.h }) })
|
|
16931
17109
|
] }),
|
|
16932
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
16933
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
16934
|
-
|
|
16935
|
-
|
|
17110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msc-stage", children: [
|
|
17111
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msc-stage-slot", children: [
|
|
17112
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msc-stage-title", children: current.title }),
|
|
17113
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msc-stage-desc", children: current.desc })
|
|
17114
|
+
] }, stageIdx),
|
|
17115
|
+
tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(MscTryOnProgress, { t: t2 })
|
|
17116
|
+
] }),
|
|
16936
17117
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bpm-spacer" }),
|
|
16937
17118
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bpm-bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
16938
17119
|
MobileBottomTabs,
|
|
@@ -17063,7 +17244,7 @@ function MultiSectionMobile({
|
|
|
17063
17244
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-sections", children: sectionEntries.map(({ name, secResult }) => {
|
|
17064
17245
|
const cleanName = name.replace(/\s*[—–-]\s*.*/g, "");
|
|
17065
17246
|
const sec = secResult;
|
|
17066
|
-
const sizeValue = sec.size || secResult.recommendedSize;
|
|
17247
|
+
const sizeValue = sec.found === false ? t2("No fit") : sec.size || secResult.recommendedSize;
|
|
17067
17248
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
17068
17249
|
"button",
|
|
17069
17250
|
{
|
|
@@ -17098,7 +17279,19 @@ function MultiSectionMobile({
|
|
|
17098
17279
|
children: t2("Continue Shopping")
|
|
17099
17280
|
}
|
|
17100
17281
|
)
|
|
17101
|
-
] }) :
|
|
17282
|
+
] }) : sizingResult?.found === false ? (
|
|
17283
|
+
// Backend couldn't find a size that fits — Try-On is meaningless
|
|
17284
|
+
// without a recommendation, so surface a clear terminal action.
|
|
17285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17286
|
+
"button",
|
|
17287
|
+
{
|
|
17288
|
+
type: "button",
|
|
17289
|
+
className: "ps-msr-tryon-cta",
|
|
17290
|
+
onClick: onClose,
|
|
17291
|
+
children: t2("Continue Shopping")
|
|
17292
|
+
}
|
|
17293
|
+
)
|
|
17294
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
17102
17295
|
"button",
|
|
17103
17296
|
{
|
|
17104
17297
|
type: "button",
|
|
@@ -17130,6 +17323,62 @@ const SKELETON_CONNECTIONS = [
|
|
|
17130
17323
|
["rightHip", "rightKnee"],
|
|
17131
17324
|
["rightKnee", "rightAnkle"]
|
|
17132
17325
|
];
|
|
17326
|
+
const TRYON_TARGET_SECONDS = 22;
|
|
17327
|
+
const TRYON_RING_RADIUS = 27;
|
|
17328
|
+
const TRYON_RING_CIRC = 2 * Math.PI * TRYON_RING_RADIUS;
|
|
17329
|
+
function TryOnProgress({ t: t2, isActive }) {
|
|
17330
|
+
const startRef = reactExports.useRef(null);
|
|
17331
|
+
const ringRef = reactExports.useRef(null);
|
|
17332
|
+
const barRef = reactExports.useRef(null);
|
|
17333
|
+
const etaRef = reactExports.useRef(null);
|
|
17334
|
+
const pctRef = reactExports.useRef(null);
|
|
17335
|
+
reactExports.useEffect(() => {
|
|
17336
|
+
if (!isActive) {
|
|
17337
|
+
startRef.current = null;
|
|
17338
|
+
return;
|
|
17339
|
+
}
|
|
17340
|
+
startRef.current = Date.now();
|
|
17341
|
+
const id2 = setInterval(() => {
|
|
17342
|
+
const start = startRef.current || Date.now();
|
|
17343
|
+
const elapsed = (Date.now() - start) / 1e3;
|
|
17344
|
+
const pct = Math.min(95, elapsed / TRYON_TARGET_SECONDS * 100);
|
|
17345
|
+
const val = Math.round(pct);
|
|
17346
|
+
if (barRef.current) barRef.current.style.width = `${val}%`;
|
|
17347
|
+
if (pctRef.current) pctRef.current.textContent = `${val}%`;
|
|
17348
|
+
if (ringRef.current) {
|
|
17349
|
+
ringRef.current.style.strokeDashoffset = String(TRYON_RING_CIRC * (1 - pct / 100));
|
|
17350
|
+
}
|
|
17351
|
+
if (etaRef.current) {
|
|
17352
|
+
const remaining = Math.max(0, TRYON_TARGET_SECONDS - Math.floor(elapsed));
|
|
17353
|
+
etaRef.current.textContent = elapsed >= TRYON_TARGET_SECONDS ? t2("Finalizing...") : `~${remaining}s`;
|
|
17354
|
+
}
|
|
17355
|
+
}, 200);
|
|
17356
|
+
return () => clearInterval(id2);
|
|
17357
|
+
}, [isActive]);
|
|
17358
|
+
if (!isActive) return null;
|
|
17359
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-progress-wrap", children: [
|
|
17360
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-progress-ring", children: [
|
|
17361
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "64", height: "64", viewBox: "0 0 64 64", "aria-hidden": "true", children: [
|
|
17362
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "32", cy: "32", r: TRYON_RING_RADIUS, className: "ps-tryon-progress-ring-track" }),
|
|
17363
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17364
|
+
"circle",
|
|
17365
|
+
{
|
|
17366
|
+
ref: ringRef,
|
|
17367
|
+
cx: "32",
|
|
17368
|
+
cy: "32",
|
|
17369
|
+
r: TRYON_RING_RADIUS,
|
|
17370
|
+
className: "ps-tryon-progress-ring-fill",
|
|
17371
|
+
strokeDasharray: TRYON_RING_CIRC,
|
|
17372
|
+
strokeDashoffset: TRYON_RING_CIRC
|
|
17373
|
+
}
|
|
17374
|
+
)
|
|
17375
|
+
] }),
|
|
17376
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { ref: etaRef, className: "ps-tryon-progress-eta", children: `~${TRYON_TARGET_SECONDS}s` })
|
|
17377
|
+
] }),
|
|
17378
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-progress-bar-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: barRef, className: "ps-tryon-progress-bar-fill" }) }),
|
|
17379
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { ref: pctRef, className: "ps-tryon-progress-pct", children: "0%" })
|
|
17380
|
+
] });
|
|
17381
|
+
}
|
|
17133
17382
|
function FaceOverlay({
|
|
17134
17383
|
landmarks,
|
|
17135
17384
|
imgWidth,
|
|
@@ -17267,16 +17516,20 @@ function StageCycler({
|
|
|
17267
17516
|
}, [tryOnProcessing]);
|
|
17268
17517
|
reactExports.useEffect(() => {
|
|
17269
17518
|
if (isDone) return;
|
|
17519
|
+
const intervalMs = tryOnProcessing ? 2200 : 900;
|
|
17270
17520
|
const id2 = setInterval(() => {
|
|
17271
17521
|
setIdx((i) => Math.min(i + 1, active.length - 1));
|
|
17272
|
-
},
|
|
17522
|
+
}, intervalMs);
|
|
17273
17523
|
return () => clearInterval(id2);
|
|
17274
|
-
}, [isDone, active.length]);
|
|
17524
|
+
}, [isDone, active.length, tryOnProcessing]);
|
|
17275
17525
|
const current = active[idx] ?? active[0];
|
|
17276
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
17277
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
17278
|
-
|
|
17279
|
-
|
|
17526
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msc-stage", style: { alignSelf: "center", marginTop: "auto", marginBottom: "auto" }, children: [
|
|
17527
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msc-stage-slot", children: [
|
|
17528
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msc-stage-title", children: current.title }),
|
|
17529
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msc-stage-desc", children: current.desc })
|
|
17530
|
+
] }, `${tryOnProcessing ? "t" : "s"}-${idx}`),
|
|
17531
|
+
tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnProgress, { t: t2, isActive: !!tryOnProcessing })
|
|
17532
|
+
] });
|
|
17280
17533
|
}
|
|
17281
17534
|
function SkeletonOverlay({ landmarks, imgWidth, imgHeight }) {
|
|
17282
17535
|
const W2 = imgWidth;
|
|
@@ -17515,7 +17768,8 @@ function SectionDetailView({
|
|
|
17515
17768
|
backLabel,
|
|
17516
17769
|
internationalSizes,
|
|
17517
17770
|
continueLabel,
|
|
17518
|
-
renderRaw = false
|
|
17771
|
+
renderRaw = false,
|
|
17772
|
+
sectionFound
|
|
17519
17773
|
}) {
|
|
17520
17774
|
const recSize = sectionResult?.recommendedSize || "";
|
|
17521
17775
|
const [selectedSize, setSelectedSize] = reactExports.useState(null);
|
|
@@ -17560,7 +17814,8 @@ function SectionDetailView({
|
|
|
17560
17814
|
const hasBadFit = details.some((d) => BAD_FIT.test(d.fit || ""));
|
|
17561
17815
|
return hasBadFit ? t2("Not Recommended") : t2("Your Selection");
|
|
17562
17816
|
}, [isRecommended, sectionResult, t2]);
|
|
17563
|
-
const
|
|
17817
|
+
const noFitMessage = t2("We couldn't find a size that fits for this product");
|
|
17818
|
+
const displaySizeLabel = sectionFound === false ? noFitMessage : selectedCountry && isRecommended && internationalSizes && internationalSizes[selectedCountry] ? internationalSizes[selectedCountry] : displaySize;
|
|
17564
17819
|
const columnUnits = reactExports.useMemo(() => {
|
|
17565
17820
|
const units = [];
|
|
17566
17821
|
for (let i = 0; i < section.headers.length; i++) {
|
|
@@ -18414,6 +18669,7 @@ function SizeResultView({
|
|
|
18414
18669
|
const allDone = hasPhoto ? sizingDone && tryOnDone : sizingDone;
|
|
18415
18670
|
const isMobile = useIsMobile();
|
|
18416
18671
|
const isAccessory = measurementType === "face" || measurementType === "head";
|
|
18672
|
+
const noFit = sizingResult?.found === false;
|
|
18417
18673
|
const vtoExcluded = measurementType === "foot";
|
|
18418
18674
|
console.log("[PS-SDK] SizeResultView render:", {
|
|
18419
18675
|
hasPhoto,
|
|
@@ -18452,6 +18708,7 @@ function SizeResultView({
|
|
|
18452
18708
|
previewUrl,
|
|
18453
18709
|
bodyLandmarks: bodyLandmarks ?? null,
|
|
18454
18710
|
sizingDone,
|
|
18711
|
+
tryOnProcessing,
|
|
18455
18712
|
onSwitchToManual: () => setView("body-profile"),
|
|
18456
18713
|
t: t2
|
|
18457
18714
|
}
|
|
@@ -18497,6 +18754,7 @@ function SizeResultView({
|
|
|
18497
18754
|
sectionName: entry.name,
|
|
18498
18755
|
section: entry.section,
|
|
18499
18756
|
sectionResult: entry.secResult,
|
|
18757
|
+
sectionFound: entry.secResult?.found,
|
|
18500
18758
|
userMeasurements: entry.userMeasurements,
|
|
18501
18759
|
unitLbl,
|
|
18502
18760
|
chartUnit: resultUnit,
|
|
@@ -18508,7 +18766,7 @@ function SizeResultView({
|
|
|
18508
18766
|
isMobile: true,
|
|
18509
18767
|
isTryOnImage: !!resultImageUrl,
|
|
18510
18768
|
showLines,
|
|
18511
|
-
onToggleLines: () => setShowLines(!showLines),
|
|
18769
|
+
onToggleLines: isAccessory ? void 0 : () => setShowLines(!showLines),
|
|
18512
18770
|
onImageLoad: handleImgLoad,
|
|
18513
18771
|
overlayNode: resultImageUrl && poseReady && poseLines ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18514
18772
|
MeasurementOverlay,
|
|
@@ -18546,6 +18804,7 @@ function SizeResultView({
|
|
|
18546
18804
|
sectionName: entry.name,
|
|
18547
18805
|
section: entry.section,
|
|
18548
18806
|
sectionResult: entry.secResult,
|
|
18807
|
+
sectionFound: entry.secResult?.found,
|
|
18549
18808
|
userMeasurements: entry.userMeasurements,
|
|
18550
18809
|
unitLbl,
|
|
18551
18810
|
chartUnit: resultUnit,
|
|
@@ -18582,7 +18841,7 @@ function SizeResultView({
|
|
|
18582
18841
|
},
|
|
18583
18842
|
onClose,
|
|
18584
18843
|
showLines,
|
|
18585
|
-
onToggleLines: () => setShowLines(!showLines),
|
|
18844
|
+
onToggleLines: isAccessory ? void 0 : () => setShowLines(!showLines),
|
|
18586
18845
|
onImageLoad: handleImgLoad,
|
|
18587
18846
|
overlayNode: resultImageUrl && poseReady && poseLines ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18588
18847
|
MeasurementOverlay,
|
|
@@ -18617,7 +18876,10 @@ function SizeResultView({
|
|
|
18617
18876
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
|
|
18618
18877
|
/* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage, alt: productTitle, className: "ps-tryon-v2-bg-img", onLoad: handleImgLoad }),
|
|
18619
18878
|
tryOnProcessing && bodyLandmarks && /* @__PURE__ */ jsxRuntimeExports.jsx(SkeletonOverlay, { landmarks: bodyLandmarks, imgWidth: imgDims.w, imgHeight: imgDims.h }),
|
|
18620
|
-
tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.
|
|
18879
|
+
tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-processing-label", children: [
|
|
18880
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("Generating try-on...") }),
|
|
18881
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TryOnProgress, { t: t2, isActive: true })
|
|
18882
|
+
] }),
|
|
18621
18883
|
resultImageUrl && !tryOnProcessing && poseReady && poseLines && /* @__PURE__ */ jsxRuntimeExports.jsx(MeasurementOverlay, { lines: poseLines, fitRows: (() => {
|
|
18622
18884
|
const all = [...sizingResult?.matchDetails || []];
|
|
18623
18885
|
if (sizingResult?.sections) {
|
|
@@ -18634,7 +18896,7 @@ function SizeResultView({
|
|
|
18634
18896
|
}).map((m2) => ({ area: m2.measurement, userNum: parseFloat(m2.userValue) || 0, chartLabel: m2.chartRange || "", fit: m2.fit }));
|
|
18635
18897
|
})(), show: showLines, imgWidth: imgDims.w, imgHeight: imgDims.h }),
|
|
18636
18898
|
resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "absolute", bottom: "0.5vw", left: "0.5vw", zIndex: 3, display: "flex", flexDirection: "column", gap: "0.3vw" }, children: [
|
|
18637
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setShowLines(!showLines), children: [
|
|
18899
|
+
!isAccessory && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setShowLines(!showLines), children: [
|
|
18638
18900
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", style: { marginRight: "0.3vw" }, children: [
|
|
18639
18901
|
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
|
|
18640
18902
|
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
|
|
@@ -18664,7 +18926,7 @@ function SizeResultView({
|
|
|
18664
18926
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: `ps-tryon-sr-card-v2${isLast ? " ps-full" : ""}`, onClick: () => setActiveSection(name), style: { animationDelay: `${idx * 0.07}s` }, children: [
|
|
18665
18927
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-card-v2-text", children: [
|
|
18666
18928
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-sr-card-v2-label", children: name.replace(/\s*[—–-]\s*.*/g, "") }),
|
|
18667
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-sr-card-v2-value", children: sec.size || secResult.recommendedSize }),
|
|
18929
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-sr-card-v2-value", children: sec.found === false ? t2("No fit") : sec.size || secResult.recommendedSize }),
|
|
18668
18930
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-sr-card-v2-rec", children: t2("recommended") })
|
|
18669
18931
|
] }),
|
|
18670
18932
|
sectionImg && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: sectionImg, alt: name, className: "ps-tryon-sr-card-v2-img" }),
|
|
@@ -18688,7 +18950,7 @@ function SizeResultView({
|
|
|
18688
18950
|
" →"
|
|
18689
18951
|
]
|
|
18690
18952
|
}
|
|
18691
|
-
) : vtoExcluded ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18953
|
+
) : vtoExcluded || noFit ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18692
18954
|
"button",
|
|
18693
18955
|
{
|
|
18694
18956
|
className: "ps-tryon-v2-cta",
|
|
@@ -18741,6 +19003,7 @@ function SizeResultView({
|
|
|
18741
19003
|
sectionName,
|
|
18742
19004
|
section: singleSection,
|
|
18743
19005
|
sectionResult: singleResult,
|
|
19006
|
+
sectionFound: sizingResult?.found,
|
|
18744
19007
|
userMeasurements: singleUserMeasurements,
|
|
18745
19008
|
unitLbl,
|
|
18746
19009
|
chartUnit: resultUnit,
|
|
@@ -18748,7 +19011,7 @@ function SizeResultView({
|
|
|
18748
19011
|
onBack: resultImageUrl ? onClose || (() => setView("body-profile")) : () => setView("body-profile"),
|
|
18749
19012
|
backLabel: t2("Back"),
|
|
18750
19013
|
internationalSizes: sizingResult?.internationalSizes,
|
|
18751
|
-
onTryOn: resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
19014
|
+
onTryOn: resultImageUrl || vtoExcluded || noFit ? void 0 : handleSingleTryOn,
|
|
18752
19015
|
continueLabel: resultImageUrl ? t2("Continue Shopping") : void 0,
|
|
18753
19016
|
tryOnProcessing,
|
|
18754
19017
|
productImage: resultImageUrl || productImage,
|
|
@@ -18757,7 +19020,7 @@ function SizeResultView({
|
|
|
18757
19020
|
renderRaw: isAccessory,
|
|
18758
19021
|
isTryOnImage: !!resultImageUrl,
|
|
18759
19022
|
showLines,
|
|
18760
|
-
onToggleLines: () => setShowLines(!showLines),
|
|
19023
|
+
onToggleLines: isAccessory ? void 0 : () => setShowLines(!showLines),
|
|
18761
19024
|
onImageLoad: handleImgLoad,
|
|
18762
19025
|
overlayNode: resultImageUrl && poseReady && poseLines ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18763
19026
|
MeasurementOverlay,
|
|
@@ -18778,7 +19041,7 @@ function SizeResultView({
|
|
|
18778
19041
|
/* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: resultImageUrl || productImage, alt: productTitle, className: "ps-tryon-v2-bg-img", onLoad: handleImgLoad }),
|
|
18779
19042
|
resultImageUrl && poseReady && poseLines && /* @__PURE__ */ jsxRuntimeExports.jsx(MeasurementOverlay, { lines: poseLines, fitRows: (sizingResult?.matchDetails || []).map((m2) => ({ area: m2.measurement, userNum: parseFloat(m2.userValue) || 0, chartLabel: m2.chartRange || "", fit: m2.fit })), show: showLines, imgWidth: imgDims.w, imgHeight: imgDims.h }),
|
|
18780
19043
|
resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "absolute", bottom: "0.5vw", left: "0.5vw", zIndex: 3, display: "flex", flexDirection: "column", gap: "0.3vw" }, children: [
|
|
18781
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setShowLines(!showLines), children: showLines ? t2("Hide Fit") : t2("Show Fit") }),
|
|
19044
|
+
!isAccessory && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setShowLines(!showLines), children: showLines ? t2("Hide Fit") : t2("Show Fit") }),
|
|
18782
19045
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: handleDownload, children: t2("Download") })
|
|
18783
19046
|
] })
|
|
18784
19047
|
] }),
|
|
@@ -18788,6 +19051,7 @@ function SizeResultView({
|
|
|
18788
19051
|
sectionName,
|
|
18789
19052
|
section: singleSection,
|
|
18790
19053
|
sectionResult: singleResult,
|
|
19054
|
+
sectionFound: sizingResult?.found,
|
|
18791
19055
|
userMeasurements: singleUserMeasurements,
|
|
18792
19056
|
unitLbl,
|
|
18793
19057
|
chartUnit: resultUnit,
|
|
@@ -18795,7 +19059,7 @@ function SizeResultView({
|
|
|
18795
19059
|
onBack: resultImageUrl ? onClose || (() => setView("body-profile")) : () => setView("body-profile"),
|
|
18796
19060
|
backLabel: t2("Back"),
|
|
18797
19061
|
internationalSizes: sizingResult?.internationalSizes,
|
|
18798
|
-
onTryOn: resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
19062
|
+
onTryOn: resultImageUrl || vtoExcluded || noFit ? void 0 : handleSingleTryOn,
|
|
18799
19063
|
continueLabel: resultImageUrl ? t2("Continue Shopping") : void 0,
|
|
18800
19064
|
tryOnProcessing,
|
|
18801
19065
|
t: t2,
|
|
@@ -19171,7 +19435,7 @@ function UploadView({
|
|
|
19171
19435
|
}
|
|
19172
19436
|
) });
|
|
19173
19437
|
}
|
|
19174
|
-
const RING_RADIUS =
|
|
19438
|
+
const RING_RADIUS = 27;
|
|
19175
19439
|
const RING_CIRCUMFERENCE = 2 * Math.PI * RING_RADIUS;
|
|
19176
19440
|
function ProcessingView({
|
|
19177
19441
|
previewUrl,
|
|
@@ -19216,12 +19480,12 @@ function ProcessingView({
|
|
|
19216
19480
|
] }),
|
|
19217
19481
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-progress-section", children: [
|
|
19218
19482
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-progress-ring", children: [
|
|
19219
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0
|
|
19483
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 64 64", width: "64", height: "64", "aria-hidden": "true", children: [
|
|
19220
19484
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19221
19485
|
"circle",
|
|
19222
19486
|
{
|
|
19223
|
-
cx: "
|
|
19224
|
-
cy: "
|
|
19487
|
+
cx: "32",
|
|
19488
|
+
cy: "32",
|
|
19225
19489
|
r: RING_RADIUS,
|
|
19226
19490
|
className: "ps-tryon-progress-ring-track"
|
|
19227
19491
|
}
|
|
@@ -19230,8 +19494,8 @@ function ProcessingView({
|
|
|
19230
19494
|
"circle",
|
|
19231
19495
|
{
|
|
19232
19496
|
ref: ringCb,
|
|
19233
|
-
cx: "
|
|
19234
|
-
cy: "
|
|
19497
|
+
cx: "32",
|
|
19498
|
+
cy: "32",
|
|
19235
19499
|
r: RING_RADIUS,
|
|
19236
19500
|
className: "ps-tryon-progress-ring-fill",
|
|
19237
19501
|
strokeDasharray: RING_CIRCUMFERENCE,
|
|
@@ -21801,7 +22065,7 @@ function BodyProfileView({
|
|
|
21801
22065
|
hidePhotoOptions: hasActiveProfileWithMeasurements,
|
|
21802
22066
|
onNext: hasActiveProfileWithMeasurements && onUseActiveProfile ? onUseActiveProfile : handleNext,
|
|
21803
22067
|
canProceed: true,
|
|
21804
|
-
fastPathLabel: hasActiveProfileWithMeasurements ? t2("Find My Best Fit") : void 0,
|
|
22068
|
+
fastPathLabel: hasActiveProfileWithMeasurements ? t2("Find My Best Fit") + (getUnitLabel(hUnit) ? ` (${getUnitLabel(hUnit)})` : "") : void 0,
|
|
21805
22069
|
activeProfileName: hasActiveProfileWithMeasurements ? activeProfileName : null,
|
|
21806
22070
|
onStartFresh,
|
|
21807
22071
|
error,
|
|
@@ -22056,7 +22320,8 @@ function BodyProfileView({
|
|
|
22056
22320
|
!(isMobile && step === "basics") && (() => {
|
|
22057
22321
|
const useProfileFast = step === "basics" && hasActiveProfileWithMeasurements && !!onUseActiveProfile;
|
|
22058
22322
|
const handleClick = useProfileFast ? onUseActiveProfile : handleNext;
|
|
22059
|
-
const
|
|
22323
|
+
const unitSuffix = getUnitLabel(hUnit) ? ` (${getUnitLabel(hUnit)})` : "";
|
|
22324
|
+
const label = useProfileFast ? t2("Find My Best Fit") + unitSuffix : isLastStep ? t2("Find My Size") + unitSuffix : t2("Next");
|
|
22060
22325
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-nav", children: [
|
|
22061
22326
|
step !== "basics" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-bp-back-btn", onClick: handleBackStep, type: "button", children: [
|
|
22062
22327
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
|
|
@@ -22246,6 +22511,7 @@ function AccessorySizeView({
|
|
|
22246
22511
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bpm-bottom", children: [
|
|
22247
22512
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-bpm-next-btn", onClick: handleManualSubmit, children: [
|
|
22248
22513
|
t2("Find My Size"),
|
|
22514
|
+
getUnitLabel(sizingUnit) ? ` (${getUnitLabel(sizingUnit)})` : "",
|
|
22249
22515
|
" ",
|
|
22250
22516
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRightIcon, {})
|
|
22251
22517
|
] }),
|
|
@@ -22580,6 +22846,7 @@ function AccessorySizeView({
|
|
|
22580
22846
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {}),
|
|
22581
22847
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-bp-next-btn", onClick: handleManualSubmit, type: "button", children: [
|
|
22582
22848
|
t2("Find My Size"),
|
|
22849
|
+
getUnitLabel(sizingUnit) ? ` (${getUnitLabel(sizingUnit)})` : "",
|
|
22583
22850
|
" ",
|
|
22584
22851
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRightIcon, {})
|
|
22585
22852
|
] })
|
|
@@ -22813,6 +23080,9 @@ function PrimeStyleTryonInner({
|
|
|
22813
23080
|
const [sizingUnit, setSizingUnit] = reactExports.useState(imperial ? "in" : "cm");
|
|
22814
23081
|
const [heightUnit, setHeightUnit] = reactExports.useState(imperial ? "in" : "cm");
|
|
22815
23082
|
const [weightUnit, setWeightUnit] = reactExports.useState(imperial ? "lbs" : "kg");
|
|
23083
|
+
reactExports.useEffect(() => {
|
|
23084
|
+
if (detectMeasurementType(productTitle) === "foot") setSizingUnit("cm");
|
|
23085
|
+
}, [productTitle]);
|
|
22816
23086
|
const formRef = reactExports.useRef({});
|
|
22817
23087
|
const [formGender, setFormGender] = reactExports.useState("male");
|
|
22818
23088
|
const [formKey, setFormKey] = reactExports.useState(0);
|
|
@@ -22887,7 +23157,7 @@ function PrimeStyleTryonInner({
|
|
|
22887
23157
|
{ at: 75, text: t2("Refining details...") },
|
|
22888
23158
|
{ at: 90, text: t2("Almost there...") }
|
|
22889
23159
|
];
|
|
22890
|
-
const RING_CIRCUMFERENCE2 = 2 * Math.PI *
|
|
23160
|
+
const RING_CIRCUMFERENCE2 = 2 * Math.PI * 27;
|
|
22891
23161
|
progressIntervalRef.current = setInterval(() => {
|
|
22892
23162
|
if (completedRef.current) return;
|
|
22893
23163
|
const startTs = progressStartTsRef.current || Date.now();
|
|
@@ -23065,13 +23335,10 @@ function PrimeStyleTryonInner({
|
|
|
23065
23335
|
[activeProfileId, profiles, apiUrl, productImage, productTitle, effectiveProductId, setActiveProfileId$1]
|
|
23066
23336
|
);
|
|
23067
23337
|
const snapSubmitRef = reactExports.useRef(null);
|
|
23068
|
-
const
|
|
23069
|
-
|
|
23070
|
-
if (!p2) return;
|
|
23338
|
+
const [confirmProfile, setConfirmProfile] = reactExports.useState(null);
|
|
23339
|
+
const runRecommendWithProfile = reactExports.useCallback(async (p2) => {
|
|
23071
23340
|
const profileHeight = p2.height ?? p2.heightCm ?? 0;
|
|
23072
23341
|
const profileWeight = p2.weight ?? p2.weightKg ?? 0;
|
|
23073
|
-
const hasIdentity = profileHeight > 0 && profileWeight > 0;
|
|
23074
|
-
if (!hasIdentity) return;
|
|
23075
23342
|
const hasStored = !!p2.measurements && Object.keys(p2.measurements).length > 0;
|
|
23076
23343
|
const storedPhoto = p2.photoBase64;
|
|
23077
23344
|
if (!hasStored && storedPhoto && profileHeight > 0 && snapSubmitRef.current) {
|
|
@@ -23095,9 +23362,8 @@ function PrimeStyleTryonInner({
|
|
|
23095
23362
|
}
|
|
23096
23363
|
setSizingResult(null);
|
|
23097
23364
|
setSizingLoading(true);
|
|
23098
|
-
|
|
23099
|
-
|
|
23100
|
-
if (hasStoredMeasurements) {
|
|
23365
|
+
setEstimationDone(hasStored);
|
|
23366
|
+
if (hasStored) {
|
|
23101
23367
|
setPreviewUrl(null);
|
|
23102
23368
|
setBodyLandmarks(null);
|
|
23103
23369
|
}
|
|
@@ -23130,7 +23396,27 @@ function PrimeStyleTryonInner({
|
|
|
23130
23396
|
setEstimationDone(true);
|
|
23131
23397
|
}).catch(() => {
|
|
23132
23398
|
}).finally(() => setSizingLoading(false));
|
|
23133
|
-
}, [
|
|
23399
|
+
}, [effectiveProductId, productTitle, productImage, sizeGuideData, apiUrl, previewUrl]);
|
|
23400
|
+
const handleUseActiveProfile = reactExports.useCallback(async () => {
|
|
23401
|
+
const p2 = profiles.find((x2) => x2.id === activeProfileId);
|
|
23402
|
+
if (!p2) return;
|
|
23403
|
+
const profileHeight = p2.height ?? p2.heightCm ?? 0;
|
|
23404
|
+
const profileWeight = p2.weight ?? p2.weightKg ?? 0;
|
|
23405
|
+
const hasIdentity = profileHeight > 0 && profileWeight > 0;
|
|
23406
|
+
if (!hasIdentity) return;
|
|
23407
|
+
setConfirmProfile(p2);
|
|
23408
|
+
}, [profiles, activeProfileId]);
|
|
23409
|
+
const proceedFromConfirmProfile = reactExports.useCallback(() => {
|
|
23410
|
+
if (!confirmProfile) return;
|
|
23411
|
+
const p2 = confirmProfile;
|
|
23412
|
+
setConfirmProfile(null);
|
|
23413
|
+
void runRecommendWithProfile(p2);
|
|
23414
|
+
}, [confirmProfile, runRecommendWithProfile]);
|
|
23415
|
+
const cancelFromConfirmProfile = reactExports.useCallback(() => {
|
|
23416
|
+
setConfirmProfile(null);
|
|
23417
|
+
setFormKey((k2) => k2 + 1);
|
|
23418
|
+
setView("body-profile");
|
|
23419
|
+
}, []);
|
|
23134
23420
|
const applyProfileRef = reactExports.useRef(() => {
|
|
23135
23421
|
});
|
|
23136
23422
|
const handleOpen = reactExports.useCallback(() => {
|
|
@@ -24505,6 +24791,15 @@ function PrimeStyleTryonInner({
|
|
|
24505
24791
|
onCancel: () => setDeleteConfirmId(null),
|
|
24506
24792
|
t: t2
|
|
24507
24793
|
}
|
|
24794
|
+
),
|
|
24795
|
+
confirmProfile && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
24796
|
+
ConfirmMeasurementsModal,
|
|
24797
|
+
{
|
|
24798
|
+
profile: confirmProfile,
|
|
24799
|
+
onProceed: proceedFromConfirmProfile,
|
|
24800
|
+
onEdit: cancelFromConfirmProfile,
|
|
24801
|
+
t: t2
|
|
24802
|
+
}
|
|
24508
24803
|
)
|
|
24509
24804
|
] }) }),
|
|
24510
24805
|
document.body
|