@primestyleai/tryon 5.10.188 → 5.10.189

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.
@@ -15,6 +15,10 @@ export interface TryOnContext {
15
15
  * — forwarded to the prompt so Gemini drapes the fabric correctly without
16
16
  * having to guess from the image alone. */
17
17
  productMaterial?: string;
18
+ /** Optional clean product/detail image. The backend sends it to Gemini as an
19
+ * additional design reference while `garmentImage` remains the worn/model
20
+ * styling reference. */
21
+ garmentDetailImage?: string;
18
22
  /** Optional silhouette-prompt context forwarded to the backend Gemini try-on
19
23
  * call. Enables doc-example-grade fit reasoning ("X tension at button
20
24
  * because waist 54.4 exceeds size 50 drop"). All fields optional. */
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- const y = "ps_session";
3
- const P = "ps_mem_";
2
+ const f = "ps_session";
3
+ const A = "ps_mem_";
4
4
  let S = null;
5
5
  function E() {
6
6
  try {
@@ -9,20 +9,20 @@ function E() {
9
9
  return !1;
10
10
  }
11
11
  }
12
- function A() {
12
+ function P() {
13
13
  if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
14
14
  return crypto.randomUUID();
15
- const t = "0123456789abcdef";
16
- let e = P;
17
- for (let o = 0; o < 32; o++) e += t[Math.floor(Math.random() * 16)];
15
+ const r = "0123456789abcdef";
16
+ let e = A;
17
+ for (let o = 0; o < 32; o++) e += r[Math.floor(Math.random() * 16)];
18
18
  return e;
19
19
  }
20
- function T() {
20
+ function I() {
21
21
  if (!E()) return S;
22
22
  try {
23
- const t = window.localStorage.getItem(y);
24
- if (!t) return null;
25
- const e = JSON.parse(t);
23
+ const r = window.localStorage.getItem(f);
24
+ if (!r) return null;
25
+ const e = JSON.parse(r);
26
26
  return typeof e.id != "string" || typeof e.issuedAt != "number" ? null : {
27
27
  id: e.id,
28
28
  issuedAt: e.issuedAt,
@@ -32,43 +32,43 @@ function T() {
32
32
  return null;
33
33
  }
34
34
  }
35
- function g(t) {
36
- if (S = t, !!E())
35
+ function g(r) {
36
+ if (S = r, !!E())
37
37
  try {
38
- window.localStorage.setItem(y, JSON.stringify(t));
38
+ window.localStorage.setItem(f, JSON.stringify(r));
39
39
  } catch {
40
40
  }
41
41
  }
42
42
  function p() {
43
- const t = Date.now(), e = T();
44
- if (e && t - e.lastSeenAt < 2592e6)
45
- return t - e.lastSeenAt > 5 * 60 * 1e3 && g({ ...e, lastSeenAt: t }), e.id;
46
- const o = { id: A(), issuedAt: t, lastSeenAt: t };
43
+ const r = Date.now(), e = I();
44
+ if (e && r - e.lastSeenAt < 2592e6)
45
+ return r - e.lastSeenAt > 5 * 60 * 1e3 && g({ ...e, lastSeenAt: r }), e.id;
46
+ const o = { id: P(), issuedAt: r, lastSeenAt: r };
47
47
  return g(o), o.id;
48
48
  }
49
- function f() {
49
+ function y() {
50
50
  if (typeof navigator > "u") return null;
51
- const t = (navigator.userAgent || "").toLowerCase();
52
- return /ipad|tablet|(android(?!.*mobile))/.test(t) ? "tablet" : /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(t) ? "mobile" : "desktop";
51
+ const r = (navigator.userAgent || "").toLowerCase();
52
+ return /ipad|tablet|(android(?!.*mobile))/.test(r) ? "tablet" : /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(r) ? "mobile" : "desktop";
53
53
  }
54
- const I = "http://localhost:4000";
54
+ const T = "http://localhost:4000";
55
55
  class W {
56
56
  constructor(e, o) {
57
- this.apiKey = e || void 0, this.baseUrl = (o || I).replace(/\/+$/, "");
57
+ this.apiKey = e || void 0, this.baseUrl = (o || T).replace(/\/+$/, "");
58
58
  }
59
59
  get headers() {
60
60
  return w(this.apiKey);
61
61
  }
62
- async submitTryOn(e, o, a, s, r) {
62
+ async submitTryOn(e, o, a, s, t) {
63
63
  const i = {
64
64
  garmentImage: o,
65
65
  // Attribution fields — backend logs these into the TryOnEvent collection
66
66
  // so non-technical operators can answer "which products are being tried on
67
67
  // and by how many customers". Safe fallbacks when absent.
68
68
  sessionId: p(),
69
- deviceHint: f()
69
+ deviceHint: y()
70
70
  };
71
- if (r?.modelImageId && (i.modelImageId = r.modelImageId), e && (i.modelImage = e), a && a.length > 0 && (i.fitInfo = a), s && s !== "apparel" && (i.category = s), r?.productId && (i.productId = r.productId), r?.productTitle && (i.productTitle = r.productTitle), r?.productCategory && (i.productCategory = r.productCategory), r?.productSubcategory && (i.productSubcategory = r.productSubcategory), r?.productFitType && (i.productFitType = r.productFitType), r?.productType && (i.productType = r.productType), r?.productTags?.length && (i.productTags = r.productTags), r?.productDescription && (i.productDescription = r.productDescription), r?.productMaterial && (i.productMaterial = r.productMaterial), r?.silhouetteContext && (i.silhouetteContext = r.silhouetteContext), r?.editFromPrevious && (i.editFromPrevious = !0), a && a.length > 0)
71
+ if (t?.modelImageId && (i.modelImageId = t.modelImageId), e && (i.modelImage = e), a && a.length > 0 && (i.fitInfo = a), s && s !== "apparel" && (i.category = s), t?.productId && (i.productId = t.productId), t?.productTitle && (i.productTitle = t.productTitle), t?.productCategory && (i.productCategory = t.productCategory), t?.productSubcategory && (i.productSubcategory = t.productSubcategory), t?.productFitType && (i.productFitType = t.productFitType), t?.productType && (i.productType = t.productType), t?.productTags?.length && (i.productTags = t.productTags), t?.productDescription && (i.productDescription = t.productDescription), t?.productMaterial && (i.productMaterial = t.productMaterial), t?.garmentDetailImage && t.garmentDetailImage !== o && (i.garmentDetailImage = t.garmentDetailImage), t?.silhouetteContext && (i.silhouetteContext = t.silhouetteContext), t?.editFromPrevious && (i.editFromPrevious = !0), a && a.length > 0)
72
72
  for (const n of a) {
73
73
  const l = (n.garmentRange || "").replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((u) => !isNaN(u));
74
74
  if (l.length && n.userValue != null) {
@@ -113,7 +113,7 @@ class W {
113
113
  body: JSON.stringify({
114
114
  ...e,
115
115
  sessionId: p(),
116
- deviceHint: f()
116
+ deviceHint: y()
117
117
  })
118
118
  });
119
119
  if (!o.ok) {
@@ -130,9 +130,9 @@ class W {
130
130
  return this.apiKey ? `${e}?key=${encodeURIComponent(this.apiKey)}` : e;
131
131
  }
132
132
  }
133
- function w(t) {
133
+ function w(r) {
134
134
  const e = { "Content-Type": "application/json" };
135
- return t && (e.Authorization = `Bearer ${t}`), e;
135
+ return r && (e.Authorization = `Bearer ${r}`), e;
136
136
  }
137
137
  class h extends Error {
138
138
  constructor(e, o) {
@@ -191,9 +191,9 @@ class Y {
191
191
  }
192
192
  }
193
193
  const v = 512, C = 0.65;
194
- function z(t, e = {}) {
194
+ function z(r, e = {}) {
195
195
  const o = e.maxDimension ?? v, a = e.quality ?? C;
196
- return new Promise((s, r) => {
196
+ return new Promise((s, t) => {
197
197
  const i = new FileReader();
198
198
  i.onload = () => {
199
199
  const d = new Image();
@@ -204,25 +204,25 @@ function z(t, e = {}) {
204
204
  (l > o || u > o) && (l > u ? (u = Math.round(u * o / l), l = o) : (l = Math.round(l * o / u), u = o)), n.width = l, n.height = u;
205
205
  const m = n.getContext("2d");
206
206
  if (!m) {
207
- r(new Error("Canvas context not available"));
207
+ t(new Error("Canvas context not available"));
208
208
  return;
209
209
  }
210
210
  m.drawImage(d, 0, 0, l, u);
211
211
  const b = n.toDataURL("image/jpeg", a);
212
212
  s(b);
213
213
  } catch (n) {
214
- r(n);
214
+ t(n);
215
215
  }
216
- }, d.onerror = () => r(new Error("Failed to load image")), d.src = i.result;
217
- }, i.onerror = () => r(new Error("Failed to read file")), i.readAsDataURL(t);
216
+ }, d.onerror = () => t(new Error("Failed to load image")), d.src = i.result;
217
+ }, i.onerror = () => t(new Error("Failed to read file")), i.readAsDataURL(r);
218
218
  });
219
219
  }
220
- function F(t) {
221
- return ["image/jpeg", "image/png", "image/webp", "image/avif"].includes(t.type);
220
+ function F(r) {
221
+ return ["image/jpeg", "image/png", "image/webp", "image/avif"].includes(r.type);
222
222
  }
223
- async function K(t, e, o) {
223
+ async function K(r, e, o) {
224
224
  try {
225
- const a = typeof t == "string" ? t : await z(t, { maxDimension: 384, quality: 0.6 }), s = await fetch(`${e}/api/v1/sizing/age-check`, {
225
+ const a = typeof r == "string" ? r : await z(r, { maxDimension: 384, quality: 0.6 }), s = await fetch(`${e}/api/v1/sizing/age-check`, {
226
226
  method: "POST",
227
227
  headers: {
228
228
  "Content-Type": "application/json",
@@ -232,24 +232,24 @@ async function K(t, e, o) {
232
232
  });
233
233
  if (!s.ok)
234
234
  return { isAdult: !0, confidence: "low" };
235
- const r = await s.json();
235
+ const t = await s.json();
236
236
  return {
237
- isAdult: r?.isAdult !== !1,
237
+ isAdult: t?.isAdult !== !1,
238
238
  // anything other than explicit false → allow
239
- confidence: r?.confidence === "high" ? "high" : "low",
240
- detectedGender: r?.detectedGender === "male" || r?.detectedGender === "female" || r?.detectedGender === "unknown" ? r.detectedGender : void 0,
241
- reasoning: typeof r?.reasoning == "string" ? r.reasoning : void 0
239
+ confidence: t?.confidence === "high" ? "high" : "low",
240
+ detectedGender: t?.detectedGender === "male" || t?.detectedGender === "female" || t?.detectedGender === "unknown" ? t.detectedGender : void 0,
241
+ reasoning: typeof t?.reasoning == "string" ? t.reasoning : void 0
242
242
  };
243
243
  } catch {
244
244
  return { isAdult: !0, confidence: "low" };
245
245
  }
246
246
  }
247
247
  const c = {};
248
- function U(t, e) {
249
- c[t] = { ...c[t] || {}, ...e };
248
+ function U(r, e) {
249
+ c[r] = { ...c[r] || {}, ...e };
250
250
  }
251
- function V(t) {
252
- const e = t?.toLowerCase().split("-")[0] || "en";
251
+ function V(r) {
252
+ const e = r?.toLowerCase().split("-")[0] || "en";
253
253
  return (o) => e === "en" || !c[e] ? o : c[e][o] ?? o;
254
254
  }
255
255
  function j() {
@@ -607,8 +607,6 @@ const J = [
607
607
  Loose: "Holgado",
608
608
  Short: "Corto",
609
609
  Long: "Largo",
610
- Perfect: "Perfecto",
611
- "Perfect fit": "Ajuste perfecto",
612
610
  "✓ Fit": "✓ Ajuste",
613
611
  "too short": "demasiado corto",
614
612
  "too long": "demasiado largo",
@@ -864,8 +862,6 @@ const J = [
864
862
  Loose: "Lâche",
865
863
  Short: "Court",
866
864
  Long: "Long",
867
- Perfect: "Parfait",
868
- "Perfect fit": "Ajustement parfait",
869
865
  "✓ Fit": "✓ Ajusté",
870
866
  "too short": "trop court",
871
867
  "too long": "trop long",
@@ -1121,8 +1117,6 @@ const J = [
1121
1117
  Loose: "Locker",
1122
1118
  Short: "Kurz",
1123
1119
  Long: "Lang",
1124
- Perfect: "Perfekt",
1125
- "Perfect fit": "Perfekte Passform",
1126
1120
  "✓ Fit": "✓ Passt",
1127
1121
  "too short": "zu kurz",
1128
1122
  "too long": "zu lang",
@@ -1378,8 +1372,6 @@ const J = [
1378
1372
  Loose: "Largo",
1379
1373
  Short: "Corto",
1380
1374
  Long: "Lungo",
1381
- Perfect: "Perfetto",
1382
- "Perfect fit": "Vestibilità perfetta",
1383
1375
  "✓ Fit": "✓ Adatto",
1384
1376
  "too short": "troppo corto",
1385
1377
  "too long": "troppo lungo",
@@ -1635,8 +1627,6 @@ const J = [
1635
1627
  Loose: "Folgado",
1636
1628
  Short: "Curto",
1637
1629
  Long: "Longo",
1638
- Perfect: "Perfeito",
1639
- "Perfect fit": "Caimento perfeito",
1640
1630
  "✓ Fit": "✓ Caimento",
1641
1631
  "too short": "muito curto",
1642
1632
  "too long": "muito longo",
@@ -1892,8 +1882,6 @@ const J = [
1892
1882
  Loose: "ゆるい",
1893
1883
  Short: "短い",
1894
1884
  Long: "長い",
1895
- Perfect: "ぴったり",
1896
- "Perfect fit": "ぴったりフィット",
1897
1885
  "✓ Fit": "✓ フィット",
1898
1886
  "too short": "短すぎる",
1899
1887
  "too long": "長すぎる",
@@ -2149,8 +2137,6 @@ const J = [
2149
2137
  Loose: "松",
2150
2138
  Short: "短",
2151
2139
  Long: "长",
2152
- Perfect: "完美",
2153
- "Perfect fit": "完美合身",
2154
2140
  "✓ Fit": "✓ 合身",
2155
2141
  "too short": "太短",
2156
2142
  "too long": "太长",
@@ -2406,8 +2392,6 @@ const J = [
2406
2392
  Loose: "헐렁한",
2407
2393
  Short: "짧은",
2408
2394
  Long: "긴",
2409
- Perfect: "완벽",
2410
- "Perfect fit": "완벽한 핏",
2411
2395
  "✓ Fit": "✓ 적합",
2412
2396
  "too short": "너무 짧음",
2413
2397
  "too long": "너무 김",
@@ -2663,8 +2647,6 @@ const J = [
2663
2647
  Loose: "فضفاض",
2664
2648
  Short: "قصير",
2665
2649
  Long: "طويل",
2666
- Perfect: "مثالي",
2667
- "Perfect fit": "مقاس مثالي",
2668
2650
  "✓ Fit": "✓ مناسب",
2669
2651
  "too short": "قصير جداً",
2670
2652
  "too long": "طويل جداً",
@@ -2787,23 +2769,23 @@ const J = [
2787
2769
  ko: L,
2788
2770
  ar: G
2789
2771
  };
2790
- for (const [t, e] of Object.entries(O))
2791
- U(t, e);
2772
+ for (const [r, e] of Object.entries(O))
2773
+ U(r, e);
2792
2774
  export {
2793
2775
  W as A,
2794
2776
  q as L,
2795
2777
  h as P,
2796
- Y as S,
2778
+ J as S,
2797
2779
  Z as T,
2798
- z as a,
2799
- J as b,
2800
- V as c,
2801
- K as d,
2780
+ Y as a,
2781
+ z as b,
2782
+ K as c,
2783
+ V as d,
2802
2784
  j as e,
2803
- f,
2804
- p as g,
2785
+ p as f,
2786
+ y as g,
2805
2787
  F as i,
2806
2788
  w as j,
2807
2789
  U as r
2808
2790
  };
2809
- //# sourceMappingURL=index-BduSFARG.js.map
2791
+ //# sourceMappingURL=index-BlzviBfP.js.map