@primestyleai/tryon 5.8.13 → 5.8.15

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.
@@ -6800,7 +6800,10 @@ function SectionDetailView({
6800
6800
  showLines,
6801
6801
  onToggleLines,
6802
6802
  overlayNode,
6803
- onImageLoad
6803
+ onImageLoad,
6804
+ onTryOn,
6805
+ tryOnProcessing,
6806
+ backLabel
6804
6807
  }) {
6805
6808
  const recSize = sectionResult?.recommendedSize || "";
6806
6809
  const [selectedSize, setSelectedSize] = useState(null);
@@ -6831,50 +6834,71 @@ function SectionDetailView({
6831
6834
  }, [section, sizeColIdx, sizeHeader]);
6832
6835
  const displaySize = selectedSize || recSize;
6833
6836
  const isRecommended = displaySize === recSize;
6834
- const chartRangeFor = useCallback((measurement, size) => {
6835
- const b = measurement.toLowerCase().trim();
6836
- const preferCm = unitLbl === "cm" || unitLbl === "";
6837
- let mc = -1;
6837
+ const columnUnits = useMemo(() => {
6838
+ const units = [];
6838
6839
  for (let i = 0; i < section.headers.length; i++) {
6839
- const a = section.headers[i].toLowerCase().trim();
6840
- if (a === b) {
6841
- mc = i;
6842
- break;
6840
+ const h = (section.headers[i] || "").toLowerCase();
6841
+ if (/\(cm\)|centimeter/i.test(h)) {
6842
+ units.push("cm");
6843
+ continue;
6843
6844
  }
6844
- if (a.includes(b) || b.includes(a.replace(/\s*\(.*?\)\s*/g, "").trim())) {
6845
- const hasCm = /\(cm\)|centimeter/i.test(a);
6846
- const hasIn = /\(in\)|inch/i.test(a);
6847
- if (preferCm && hasCm) {
6848
- mc = i;
6845
+ if (/\(in\)|\(inch|inch/i.test(h)) {
6846
+ units.push("in");
6847
+ continue;
6848
+ }
6849
+ let inferred = null;
6850
+ for (const row of section.rows) {
6851
+ const cell = String(cellValFn(row, i, section.headers[i]) || "").trim();
6852
+ if (!cell) continue;
6853
+ if (/cm\b|centimeter/i.test(cell)) {
6854
+ inferred = "cm";
6849
6855
  break;
6850
6856
  }
6851
- if (!preferCm && hasIn) {
6852
- mc = i;
6857
+ if (/in\b|inch|"$/i.test(cell)) {
6858
+ inferred = "in";
6853
6859
  break;
6854
6860
  }
6855
- if (mc < 0) mc = i;
6861
+ }
6862
+ units.push(inferred);
6863
+ }
6864
+ return units;
6865
+ }, [section]);
6866
+ const chartRangeFor = useCallback((measurement, size) => {
6867
+ const b = measurement.toLowerCase().trim();
6868
+ const preferCm = unitLbl === "cm" || unitLbl === "";
6869
+ const wantUnit = preferCm ? "cm" : "in";
6870
+ const candidates = [];
6871
+ for (let i = 0; i < section.headers.length; i++) {
6872
+ const a = (section.headers[i] || "").toLowerCase().trim();
6873
+ if (a === b) {
6874
+ candidates.push(i);
6875
+ continue;
6876
+ }
6877
+ const aBare = a.replace(/\s*\(.*?\)\s*/g, "").trim();
6878
+ if (aBare === b || a.includes(b) || b.includes(aBare)) {
6879
+ candidates.push(i);
6856
6880
  }
6857
6881
  }
6858
- if (mc < 0) return null;
6882
+ if (candidates.length === 0) return null;
6883
+ let mc = candidates.find((i) => columnUnits[i] === wantUnit);
6884
+ if (mc == null) mc = candidates[0];
6859
6885
  const mHeader = section.headers[mc];
6860
6886
  const row = section.rows.find((r) => cellValFn(r, sizeColIdx, sizeHeader) === size);
6861
6887
  if (!row) return null;
6862
6888
  const val = cellValFn(row, mc, mHeader);
6863
6889
  if (!val) return null;
6864
6890
  const parsed = pRangeFn(val);
6865
- const colHdr = section.headers[mc].toLowerCase();
6866
- const colIsInch = /\(in\)|inch/i.test(colHdr);
6867
- const colIsCm = /\(cm\)|centimeter/i.test(colHdr);
6868
- if (colIsInch && preferCm) {
6891
+ const colUnit = columnUnits[mc];
6892
+ if (colUnit === "in" && preferCm) {
6869
6893
  const toCm = (v) => +(v * 2.54).toFixed(1);
6870
6894
  return { range: String(toCm(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toCm(parsed.max)) : ""), min: toCm(parsed.min), max: toCm(parsed.max) };
6871
6895
  }
6872
- if (colIsCm && !preferCm) {
6896
+ if (colUnit === "cm" && !preferCm) {
6873
6897
  const toIn = (v) => +(v / 2.54).toFixed(1);
6874
6898
  return { range: String(toIn(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toIn(parsed.max)) : ""), min: toIn(parsed.min), max: toIn(parsed.max) };
6875
6899
  }
6876
6900
  return { range: val, ...parsed };
6877
- }, [section, sizeColIdx, sizeHeader, unitLbl]);
6901
+ }, [section, sizeColIdx, sizeHeader, unitLbl, columnUnits]);
6878
6902
  const fitRows = useMemo(() => {
6879
6903
  const mainDetails = sectionResult?.matchDetails || [];
6880
6904
  const lengthDetails = lengthEntry?.secResult?.matchDetails || [];
@@ -7241,9 +7265,41 @@ function SectionDetailView({
7241
7265
  /* @__PURE__ */ jsxs("button", { className: "ps-bp-back-btn", onClick: onBack, type: "button", style: { fontSize: "0.7vw" }, children: [
7242
7266
  /* @__PURE__ */ jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
7243
7267
  " ",
7244
- t("Back to sections")
7268
+ backLabel || t("Back to sections")
7245
7269
  ] }),
7246
- /* @__PURE__ */ jsxs(
7270
+ onTryOn ? /* @__PURE__ */ jsxs(
7271
+ "button",
7272
+ {
7273
+ onClick: onTryOn,
7274
+ disabled: tryOnProcessing,
7275
+ style: {
7276
+ padding: "0.45vw 1.2vw",
7277
+ borderRadius: "0.4vw",
7278
+ fontSize: "0.7vw",
7279
+ fontWeight: 600,
7280
+ background: "var(--ps-accent)",
7281
+ color: "white",
7282
+ border: "none",
7283
+ cursor: tryOnProcessing ? "default" : "pointer",
7284
+ opacity: tryOnProcessing ? 0.6 : 1,
7285
+ fontFamily: "inherit",
7286
+ display: "flex",
7287
+ alignItems: "center",
7288
+ gap: "0.4vw",
7289
+ transition: "opacity 0.2s"
7290
+ },
7291
+ onMouseEnter: (e) => {
7292
+ if (!tryOnProcessing) e.currentTarget.style.opacity = "0.9";
7293
+ },
7294
+ onMouseLeave: (e) => {
7295
+ if (!tryOnProcessing) e.currentTarget.style.opacity = "1";
7296
+ },
7297
+ children: [
7298
+ /* @__PURE__ */ jsx(CameraIcon$1, { size: 12 }),
7299
+ tryOnProcessing ? t("Processing...") : t("Try It On")
7300
+ ]
7301
+ }
7302
+ ) : /* @__PURE__ */ jsxs(
7247
7303
  "button",
7248
7304
  {
7249
7305
  onClick: onBack,
@@ -7321,40 +7377,73 @@ function SizeResultView({
7321
7377
  if (sizeColIdx < 0 || !sizeGuide?.rows) return [];
7322
7378
  return sizeGuide.rows.map((r) => cellVal(r, sizeColIdx, sizeHeader)).filter(Boolean);
7323
7379
  }, [sizeGuide, sizeColIdx, sizeHeader, cellVal]);
7380
+ const sizeGuideColumnUnits = useMemo(() => {
7381
+ if (!sizeGuide?.headers || !sizeGuide?.rows) return [];
7382
+ const units = [];
7383
+ for (let i = 0; i < sizeGuide.headers.length; i++) {
7384
+ const h = (sizeGuide.headers[i] || "").toLowerCase();
7385
+ if (/\(cm\)|centimeter/i.test(h)) {
7386
+ units.push("cm");
7387
+ continue;
7388
+ }
7389
+ if (/\(in\)|\(inch|inch/i.test(h)) {
7390
+ units.push("in");
7391
+ continue;
7392
+ }
7393
+ let inferred = null;
7394
+ for (const row of sizeGuide.rows) {
7395
+ const cell = String(cellVal(row, i, sizeGuide.headers[i]) || "").trim();
7396
+ if (!cell) continue;
7397
+ if (/cm\b|centimeter/i.test(cell)) {
7398
+ inferred = "cm";
7399
+ break;
7400
+ }
7401
+ if (/in\b|inch|"$/i.test(cell)) {
7402
+ inferred = "in";
7403
+ break;
7404
+ }
7405
+ }
7406
+ units.push(inferred);
7407
+ }
7408
+ return units;
7409
+ }, [sizeGuide, cellVal]);
7324
7410
  const chartRangeFor = useCallback((measurement, size) => {
7325
7411
  if (!sizeGuide?.headers || !sizeGuide?.rows || sizeColIdx < 0) return null;
7326
7412
  const b = measurement.toLowerCase().trim();
7327
7413
  const preferCm = unitLbl === "cm" || unitLbl === "";
7328
- let mc = -1;
7414
+ const wantUnit = preferCm ? "cm" : "in";
7415
+ const candidates = [];
7329
7416
  for (let i = 0; i < sizeGuide.headers.length; i++) {
7330
- const a = sizeGuide.headers[i].toLowerCase().trim();
7417
+ const a = (sizeGuide.headers[i] || "").toLowerCase().trim();
7331
7418
  if (a === b) {
7332
- mc = i;
7333
- break;
7419
+ candidates.push(i);
7420
+ continue;
7334
7421
  }
7335
- if (a.includes(b) || b.includes(a.replace(/\s*\(.*?\)\s*/g, "").trim())) {
7336
- const hasCm = /\(cm\)|centimeter/i.test(a);
7337
- const hasIn = /\(in\)|inch/i.test(a);
7338
- if (preferCm && hasCm) {
7339
- mc = i;
7340
- break;
7341
- }
7342
- if (!preferCm && hasIn) {
7343
- mc = i;
7344
- break;
7345
- }
7346
- if (mc < 0) mc = i;
7422
+ const aBare = a.replace(/\s*\(.*?\)\s*/g, "").trim();
7423
+ if (aBare === b || a.includes(b) || b.includes(aBare)) {
7424
+ candidates.push(i);
7347
7425
  }
7348
7426
  }
7349
- if (mc < 0) return null;
7427
+ if (candidates.length === 0) return null;
7428
+ let mc = candidates.find((i) => sizeGuideColumnUnits[i] === wantUnit);
7429
+ if (mc == null) mc = candidates[0];
7350
7430
  const mHeader = sizeGuide.headers[mc];
7351
7431
  const row = sizeGuide.rows.find((r) => cellVal(r, sizeColIdx, sizeHeader) === size);
7352
7432
  if (!row) return null;
7353
7433
  const val = cellVal(row, mc, mHeader);
7354
7434
  if (!val) return null;
7355
7435
  const parsed = pRange(val);
7436
+ const colUnit = sizeGuideColumnUnits[mc];
7437
+ if (colUnit === "in" && preferCm) {
7438
+ const toCm = (v) => +(v * 2.54).toFixed(1);
7439
+ return { range: String(toCm(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toCm(parsed.max)) : ""), min: toCm(parsed.min), max: toCm(parsed.max) };
7440
+ }
7441
+ if (colUnit === "cm" && !preferCm) {
7442
+ const toIn = (v) => +(v / 2.54).toFixed(1);
7443
+ return { range: String(toIn(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toIn(parsed.max)) : ""), min: toIn(parsed.min), max: toIn(parsed.max) };
7444
+ }
7356
7445
  return { range: val, ...parsed };
7357
- }, [sizeGuide, sizeColIdx, sizeHeader, unitLbl, cellVal, pRange]);
7446
+ }, [sizeGuide, sizeColIdx, sizeHeader, unitLbl, cellVal, pRange, sizeGuideColumnUnits]);
7358
7447
  const origSize = sizingResult?.recommendedSize || "";
7359
7448
  const activeSize = origSize;
7360
7449
  useMemo(() => {
@@ -7646,7 +7735,7 @@ function SizeResultView({
7646
7735
  sectionEntries: sectionEntries.map(({ name, secResult }) => ({ name, secResult })),
7647
7736
  onSelectSection: (name) => setActiveSection(name),
7648
7737
  onTryOn: () => {
7649
- setGuideFile(null);
7738
+ setGuideFile(selectedFile || null);
7650
7739
  setShowPhotoGuide(true);
7651
7740
  },
7652
7741
  tryOnProcessing,
@@ -7654,7 +7743,7 @@ function SizeResultView({
7654
7743
  tryOnDone: !!resultImageUrl && !tryOnProcessing,
7655
7744
  onTryAgain: () => {
7656
7745
  onResetTryOn?.();
7657
- setGuideFile(null);
7746
+ setGuideFile(selectedFile || null);
7658
7747
  setShowPhotoGuide(true);
7659
7748
  },
7660
7749
  onClose,
@@ -7761,7 +7850,7 @@ function SizeResultView({
7761
7850
  style: { marginTop: 0 },
7762
7851
  disabled: tryOnProcessing,
7763
7852
  onClick: () => {
7764
- setGuideFile(null);
7853
+ setGuideFile(selectedFile || null);
7765
7854
  setShowPhotoGuide(true);
7766
7855
  },
7767
7856
  children: [
@@ -7784,6 +7873,11 @@ function SizeResultView({
7784
7873
  for (const m of sizingResult.matchDetails) singleUserMeasurements[m.measurement.toLowerCase()] = pNumFn(m.userValue);
7785
7874
  }
7786
7875
  const sectionName = t("Your Fit");
7876
+ const handleSingleTryOn = () => {
7877
+ if (resultImageUrl) return;
7878
+ setGuideFile(selectedFile || null);
7879
+ setShowPhotoGuide(true);
7880
+ };
7787
7881
  if (isMobile) {
7788
7882
  return /* @__PURE__ */ jsx(
7789
7883
  SectionDetailView,
@@ -7795,6 +7889,9 @@ function SizeResultView({
7795
7889
  unitLbl,
7796
7890
  lengthEntry: null,
7797
7891
  onBack: () => setView("body-profile"),
7892
+ backLabel: t("Back"),
7893
+ onTryOn: resultImageUrl ? void 0 : handleSingleTryOn,
7894
+ tryOnProcessing,
7798
7895
  productImage: resultImageUrl || productImage,
7799
7896
  productTitle,
7800
7897
  isMobile: true,
@@ -7835,6 +7932,9 @@ function SizeResultView({
7835
7932
  unitLbl,
7836
7933
  lengthEntry: null,
7837
7934
  onBack: () => setView("body-profile"),
7935
+ backLabel: t("Back"),
7936
+ onTryOn: resultImageUrl ? void 0 : handleSingleTryOn,
7937
+ tryOnProcessing,
7838
7938
  t
7839
7939
  }
7840
7940
  ) }, "panel-single")
@@ -16224,7 +16224,10 @@ function SectionDetailView({
16224
16224
  showLines,
16225
16225
  onToggleLines,
16226
16226
  overlayNode,
16227
- onImageLoad
16227
+ onImageLoad,
16228
+ onTryOn,
16229
+ tryOnProcessing,
16230
+ backLabel
16228
16231
  }) {
16229
16232
  const recSize = sectionResult?.recommendedSize || "";
16230
16233
  const [selectedSize, setSelectedSize] = reactExports.useState(null);
@@ -16255,50 +16258,71 @@ function SectionDetailView({
16255
16258
  }, [section, sizeColIdx, sizeHeader]);
16256
16259
  const displaySize = selectedSize || recSize;
16257
16260
  const isRecommended = displaySize === recSize;
16258
- const chartRangeFor = reactExports.useCallback((measurement, size) => {
16259
- const b = measurement.toLowerCase().trim();
16260
- const preferCm = unitLbl === "cm" || unitLbl === "";
16261
- let mc2 = -1;
16261
+ const columnUnits = reactExports.useMemo(() => {
16262
+ const units = [];
16262
16263
  for (let i = 0; i < section.headers.length; i++) {
16263
- const a = section.headers[i].toLowerCase().trim();
16264
- if (a === b) {
16265
- mc2 = i;
16266
- break;
16264
+ const h = (section.headers[i] || "").toLowerCase();
16265
+ if (/\(cm\)|centimeter/i.test(h)) {
16266
+ units.push("cm");
16267
+ continue;
16267
16268
  }
16268
- if (a.includes(b) || b.includes(a.replace(/\s*\(.*?\)\s*/g, "").trim())) {
16269
- const hasCm = /\(cm\)|centimeter/i.test(a);
16270
- const hasIn = /\(in\)|inch/i.test(a);
16271
- if (preferCm && hasCm) {
16272
- mc2 = i;
16269
+ if (/\(in\)|\(inch|inch/i.test(h)) {
16270
+ units.push("in");
16271
+ continue;
16272
+ }
16273
+ let inferred = null;
16274
+ for (const row of section.rows) {
16275
+ const cell = String(cellValFn(row, i, section.headers[i]) || "").trim();
16276
+ if (!cell) continue;
16277
+ if (/cm\b|centimeter/i.test(cell)) {
16278
+ inferred = "cm";
16273
16279
  break;
16274
16280
  }
16275
- if (!preferCm && hasIn) {
16276
- mc2 = i;
16281
+ if (/in\b|inch|"$/i.test(cell)) {
16282
+ inferred = "in";
16277
16283
  break;
16278
16284
  }
16279
- if (mc2 < 0) mc2 = i;
16280
16285
  }
16286
+ units.push(inferred);
16281
16287
  }
16282
- if (mc2 < 0) return null;
16288
+ return units;
16289
+ }, [section]);
16290
+ const chartRangeFor = reactExports.useCallback((measurement, size) => {
16291
+ const b = measurement.toLowerCase().trim();
16292
+ const preferCm = unitLbl === "cm" || unitLbl === "";
16293
+ const wantUnit = preferCm ? "cm" : "in";
16294
+ const candidates = [];
16295
+ for (let i = 0; i < section.headers.length; i++) {
16296
+ const a = (section.headers[i] || "").toLowerCase().trim();
16297
+ if (a === b) {
16298
+ candidates.push(i);
16299
+ continue;
16300
+ }
16301
+ const aBare = a.replace(/\s*\(.*?\)\s*/g, "").trim();
16302
+ if (aBare === b || a.includes(b) || b.includes(aBare)) {
16303
+ candidates.push(i);
16304
+ }
16305
+ }
16306
+ if (candidates.length === 0) return null;
16307
+ let mc2 = candidates.find((i) => columnUnits[i] === wantUnit);
16308
+ if (mc2 == null) mc2 = candidates[0];
16283
16309
  const mHeader = section.headers[mc2];
16284
16310
  const row = section.rows.find((r2) => cellValFn(r2, sizeColIdx, sizeHeader) === size);
16285
16311
  if (!row) return null;
16286
16312
  const val = cellValFn(row, mc2, mHeader);
16287
16313
  if (!val) return null;
16288
16314
  const parsed = pRangeFn(val);
16289
- const colHdr = section.headers[mc2].toLowerCase();
16290
- const colIsInch = /\(in\)|inch/i.test(colHdr);
16291
- const colIsCm = /\(cm\)|centimeter/i.test(colHdr);
16292
- if (colIsInch && preferCm) {
16315
+ const colUnit = columnUnits[mc2];
16316
+ if (colUnit === "in" && preferCm) {
16293
16317
  const toCm = (v2) => +(v2 * 2.54).toFixed(1);
16294
16318
  return { range: String(toCm(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toCm(parsed.max)) : ""), min: toCm(parsed.min), max: toCm(parsed.max) };
16295
16319
  }
16296
- if (colIsCm && !preferCm) {
16320
+ if (colUnit === "cm" && !preferCm) {
16297
16321
  const toIn = (v2) => +(v2 / 2.54).toFixed(1);
16298
16322
  return { range: String(toIn(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toIn(parsed.max)) : ""), min: toIn(parsed.min), max: toIn(parsed.max) };
16299
16323
  }
16300
16324
  return { range: val, ...parsed };
16301
- }, [section, sizeColIdx, sizeHeader, unitLbl]);
16325
+ }, [section, sizeColIdx, sizeHeader, unitLbl, columnUnits]);
16302
16326
  const fitRows = reactExports.useMemo(() => {
16303
16327
  const mainDetails = sectionResult?.matchDetails || [];
16304
16328
  const lengthDetails = lengthEntry?.secResult?.matchDetails || [];
@@ -16665,9 +16689,41 @@ function SectionDetailView({
16665
16689
  /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-bp-back-btn", onClick: onBack, type: "button", style: { fontSize: "0.7vw" }, children: [
16666
16690
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
16667
16691
  " ",
16668
- t2("Back to sections")
16692
+ backLabel || t2("Back to sections")
16669
16693
  ] }),
16670
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
16694
+ onTryOn ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
16695
+ "button",
16696
+ {
16697
+ onClick: onTryOn,
16698
+ disabled: tryOnProcessing,
16699
+ style: {
16700
+ padding: "0.45vw 1.2vw",
16701
+ borderRadius: "0.4vw",
16702
+ fontSize: "0.7vw",
16703
+ fontWeight: 600,
16704
+ background: "var(--ps-accent)",
16705
+ color: "white",
16706
+ border: "none",
16707
+ cursor: tryOnProcessing ? "default" : "pointer",
16708
+ opacity: tryOnProcessing ? 0.6 : 1,
16709
+ fontFamily: "inherit",
16710
+ display: "flex",
16711
+ alignItems: "center",
16712
+ gap: "0.4vw",
16713
+ transition: "opacity 0.2s"
16714
+ },
16715
+ onMouseEnter: (e) => {
16716
+ if (!tryOnProcessing) e.currentTarget.style.opacity = "0.9";
16717
+ },
16718
+ onMouseLeave: (e) => {
16719
+ if (!tryOnProcessing) e.currentTarget.style.opacity = "1";
16720
+ },
16721
+ children: [
16722
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CameraIcon$1, { size: 12 }),
16723
+ tryOnProcessing ? t2("Processing...") : t2("Try It On")
16724
+ ]
16725
+ }
16726
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
16671
16727
  "button",
16672
16728
  {
16673
16729
  onClick: onBack,
@@ -16745,40 +16801,73 @@ function SizeResultView({
16745
16801
  if (sizeColIdx < 0 || !sizeGuide?.rows) return [];
16746
16802
  return sizeGuide.rows.map((r2) => cellVal(r2, sizeColIdx, sizeHeader)).filter(Boolean);
16747
16803
  }, [sizeGuide, sizeColIdx, sizeHeader, cellVal]);
16804
+ const sizeGuideColumnUnits = reactExports.useMemo(() => {
16805
+ if (!sizeGuide?.headers || !sizeGuide?.rows) return [];
16806
+ const units = [];
16807
+ for (let i = 0; i < sizeGuide.headers.length; i++) {
16808
+ const h = (sizeGuide.headers[i] || "").toLowerCase();
16809
+ if (/\(cm\)|centimeter/i.test(h)) {
16810
+ units.push("cm");
16811
+ continue;
16812
+ }
16813
+ if (/\(in\)|\(inch|inch/i.test(h)) {
16814
+ units.push("in");
16815
+ continue;
16816
+ }
16817
+ let inferred = null;
16818
+ for (const row of sizeGuide.rows) {
16819
+ const cell = String(cellVal(row, i, sizeGuide.headers[i]) || "").trim();
16820
+ if (!cell) continue;
16821
+ if (/cm\b|centimeter/i.test(cell)) {
16822
+ inferred = "cm";
16823
+ break;
16824
+ }
16825
+ if (/in\b|inch|"$/i.test(cell)) {
16826
+ inferred = "in";
16827
+ break;
16828
+ }
16829
+ }
16830
+ units.push(inferred);
16831
+ }
16832
+ return units;
16833
+ }, [sizeGuide, cellVal]);
16748
16834
  const chartRangeFor = reactExports.useCallback((measurement, size) => {
16749
16835
  if (!sizeGuide?.headers || !sizeGuide?.rows || sizeColIdx < 0) return null;
16750
16836
  const b = measurement.toLowerCase().trim();
16751
16837
  const preferCm = unitLbl === "cm" || unitLbl === "";
16752
- let mc2 = -1;
16838
+ const wantUnit = preferCm ? "cm" : "in";
16839
+ const candidates = [];
16753
16840
  for (let i = 0; i < sizeGuide.headers.length; i++) {
16754
- const a = sizeGuide.headers[i].toLowerCase().trim();
16841
+ const a = (sizeGuide.headers[i] || "").toLowerCase().trim();
16755
16842
  if (a === b) {
16756
- mc2 = i;
16757
- break;
16843
+ candidates.push(i);
16844
+ continue;
16758
16845
  }
16759
- if (a.includes(b) || b.includes(a.replace(/\s*\(.*?\)\s*/g, "").trim())) {
16760
- const hasCm = /\(cm\)|centimeter/i.test(a);
16761
- const hasIn = /\(in\)|inch/i.test(a);
16762
- if (preferCm && hasCm) {
16763
- mc2 = i;
16764
- break;
16765
- }
16766
- if (!preferCm && hasIn) {
16767
- mc2 = i;
16768
- break;
16769
- }
16770
- if (mc2 < 0) mc2 = i;
16846
+ const aBare = a.replace(/\s*\(.*?\)\s*/g, "").trim();
16847
+ if (aBare === b || a.includes(b) || b.includes(aBare)) {
16848
+ candidates.push(i);
16771
16849
  }
16772
16850
  }
16773
- if (mc2 < 0) return null;
16851
+ if (candidates.length === 0) return null;
16852
+ let mc2 = candidates.find((i) => sizeGuideColumnUnits[i] === wantUnit);
16853
+ if (mc2 == null) mc2 = candidates[0];
16774
16854
  const mHeader = sizeGuide.headers[mc2];
16775
16855
  const row = sizeGuide.rows.find((r2) => cellVal(r2, sizeColIdx, sizeHeader) === size);
16776
16856
  if (!row) return null;
16777
16857
  const val = cellVal(row, mc2, mHeader);
16778
16858
  if (!val) return null;
16779
16859
  const parsed = pRange(val);
16860
+ const colUnit = sizeGuideColumnUnits[mc2];
16861
+ if (colUnit === "in" && preferCm) {
16862
+ const toCm = (v2) => +(v2 * 2.54).toFixed(1);
16863
+ return { range: String(toCm(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toCm(parsed.max)) : ""), min: toCm(parsed.min), max: toCm(parsed.max) };
16864
+ }
16865
+ if (colUnit === "cm" && !preferCm) {
16866
+ const toIn = (v2) => +(v2 / 2.54).toFixed(1);
16867
+ return { range: String(toIn(parsed.min)) + (parsed.min !== parsed.max ? "–" + String(toIn(parsed.max)) : ""), min: toIn(parsed.min), max: toIn(parsed.max) };
16868
+ }
16780
16869
  return { range: val, ...parsed };
16781
- }, [sizeGuide, sizeColIdx, sizeHeader, unitLbl, cellVal, pRange]);
16870
+ }, [sizeGuide, sizeColIdx, sizeHeader, unitLbl, cellVal, pRange, sizeGuideColumnUnits]);
16782
16871
  const origSize = sizingResult?.recommendedSize || "";
16783
16872
  const activeSize = origSize;
16784
16873
  reactExports.useMemo(() => {
@@ -17070,7 +17159,7 @@ function SizeResultView({
17070
17159
  sectionEntries: sectionEntries.map(({ name, secResult }) => ({ name, secResult })),
17071
17160
  onSelectSection: (name) => setActiveSection(name),
17072
17161
  onTryOn: () => {
17073
- setGuideFile(null);
17162
+ setGuideFile(selectedFile || null);
17074
17163
  setShowPhotoGuide(true);
17075
17164
  },
17076
17165
  tryOnProcessing,
@@ -17078,7 +17167,7 @@ function SizeResultView({
17078
17167
  tryOnDone: !!resultImageUrl && !tryOnProcessing,
17079
17168
  onTryAgain: () => {
17080
17169
  onResetTryOn?.();
17081
- setGuideFile(null);
17170
+ setGuideFile(selectedFile || null);
17082
17171
  setShowPhotoGuide(true);
17083
17172
  },
17084
17173
  onClose,
@@ -17185,7 +17274,7 @@ function SizeResultView({
17185
17274
  style: { marginTop: 0 },
17186
17275
  disabled: tryOnProcessing,
17187
17276
  onClick: () => {
17188
- setGuideFile(null);
17277
+ setGuideFile(selectedFile || null);
17189
17278
  setShowPhotoGuide(true);
17190
17279
  },
17191
17280
  children: [
@@ -17208,6 +17297,11 @@ function SizeResultView({
17208
17297
  for (const m2 of sizingResult.matchDetails) singleUserMeasurements[m2.measurement.toLowerCase()] = pNumFn(m2.userValue);
17209
17298
  }
17210
17299
  const sectionName = t2("Your Fit");
17300
+ const handleSingleTryOn = () => {
17301
+ if (resultImageUrl) return;
17302
+ setGuideFile(selectedFile || null);
17303
+ setShowPhotoGuide(true);
17304
+ };
17211
17305
  if (isMobile) {
17212
17306
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
17213
17307
  SectionDetailView,
@@ -17219,6 +17313,9 @@ function SizeResultView({
17219
17313
  unitLbl,
17220
17314
  lengthEntry: null,
17221
17315
  onBack: () => setView("body-profile"),
17316
+ backLabel: t2("Back"),
17317
+ onTryOn: resultImageUrl ? void 0 : handleSingleTryOn,
17318
+ tryOnProcessing,
17222
17319
  productImage: resultImageUrl || productImage,
17223
17320
  productTitle,
17224
17321
  isMobile: true,
@@ -17259,6 +17356,9 @@ function SizeResultView({
17259
17356
  unitLbl,
17260
17357
  lengthEntry: null,
17261
17358
  onBack: () => setView("body-profile"),
17359
+ backLabel: t2("Back"),
17360
+ onTryOn: resultImageUrl ? void 0 : handleSingleTryOn,
17361
+ tryOnProcessing,
17262
17362
  t: t2
17263
17363
  }
17264
17364
  ) }, "panel-single")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "5.8.13",
3
+ "version": "5.8.15",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",