@useinsider/guido 3.13.0 → 3.13.1-beta.77f8a06

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/README.md CHANGED
@@ -134,7 +134,7 @@ const config: GuidoConfigInput = {
134
134
  // Optional: Editor settings
135
135
  editor?: {
136
136
  locale?: string, // Default: 'en'
137
- translationsPath?: string, // Default: 'window.trans.en'
137
+ translationsPath?: string, // Default: first locale registered on window.trans
138
138
  migrationDate?: number, // Stripo migration timestamp
139
139
  emailHeader?: {
140
140
  senderName?: string,
@@ -1,4 +1,7 @@
1
1
  import { ProductType as a, MessageType as o } from "./schemas.js";
2
+ const i = {
3
+ translationsPath: "window.trans[Object.keys(window.trans)[0]]"
4
+ };
2
5
  a.EMAIL;
3
6
  o.PROMOTIONAL;
4
7
  const e = [
@@ -33,12 +36,13 @@ const e = [
33
36
  "vikingsankara",
34
37
  "stripoeditorlivetest"
35
38
  ];
36
- function n(t) {
39
+ function s(t) {
37
40
  return e.includes(t);
38
41
  }
39
42
  export {
43
+ i as DEFAULT_EDITOR,
40
44
  o as MessageType,
41
45
  a as ProductType,
42
46
  e as TEST_PARTNERS,
43
- n as isTestPartner
47
+ s as isTestPartner
44
48
  };
@@ -1,18 +1,20 @@
1
+ import "../@types/config/schemas.js";
2
+ import { DEFAULT_EDITOR } from "../@types/config/defaults.js";
1
3
  import memoize from "../node_modules/lodash-es/memoize.js";
2
4
  import { ref } from "vue";
3
5
  import { useConfig } from "./useConfig.js";
4
6
  const useTranslations = () => {
5
7
  var o, e;
6
- const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || "window.trans.en", translations = ref(eval(translationsPath)), trans = (n, t) => {
7
- const r = translations.value[n];
8
- return r ? t ? Object.entries(t).reduce(
8
+ const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || DEFAULT_EDITOR.translationsPath, translations = ref(eval(translationsPath)), trans = (t, n) => {
9
+ const r = translations.value[t];
10
+ return r ? n ? Object.entries(n).reduce(
9
11
  (s, [i, a]) => s.replace(new RegExp(`{${i}}`, "g"), String(a)),
10
12
  r
11
- ) : r : (console.warn(`Translation key not found: ${n}`), n);
13
+ ) : r : (console.warn(`Translation key not found: ${t}`), t);
12
14
  };
13
15
  return memoize(
14
16
  trans,
15
- (n, t) => !t || Object.keys(t).length === 0 ? n : JSON.stringify({ key: n, params: t })
17
+ (t, n) => !n || Object.keys(n).length === 0 ? t : JSON.stringify({ key: t, params: n })
16
18
  );
17
19
  };
18
20
  export {
@@ -1,14 +1,35 @@
1
- import { pairProductVariables as r } from "../../utils/pairProductVariables.js";
2
- const t = [
1
+ import { pairProductVariables as o } from "../../utils/pairProductVariables.js";
2
+ import { wrapHiddenPriceTdsForOutlook as r, MSO_ITEMS_HIDE_START as e, MSO_ITEMS_HIDE_END as t } from "./utils/itemsCompilerUtils.js";
3
+ const a = [
3
4
  {
4
5
  id: "pair-product-variables",
5
6
  description: "Replace product default values with template variables",
6
7
  type: "custom",
7
- processor: r,
8
+ processor: o,
8
9
  priority: 60
9
10
  // After recommendation rules (priority 50-53)
11
+ },
12
+ {
13
+ id: "wrap-hidden-price-mso-conditional",
14
+ // SD-147597: Outlook ignores display:none on <td>, so the horizontal layout's
15
+ // hidden price fallback renders too — duplicate price. Mark the hidden td(s)
16
+ // with safe placeholder comments and collapse them inline for web-engine Outlook.
17
+ description: "Mark hidden Items price tds for Outlook conditional hiding",
18
+ type: "custom",
19
+ processor: r,
20
+ priority: 65
21
+ // After pair-product-variables (60), before outlook rules (70+)
22
+ },
23
+ {
24
+ id: "swap-items-mso-markers",
25
+ // Injecting the delicate `<!-- -->` ghost token LAST (after reco minify P99
26
+ // and reco swap P100) keeps it out of every whitespace/comment-mangling pass.
27
+ description: "Swap Items MSO markers into [if !mso] conditional comments",
28
+ type: "custom",
29
+ processor: (i) => i.replaceAll(`<!--${e}-->`, "<!--[if !mso]><!-- -->").replaceAll(`<!--${t}-->`, "<!--<![endif]-->"),
30
+ priority: 101
10
31
  }
11
32
  ];
12
33
  export {
13
- t as itemsCompilerRules
34
+ a as itemsCompilerRules
14
35
  };
@@ -1,4 +1,4 @@
1
- const c = `
1
+ const r = `
2
2
  <!--[if gte mso 9]>
3
3
  <xml>
4
4
  <o:OfficeDocumentSettings>
@@ -6,15 +6,21 @@ const c = `
6
6
  <o:PixelsPerInch>96</o:PixelsPerInch>
7
7
  </o:OfficeDocumentSettings>
8
8
  </xml>
9
- <![endif]-->`, s = {
9
+ <![endif]-->`, n = {
10
10
  xmlns: "http://www.w3.org/1999/xhtml",
11
11
  "xmlns:o": "urn:schemas-microsoft-com:office:office"
12
- }, r = [
12
+ }, p = `
13
+ <style type="text/css">
14
+ ul, ol { padding: 0px 0px 0px 40px; }
15
+ li p { mso-margin-bottom-alt: 15px; }
16
+ .es-text-ltr ul, .es-text-ltr ol { padding: 0px 0px 0px 40px; }
17
+ .es-text-rtl ol, .es-text-rtl ul { padding: 0px 40px 0px 0px; }
18
+ </style>`, l = [
13
19
  {
14
20
  id: "append-office-xml",
15
21
  description: "Appending office XML into the head if it does not exist.",
16
22
  type: "custom",
17
- processor: (e) => e.includes("<o:OfficeDocumentSettings>") ? e : e.replace("</head>", `${c}</head>`),
23
+ processor: (e) => e.includes("<o:OfficeDocumentSettings>") ? e : e.replace("</head>", `${r}</head>`),
18
24
  priority: 70
19
25
  },
20
26
  {
@@ -23,14 +29,21 @@ const c = `
23
29
  type: "custom",
24
30
  processor: (e) => {
25
31
  let t = e;
26
- return Object.entries(s).forEach(([o, i]) => {
27
- const n = new RegExp(`${o}="[^"]*"`);
28
- t.search(n) === -1 && (t = t.replace("<html", `<html ${o}="${i}"`));
32
+ return Object.entries(n).forEach(([o, i]) => {
33
+ const s = new RegExp(`${o}="[^"]*"`);
34
+ t.search(s) === -1 && (t = t.replace("<html", `<html ${o}="${i}"`));
29
35
  }), t;
30
36
  },
31
37
  priority: 71
38
+ },
39
+ {
40
+ id: "append-outlook-list-css",
41
+ description: "Appending Outlook list rules into the head if the base CSS does not already carry them.",
42
+ type: "custom",
43
+ processor: (e) => e.includes("mso-margin-bottom-alt") ? e : e.replace("</head>", `${p}</head>`),
44
+ priority: 73
32
45
  }
33
46
  ];
34
47
  export {
35
- r as outlookCompilerRules
48
+ l as outlookCompilerRules
36
49
  };
@@ -0,0 +1,28 @@
1
+ const p = "MSO_ITEMS_HIDE_START", E = "MSO_ITEMS_HIDE_END", u = "mso-hide:all; max-height:0; overflow:hidden; font-size:0; line-height:0;", _ = ".ins-product-cart td.horizontal-price, .ins-product-cart td.vertical-price";
2
+ function T(t) {
3
+ if (!t.includes("vertical-price") || !t.includes("ins-product-cart"))
4
+ return t;
5
+ const i = t.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), r = new DOMParser().parseFromString(i, "text/html");
6
+ let n = !1;
7
+ if (r.querySelectorAll(_).forEach((e) => {
8
+ var s, a;
9
+ const o = e.getAttribute("style") || "";
10
+ if (!/display\s*:\s*none/i.test(o))
11
+ return;
12
+ const c = e.previousSibling;
13
+ if (((c == null ? void 0 : c.nodeType) !== Node.COMMENT_NODE || c.data !== p) && ((s = e.parentNode) == null || s.insertBefore(r.createComment(p), e), (a = e.parentNode) == null || a.insertBefore(r.createComment(E), e.nextSibling)), !/mso-hide/i.test(o)) {
14
+ const d = o.trim().endsWith(";") ? " " : "; ";
15
+ e.setAttribute("style", `${o}${d}${u}`);
16
+ }
17
+ n = !0;
18
+ }), !n)
19
+ return t;
20
+ const l = i.match(/<!DOCTYPE[^>]*>/i);
21
+ return ((l ? `${l[0]}
22
+ ` : "") + r.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
23
+ }
24
+ export {
25
+ E as MSO_ITEMS_HIDE_END,
26
+ p as MSO_ITEMS_HIDE_START,
27
+ T as wrapHiddenPriceTdsForOutlook
28
+ };
@@ -88,11 +88,11 @@ function k(o) {
88
88
  }
89
89
  function h(o) {
90
90
  var e;
91
- const t = (c, u) => c == null ? u : c === "1" || c === "true", r = (c, u) => c || u, l = o["data-type"] || o["data-source"], a = k(l), i = I[a];
91
+ const t = (l, u) => l == null ? u : l === "1" || l === "true", r = (l, u) => l || u, c = o["data-type"] || o["data-source"], a = k(c), i = I[a];
92
92
  let n = o["data-cart_items_select_control_value"] || ((e = i == null ? void 0 : i[0]) == null ? void 0 : e.value) || g.cartItemsSelectControlValue;
93
93
  if (n && !n.includes("{{") && /^\d+$/.test(n)) {
94
- const c = parseInt(n) - 1, u = I[a];
95
- u && u[c] && (n = u[c].value);
94
+ const l = parseInt(n) - 1, u = I[a];
95
+ u && u[l] && (n = u[l].value);
96
96
  }
97
97
  return {
98
98
  initialized: !0,
@@ -148,7 +148,7 @@ function N(o, t) {
148
148
  };
149
149
  return r[o] || r.CART_ITEMS;
150
150
  }
151
- class z {
151
+ class H {
152
152
  constructor() {
153
153
  M(this, "parser");
154
154
  this.parser = new DOMParser();
@@ -159,13 +159,13 @@ class z {
159
159
  return this.backfillV2ProductTdAttributes(t);
160
160
  let r = this.removeJinjaConditionals(t);
161
161
  r = this.replaceTemplateVariables(r);
162
- const l = this.parser.parseFromString(r, "text/html"), a = l.querySelectorAll(
162
+ const c = this.parser.parseFromString(r, "text/html"), a = c.querySelectorAll(
163
163
  "td.esd-cart-items-block, td.esd-browsed-items-block, td.esd-purchased-items-block"
164
164
  );
165
165
  return q().$patch((n) => {
166
166
  n.migrations = { ...n.migrations, [w]: a.length };
167
167
  }), a.length === 0 ? (console.warn("ItemsBlockMigrator: No blocks found with items block selectors"), r) : (a.forEach((n) => {
168
- const e = this.extractConfiguration(n), c = F({
168
+ const e = this.extractConfiguration(n), l = F({
169
169
  orientation: e.orientation,
170
170
  itemsType: e.itemsType,
171
171
  itemId: e.itemId,
@@ -181,7 +181,7 @@ class z {
181
181
  quantityStyles: e.quantityStyles,
182
182
  nodeConfig: h(e.configBlockAttributes)
183
183
  }), s = this.parser.parseFromString(
184
- `<table><tbody><tr>${c}</tr></tbody></table>`,
184
+ `<table><tbody><tr>${l}</tr></tbody></table>`,
185
185
  "text/html"
186
186
  ).querySelector("td");
187
187
  if (s && n.parentNode) {
@@ -190,7 +190,7 @@ class z {
190
190
  const d = s.querySelector("esd-config-block");
191
191
  d && d.remove(), n.parentNode.replaceChild(s, n);
192
192
  }
193
- }), l.documentElement.outerHTML);
193
+ }), c.documentElement.outerHTML);
194
194
  } catch (r) {
195
195
  return console.error("ItemsBlockMigrator failed:", r), t;
196
196
  }
@@ -205,15 +205,15 @@ class z {
205
205
  var C, D, P;
206
206
  const r = k(
207
207
  ((C = t.querySelector("[data-type]")) == null ? void 0 : C.getAttribute("data-type")) ?? null
208
- ), l = ((D = t.querySelector("[data-number]")) == null ? void 0 : D.getAttribute("data-number")) || "1", a = parseInt(l) - 1, i = I[r], n = ((P = i == null ? void 0 : i[a]) == null ? void 0 : P.value) || i[0].value, e = t.querySelector('[product-attr="price"]'), c = (e == null ? void 0 : e.getAttribute("data-currency_symbol")) || "USD", s = ((e == null ? void 0 : e.getAttribute("data-curency")) || "before") === "after" ? "1" : "0", _ = (e == null ? void 0 : e.getAttribute("data-formated")) !== "false", d = this.extractConfigBlockAttributes(t, r, l), b = d["data-card_orientation_control_value"];
208
+ ), c = ((D = t.querySelector("[data-number]")) == null ? void 0 : D.getAttribute("data-number")) || "1", a = parseInt(c) - 1, i = I[r], n = ((P = i == null ? void 0 : i[a]) == null ? void 0 : P.value) || i[0].value, e = t.querySelector('[product-attr="price"]'), l = (e == null ? void 0 : e.getAttribute("data-currency_symbol")) || "USD", s = ((e == null ? void 0 : e.getAttribute("data-curency")) || "before") === "after" ? "1" : "0", _ = (e == null ? void 0 : e.getAttribute("data-formated")) !== "false", d = this.extractConfigBlockAttributes(t, r, c), b = d["data-card_orientation_control_value"];
209
209
  let S;
210
210
  b ? S = b === "horizontal" ? "horizontal" : "vertical" : S = t.querySelector('[colspan="2"]') !== null ? "vertical" : "horizontal";
211
- const y = t.querySelector('a[product-attr="name"]'), A = (y == null ? void 0 : y.getAttribute("style")) || void 0, f = t.querySelector('a[product-attr="button"]'), m = (f == null ? void 0 : f.getAttribute("style")) || void 0, R = (e == null ? void 0 : e.getAttribute("style")) || void 0, T = t.querySelector("p.original-price"), L = (T == null ? void 0 : T.getAttribute("style")) || void 0, E = t.querySelector('[product-attr="quantity"]'), B = (E == null ? void 0 : E.getAttribute("style")) || void 0;
211
+ const y = t.querySelector('a[product-attr="name"]'), A = (y == null ? void 0 : y.getAttribute("style")) || void 0, f = t.querySelector('a[product-attr="button"]'), m = (f == null ? void 0 : f.getAttribute("style")) || void 0, R = (e == null ? void 0 : e.getAttribute("style")) || void 0, E = t.querySelector("p.original-price"), L = (E == null ? void 0 : E.getAttribute("style")) || void 0, T = t.querySelector('[product-attr="quantity"]'), B = (T == null ? void 0 : T.getAttribute("style")) || void 0;
212
212
  return {
213
213
  orientation: S,
214
214
  itemsType: r,
215
215
  itemId: n,
216
- currencySymbol: c,
216
+ currencySymbol: l,
217
217
  currencyLocation: s,
218
218
  formattedPrice: _,
219
219
  configBlockAttributes: d,
@@ -231,7 +231,7 @@ class z {
231
231
  * @param itemsType - The type of items (CART_ITEMS, BROWSED_ITEMS, PURCHASED_ITEMS)
232
232
  * @param itemNumber - The item number (1-based index)
233
233
  */
234
- extractConfigBlockAttributes(t, r, l) {
234
+ extractConfigBlockAttributes(t, r, c) {
235
235
  const a = t.querySelector("esd-config-block"), i = {};
236
236
  if (!a)
237
237
  return this.getDefaultConfigBlockAttributes();
@@ -240,18 +240,18 @@ class z {
240
240
  }), i["data-cart_items_select_control_value"]) {
241
241
  const e = i["data-cart_items_select_control_value"];
242
242
  if (/^\d+$/.test(e)) {
243
- const c = parseInt(e) - 1, u = I[r];
244
- u && u[c] && (i["data-cart_items_select_control_value"] = u[c].value);
243
+ const l = parseInt(e) - 1, u = I[r];
244
+ u && u[l] && (i["data-cart_items_select_control_value"] = u[l].value);
245
245
  }
246
246
  }
247
247
  if (i["data-product_price_control_curency"]) {
248
248
  const e = i["data-product_price_control_curency"];
249
- let c = e;
250
- e === "before" ? c = "0" : e === "after" && (c = "1"), i["data-product_price_control_curency"] = c, i["data-product_price_currency_location"] = c;
249
+ let l = e;
250
+ e === "before" ? l = "0" : e === "after" && (l = "1"), i["data-product_price_control_curency"] = l, i["data-product_price_currency_location"] = l;
251
251
  }
252
252
  (!i["data-product_price_control_currency_symbol"] || i["data-product_price_control_currency_symbol"].trim() === "") && (i["data-product_price_control_currency_symbol"] = "USD");
253
253
  const n = { ...this.getDefaultConfigBlockAttributes(), ...i };
254
- return n["data-type"] = r, n["data-source"] = r, n["data-product_image_link"] = $(r, l), n["data-product_button_link"] = N(r, l), n;
254
+ return n["data-type"] = r, n["data-source"] = r, n["data-product_image_link"] = $(r, c), n["data-product_button_link"] = N(r, c), n;
255
255
  }
256
256
  /**
257
257
  * Returns default esd-config-block attributes based on the old template structure
@@ -301,7 +301,7 @@ class z {
301
301
  };
302
302
  }
303
303
  /**
304
- * Backfills data-type (and data-number) onto v2 `.ins-product-td` elements
304
+ * Backfills data-type (and data-number, data-nodup) onto v2 `.ins-product-td` elements
305
305
  * from their persisted `esd-ext-config` nodeConfig, and strips the legacy
306
306
  * static `width` that older builds baked onto the product-td.
307
307
  *
@@ -326,22 +326,24 @@ class z {
326
326
  if (!t.includes("ins-product-td") || !t.includes("esd-ext-config"))
327
327
  return t;
328
328
  const r = this.parser.parseFromString(t, "text/html");
329
- let l = !1;
329
+ let c = !1;
330
330
  return r.querySelectorAll(".ins-product-td").forEach((a) => {
331
- if (a.hasAttribute("width") && (a.removeAttribute("width"), l = !0), a.getAttribute("data-type"))
332
- return;
331
+ a.hasAttribute("width") && (a.removeAttribute("width"), c = !0);
333
332
  const i = a.getAttribute("esd-ext-config");
334
- if (i)
335
- try {
336
- const n = JSON.parse(i), e = n.type || n.source;
337
- if (!e)
338
- return;
339
- a.setAttribute("data-type", e), l = !0;
340
- const c = typeof n.itemsSelectValue == "string" ? n.itemsSelectValue.match(/\((\d+)\)/) : null;
341
- c && a.getAttribute("data-number") !== c[1] && a.setAttribute("data-number", c[1]);
342
- } catch {
343
- }
344
- }), l ? r.documentElement.outerHTML : t;
333
+ let n = null;
334
+ try {
335
+ n = i ? JSON.parse(i) : null;
336
+ } catch {
337
+ }
338
+ if (!n || (!a.getAttribute("data-nodup") && typeof n.priceHideDiscount == "boolean" && (a.setAttribute("data-nodup", String(n.priceHideDiscount)), c = !0), a.getAttribute("data-type")))
339
+ return;
340
+ const e = n.type || n.source;
341
+ if (!e)
342
+ return;
343
+ a.setAttribute("data-type", e), c = !0;
344
+ const l = typeof n.itemsSelectValue == "string" ? n.itemsSelectValue.match(/\((\d+)\)/) : null;
345
+ l && a.getAttribute("data-number") !== l[1] && a.setAttribute("data-number", l[1]);
346
+ }), c ? r.documentElement.outerHTML : t;
345
347
  }
346
348
  /**
347
349
  * Fast check for the presence of any items block (cart / browsed / purchased)
@@ -362,15 +364,15 @@ class z {
362
364
  * contains display condition Jinja scripts that should NOT be removed.
363
365
  */
364
366
  removeJinjaConditionals(t) {
365
- const r = "__ESD_DISPLAY_CONDITIONS_PLACEHOLDER__", l = t.match(/esd-custom-display-conditions="[^"]*"/);
366
- let a = l ? t.replace(l[0], r) : t;
367
+ const r = "__ESD_DISPLAY_CONDITIONS_PLACEHOLDER__", c = t.match(/esd-custom-display-conditions="[^"]*"/);
368
+ let a = c ? t.replace(c[0], r) : t;
367
369
  return a = a.replace(
368
370
  /\{%\s*if\s+(ins_apr|browsed_item|purchased_item)_total_product_kind\s*(&gt;|>)\s*\d+\s*%\}/g,
369
371
  ""
370
372
  ), a = a.replace(
371
373
  /\{%\s*if\s+(ins_apr|browsed_item|purchased_item)_price_\d+\s*(!&#61;|!=)\s*\1_originalprice_\d+\s*%\}/g,
372
374
  ""
373
- ), a = a.replace(/\{%\s*endif\s*%\}/g, ""), l && (a = a.replace(r, l[0])), a = a.replace(/\n\s*\n\s*\n/g, `
375
+ ), a = a.replace(/\{%\s*endif\s*%\}/g, ""), c && (a = a.replace(r, c[0])), a = a.replace(/\n\s*\n\s*\n/g, `
374
376
 
375
377
  `), a;
376
378
  }
@@ -385,30 +387,30 @@ class z {
385
387
  */
386
388
  replaceTemplateVariables(t) {
387
389
  const { PAIRS_FOR_EXTENSION: r } = K;
388
- return t.replace(/{{([^}]+)}}/g, (l, a) => {
390
+ return t.replace(/{{([^}]+)}}/g, (c, a) => {
389
391
  const i = a.match(/^(ins_apr|browsed_item|purchased_item)_([a-z_]+)_(\d+)$/);
390
392
  if (!i)
391
- return l;
392
- const [, n, e, c] = i, u = V[n];
393
+ return c;
394
+ const [, n, e, l] = i, u = V[n];
393
395
  if (!u)
394
- return console.warn(`Unknown variable prefix: ${n}`), l;
396
+ return console.warn(`Unknown variable prefix: ${n}`), c;
395
397
  const s = x[e];
396
398
  if (!s)
397
- return console.warn(`Unknown variable suffix mapping for: ${e}`), l;
399
+ return console.warn(`Unknown variable suffix mapping for: ${e}`), c;
398
400
  const { pairsKey: _, defaultKey: d, isArray: b } = s, y = r[_][u];
399
401
  if (!y)
400
- return console.warn(`No data found for: ${_}.${u}`), l;
402
+ return console.warn(`No data found for: ${_}.${u}`), c;
401
403
  if (b) {
402
- const f = parseInt(c) - 1, m = y[d];
403
- return Array.isArray(m) && m[f] ? m[f] : (console.warn(`Array value not found: ${_}.${u}.${d}[${f}]`), l);
404
+ const f = parseInt(l) - 1, m = y[d];
405
+ return Array.isArray(m) && m[f] ? m[f] : (console.warn(`Array value not found: ${_}.${u}.${d}[${f}]`), c);
404
406
  }
405
407
  const A = y[d];
406
- return A !== void 0 ? String(A) : (console.warn(`Default value not found: ${_}.${u}.${d}`), l);
408
+ return A !== void 0 ? String(A) : (console.warn(`Default value not found: ${_}.${u}.${d}`), c);
407
409
  });
408
410
  }
409
411
  }
410
412
  function Q(o) {
411
- return new z().migrate(o);
413
+ return new H().migrate(o);
412
414
  }
413
415
  export {
414
416
  Q as migrateItemsBlock
@@ -1,14 +1,14 @@
1
- import { BlockId as g } from "../../../enums/block.js";
2
- import { useOnboardingStore as p } from "../../../stores/onboarding.js";
1
+ import { BlockId as f } from "../../../enums/block.js";
2
+ import { useOnboardingStore as g } from "../../../stores/onboarding.js";
3
3
  import { getMigrationBannerHtml as y } from "../../../utils/migrationBannerHtml.js";
4
4
  import { Block as I, BlockCompositionType as C, ModificationDescription as c } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { SETTINGS_ENUMS as l, DefaultConfigValues as m } from "./enums/settingsEnums.js";
5
+ import { SETTINGS_ENUMS as d, DefaultConfigValues as m } from "./enums/settingsEnums.js";
6
6
  import { getDefaultTemplate as b } from "./template.js";
7
- import { getItemsBlockContainer as d, getItemsBlockConfig as u, deriveItemNumber as h, getDefaultItemsBlockConfig as N } from "./utils/nodeConfigUtils.js";
8
- const f = g.Items;
9
- class P extends I {
7
+ import { getItemsBlockContainer as l, getItemsBlockConfig as u, deriveItemNumber as h, getDefaultItemsBlockConfig as N } from "./utils/nodeConfigUtils.js";
8
+ const p = f.Items;
9
+ class O extends I {
10
10
  getId() {
11
- return f;
11
+ return p;
12
12
  }
13
13
  getIcon() {
14
14
  return "items-icon";
@@ -24,15 +24,15 @@ class P extends I {
24
24
  }
25
25
  getSettingsPanelTitleHtml() {
26
26
  return y(
27
- f,
27
+ p,
28
28
  this.api.translate("Items"),
29
29
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Items block and test your message to ensure it works properly.")
30
30
  );
31
31
  }
32
32
  getTemplate() {
33
33
  return b({
34
- orientation: l.ORIENTATION.VERTICAL,
35
- itemsType: l.ITEMS_TYPE.CART_ITEMS,
34
+ orientation: d.ORIENTATION.VERTICAL,
35
+ itemsType: d.ITEMS_TYPE.CART_ITEMS,
36
36
  itemId: "{{Abandoned Cart Item (1) Url}}",
37
37
  currencySymbol: m.productPriceCurrencySymbolControlValue,
38
38
  currencyLocation: m.productPriceCurrencyLocationControlValue,
@@ -45,23 +45,23 @@ class P extends I {
45
45
  canBeSavedAsModule() {
46
46
  return !0;
47
47
  }
48
- onCreated(o) {
49
- const t = this.api.getDocumentModifier(), i = this.api.getDocumentRootCssNode();
50
- i.querySelector('[product-attr="imageSrc"] img') || t.modifyCss(i).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
51
- const e = d(o);
52
- if (!e)
48
+ onCreated(e) {
49
+ const t = this.api.getDocumentModifier(), o = this.api.getDocumentRootCssNode();
50
+ o.querySelector('[product-attr="imageSrc"] img') || t.modifyCss(o).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
51
+ const i = l(e);
52
+ if (!i)
53
53
  return;
54
- const r = e.getNodeConfig(), s = r && Object.keys(r).length > 0, n = u(o);
54
+ const r = i.getNodeConfig(), s = r && Object.keys(r).length > 0, n = u(e);
55
55
  if (n != null && n.initialized)
56
56
  if (s)
57
- n.blockInstanceId || this.api.getDocumentModifier().modifyHtml(e).setNodeConfig({ ...n, blockInstanceId: String(Date.now()) }).apply(new c("Assign block instance ID to block"));
57
+ n.blockInstanceId || this.api.getDocumentModifier().modifyHtml(i).setNodeConfig({ ...n, blockInstanceId: String(Date.now()) }).apply(new c("Assign block instance ID to block"));
58
58
  else {
59
59
  const a = this.api.getDocumentModifier();
60
- a.modifyHtml(e).setNodeConfig(n), this._stampProductTdDomAttributes(e, n, a), a.apply(new c("Migrate legacy config to nodeConfig"));
60
+ a.modifyHtml(i).setNodeConfig(n), this._stampProductTdDomAttributes(i, n, a), a.apply(new c("Migrate legacy config to nodeConfig"));
61
61
  }
62
62
  else {
63
63
  const a = N();
64
- this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(a).apply(new c("Initialize Items block with default configuration")), p().startOnboarding("itemsOnboarding");
64
+ this.api.getDocumentModifier().modifyHtml(i).setNodeConfig(a).apply(new c("Initialize Items block with default configuration")), g().startOnboarding("itemsOnboarding");
65
65
  }
66
66
  }
67
67
  /**
@@ -70,33 +70,33 @@ class P extends I {
70
70
  * into nodeConfig, so without this a reused module would reset to defaults.
71
71
  * Guarded to the nodeConfig-empty case so it runs once and never loops.
72
72
  */
73
- onDocumentChanged(o) {
74
- const t = d(o);
73
+ onDocumentChanged(e) {
74
+ const t = l(e);
75
75
  if (!t)
76
76
  return;
77
- const i = t.getNodeConfig();
78
- if (i && Object.keys(i).length > 0)
77
+ const o = t.getNodeConfig();
78
+ if (o && Object.keys(o).length > 0)
79
79
  return;
80
- const r = u(o);
80
+ const r = u(e);
81
81
  if (!(r != null && r.initialized))
82
82
  return;
83
83
  const s = this.api.getDocumentModifier();
84
84
  s.modifyHtml(t).setNodeConfig(r), this._stampProductTdDomAttributes(t, r, s), s.apply(new c("Recover Items block config from saved module"));
85
85
  }
86
86
  /**
87
- * Bakes the compiler-read DOM attributes (`data-type`, `data-number`) onto the
87
+ * Bakes the compiler-read DOM attributes (`data-type`, `data-number`, `data-nodup`) onto the
88
88
  * `.ins-product-td` container from the recovered config. Required for saved modules:
89
89
  * `migrate()` (which backfills these) only runs at template load — never when a module
90
90
  * is dropped into a live editor — so this is the one place the namespace + index get
91
91
  * restored before export. The name `<a>` carries no data-type/data-number of its own and
92
92
  * relies on this td-level fallback in pairProductVariables.
93
93
  */
94
- _stampProductTdDomAttributes(o, t, i) {
95
- const e = h(t.itemsSelectValue, t.type);
96
- i.modifyHtml(o).setAttribute("data-type", t.type), i.modifyHtml(o).setAttribute("data-number", e);
94
+ _stampProductTdDomAttributes(e, t, o) {
95
+ const i = h(t.itemsSelectValue, t.type);
96
+ o.modifyHtml(e).setAttribute("data-type", t.type), o.modifyHtml(e).setAttribute("data-number", i), o.modifyHtml(e).setAttribute("data-nodup", String(t.priceHideDiscount));
97
97
  }
98
98
  }
99
99
  export {
100
- f as BLOCK_ID,
101
- P as ItemsBlock
100
+ p as BLOCK_ID,
101
+ O as ItemsBlock
102
102
  };
@@ -1,43 +1,47 @@
1
- import { UIElementType as o, UEAttr as d } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { CommonControl as r } from "../../../common-control.js";
3
- import { ItemsBlockControlId as n } from "../../enums/controlEnums.js";
4
- import { getItemsBlockConfig as s, setItemsBlockConfig as a } from "../../utils/nodeConfigUtils.js";
5
- const c = n.PRICE_HIDE_DISCOUNT, i = {
1
+ import { ModificationDescription as c, UIElementType as s, UEAttr as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { CommonControl as p } from "../../../common-control.js";
3
+ import { ItemsBlockControlId as r } from "../../enums/controlEnums.js";
4
+ import { getItemsBlockConfig as d, setItemsBlockConfig as u } from "../../utils/nodeConfigUtils.js";
5
+ const D = r.PRICE_HIDE_DISCOUNT, i = {
6
6
  HIDE_DISCOUNT: "hideDiscount"
7
7
  };
8
- class C extends r {
8
+ class E extends p {
9
9
  getId() {
10
- return c;
10
+ return D;
11
11
  }
12
12
  getTemplate() {
13
13
  return `
14
- <div class="container ${n.PRICE_HIDE_DISCOUNT}">
14
+ <div class="container ${r.PRICE_HIDE_DISCOUNT}">
15
15
  ${this._getHideDiscount()}
16
16
  </div>
17
17
  `;
18
18
  }
19
19
  onRender() {
20
- const e = s(this.currentNode);
21
- this.api.updateValues({ [i.HIDE_DISCOUNT]: (e == null ? void 0 : e.priceHideDiscount) ?? !0 }), this.api.onValueChanged(i.HIDE_DISCOUNT, (t) => {
22
- this._onHideDiscountChange(t);
20
+ const t = d(this.currentNode);
21
+ this.api.updateValues({ [i.HIDE_DISCOUNT]: (t == null ? void 0 : t.priceHideDiscount) ?? !0 }), this.api.onValueChanged(i.HIDE_DISCOUNT, (e) => {
22
+ this._onHideDiscountChange(e);
23
23
  });
24
24
  }
25
- onTemplateNodeUpdated(e) {
26
- super.onTemplateNodeUpdated(e), this.handleBlockInstanceChange(() => {
27
- const t = s(this.currentNode);
28
- this.api.updateValues({ [i.HIDE_DISCOUNT]: (t == null ? void 0 : t.priceHideDiscount) ?? !0 });
25
+ onTemplateNodeUpdated(t) {
26
+ super.onTemplateNodeUpdated(t), this.handleBlockInstanceChange(() => {
27
+ const e = d(this.currentNode);
28
+ this.api.updateValues({ [i.HIDE_DISCOUNT]: (e == null ? void 0 : e.priceHideDiscount) ?? !0 });
29
29
  });
30
30
  }
31
- _onHideDiscountChange(e) {
32
- a(this.currentNode, this.api, { priceHideDiscount: e }), this.api.updateValues({ [i.HIDE_DISCOUNT]: e });
31
+ _onHideDiscountChange(t) {
32
+ var n;
33
+ const e = this.api.getDocumentModifier();
34
+ u(this.currentNode, this.api, { priceHideDiscount: t }, e);
35
+ const o = (n = this.currentNode) == null ? void 0 : n.closest(".ins-product-td");
36
+ o && e.modifyHtml(o).setAttribute("data-nodup", String(t)), e.apply(new c("Update hide-discount setting")), this.api.updateValues({ [i.HIDE_DISCOUNT]: t });
33
37
  }
34
38
  _getHideDiscount() {
35
39
  return `
36
40
  <div class="display-flex align-items-center justify-content-between">
37
- <${o.LABEL}
38
- ${d.LABEL.text}="${this.api.translate("Hide if same as discounted ")}"
41
+ <${s.LABEL}
42
+ ${a.LABEL.text}="${this.api.translate("Hide if same as discounted ")}"
39
43
  >
40
- </${o.LABEL}>
44
+ </${s.LABEL}>
41
45
  ${this._GuToggle(i.HIDE_DISCOUNT)}
42
46
  </div>
43
47
  </div>
@@ -45,6 +49,6 @@ class C extends r {
45
49
  }
46
50
  }
47
51
  export {
48
- c as CONTROL_BLOCK_ID,
49
- C as PriceHideDiscountControl
52
+ D as CONTROL_BLOCK_ID,
53
+ E as PriceHideDiscountControl
50
54
  };
@@ -1,9 +1,4 @@
1
1
  import type { ModuleAddData, ModuleModifier } from '@@/Types/stripo';
2
- /**
3
- * Host-registered translation key for the "some attributes could not be
4
- * converted" toaster. Guido resolves it against the host's `window.trans.en`;
5
- * the copy is registered host-side.
6
- */
7
2
  export declare const UNRESOLVED_DYNAMIC_CONTENT_ON_DROP_KEY = "dynamic-content.unresolved-attributes-on-drop";
8
3
  /**
9
4
  * Repairs label-form dynamic-content tokens in saved modules as they are dropped
@@ -0,0 +1,12 @@
1
+ export declare const MSO_ITEMS_HIDE_START = "MSO_ITEMS_HIDE_START";
2
+ export declare const MSO_ITEMS_HIDE_END = "MSO_ITEMS_HIDE_END";
3
+ /**
4
+ * SD-147597: the horizontal Items layout ships a second copy of price +
5
+ * original price in a `td.vertical-price` fallback hidden only by inline
6
+ * `display:none` (and vice versa for the vertical price orientation). Outlook's
7
+ * Word engine ignores `display:none` on `<td>`, so it paints BOTH copies —
8
+ * duplicate price. Wrap whichever price td(s) are hidden at export time in safe
9
+ * placeholder comments (swapped into `<!--[if !mso]>` by the priority-101 rule)
10
+ * and collapse them inline for web-engine Outlook.
11
+ */
12
+ export declare function wrapHiddenPriceTdsForOutlook(html: string): string;
@@ -34,7 +34,7 @@ export declare class ItemsBlock extends Block {
34
34
  */
35
35
  onDocumentChanged(node: ImmutableHtmlNode): void;
36
36
  /**
37
- * Bakes the compiler-read DOM attributes (`data-type`, `data-number`) onto the
37
+ * Bakes the compiler-read DOM attributes (`data-type`, `data-number`, `data-nodup`) onto the
38
38
  * `.ins-product-td` container from the recovered config. Required for saved modules:
39
39
  * `migrate()` (which backfills these) only runs at template load — never when a module
40
40
  * is dropped into a live editor — so this is the one place the namespace + index get
@@ -1,85 +1,85 @@
1
1
  import { productPairs as N } from "../extensions/Blocks/Items/enums/productEnums.js";
2
2
  import { DefaultConfigValues as O } from "../extensions/Blocks/Items/enums/settingsEnums.js";
3
- import { preserveTextStyles as C } from "./preserveTextStyles.js";
4
- function V(L) {
5
- const H = L.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), g = new DOMParser().parseFromString(H, "text/html"), m = N.PAIRS_FOR_EXTENSION;
3
+ import { preserveTextStyles as R } from "./preserveTextStyles.js";
4
+ function v(L) {
5
+ const H = L.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), y = new DOMParser().parseFromString(H, "text/html"), m = N.PAIRS_FOR_EXTENSION;
6
6
  Object.entries(m).forEach(([r, f]) => {
7
- g.querySelectorAll(".ins-product-td").forEach((c) => {
8
- const A = c.getAttribute("data-number") || "1", y = c.getAttribute("data-type") || "CART_ITEMS";
9
- c.querySelectorAll(`[product-attr="${r}"]`).forEach((t) => {
7
+ y.querySelectorAll(".ins-product-td").forEach((l) => {
8
+ const h = l.getAttribute("data-number") || "1", $ = l.getAttribute("data-type") || "CART_ITEMS";
9
+ l.querySelectorAll(`[product-attr="${r}"]`).forEach((t) => {
10
10
  var F, I, w;
11
- const T = t.getAttribute("data-type") || y, u = t.getAttribute("data-number") || A, d = f[T];
11
+ const T = t.getAttribute("data-type") || $, u = t.getAttribute("data-number") || h, d = f[T];
12
12
  if (d)
13
13
  switch (r) {
14
14
  case "imageSrc": {
15
- let e = null, i = null;
16
- if (t.tagName === "IMG" ? (e = t, i = e.closest("a")) : (e = t.querySelector("img"), i = t.querySelector("a") || t.closest("a")), !e)
15
+ let e = null, c = null;
16
+ if (t.tagName === "IMG" ? (e = t, c = e.closest("a")) : (e = t.querySelector("img"), c = t.querySelector("a") || t.closest("a")), !e)
17
17
  break;
18
- const a = d.DEFAULT, s = d.ATTR;
19
- if (a && e.src) {
18
+ const i = d.DEFAULT, s = d.ATTR;
19
+ if (i && e.src) {
20
20
  const o = e.src;
21
- a.some((h) => {
22
- const l = h.split("/").pop() || "", $ = o.split("/").pop() || "";
23
- return o.includes(h) || o.includes(l) || $ === l;
21
+ i.some((E) => {
22
+ const a = E.split("/").pop() || "", b = o.split("/").pop() || "";
23
+ return o.includes(E) || o.includes(a) || b === a;
24
24
  }) && (e.src = `{{${s}_${u}}}`);
25
25
  }
26
26
  const n = (I = (F = m.name) == null ? void 0 : F[T]) == null ? void 0 : I.ATTR;
27
- if (n && e.setAttribute("alt", `{{${n}_${u}}}`), i) {
27
+ if (n && e.setAttribute("alt", `{{${n}_${u}}}`), c) {
28
28
  const o = (w = m.itemLink) == null ? void 0 : w[T];
29
29
  if (o) {
30
- const E = o.HREF, h = o.DEFAULT_HREF || "#!", l = i.href;
31
- (l === "#" || l === "" || l.endsWith("#!") || l.endsWith(h) || l === `${window.location.href}${h}` || !l || l === window.location.href) && (i.href = `{{${E}_${u}}}`);
30
+ const A = o.HREF, E = o.DEFAULT_HREF || "#!", a = c.href;
31
+ (a === "#" || a === "" || a.endsWith("#!") || a.endsWith(E) || a === `${window.location.href}${E}` || !a || a === window.location.href) && (c.href = `{{${A}_${u}}}`);
32
32
  }
33
33
  }
34
34
  break;
35
35
  }
36
36
  case "name": {
37
- const e = d, i = e.ATTR, a = e.DEFAULT_HREF || "#!", s = e.HREF;
38
- t.textContent && (t.innerHTML = C(t, `{{${i}_${u}}}`));
37
+ const e = d, c = e.ATTR, i = e.DEFAULT_HREF || "#!", s = e.HREF;
38
+ t.textContent && (t.innerHTML = R(t, `{{${c}_${u}}}`));
39
39
  const n = t.closest("a") || (t.tagName === "A" ? t : null);
40
40
  if (n && s) {
41
- const o = n.href, E = `${window.location.href}${a}`;
42
- (o === E || o.endsWith(a)) && (n.href = `{{${s}_${u}}}`);
41
+ const o = n.href, A = `${window.location.href}${i}`;
42
+ (o === A || o.endsWith(i)) && (n.href = `{{${s}_${u}}}`);
43
43
  }
44
44
  break;
45
45
  }
46
46
  case "price":
47
47
  case "originalPrice": {
48
- const e = d, i = t.getAttribute("data-formated"), a = t.getAttribute("data-single_price"), s = i === "true", n = a === "true", o = t.getAttribute("data-curency") || "before";
49
- let E;
50
- n ? E = s ? e.SINGLE_PRICE_FORMATTED : e.SINGLE_PRICE : E = s ? e.PRICE_FORMATTED : e.PRICE;
51
- const h = e.CURRENCY;
52
- let l = `{{${E}_${u}}}`;
53
- const $ = (t.getAttribute("data-currency_symbol") || "").trim(), q = $ !== "" && $ !== O.productPriceCurrencySymbolControlValue;
54
- let b = "";
55
- q ? b = $ : h && (b = `{{${h}_${u}}}`), b && (l = o === "after" ? `${l} ${b}` : `${b} ${l}`), t.innerHTML = C(t, l);
48
+ const e = d, c = t.getAttribute("data-formated"), i = t.getAttribute("data-single_price"), s = c === "true", n = i === "true", o = t.getAttribute("data-curency") || "before";
49
+ let A;
50
+ n ? A = s ? e.SINGLE_PRICE_FORMATTED : e.SINGLE_PRICE : A = s ? e.PRICE_FORMATTED : e.PRICE;
51
+ const E = e.CURRENCY;
52
+ let a = `{{${A}_${u}}}`;
53
+ const b = (t.getAttribute("data-currency_symbol") || "").trim(), q = b !== "" && b !== O.productPriceCurrencySymbolControlValue;
54
+ let g = "";
55
+ q ? g = b : E && (g = `{{${E}_${u}}}`), g && (a = o === "after" ? `${a} ${g}` : `${g} ${a}`), t.innerHTML = R(t, a);
56
56
  break;
57
57
  }
58
58
  case "quantity": {
59
- const e = d, i = e.ATTR, a = e.DEFAULT;
60
- t.textContent && t.textContent.trim() === a && (t.innerHTML = C(t, `{{${i}_${u}}}`));
59
+ const e = d, c = e.ATTR, i = e.DEFAULT;
60
+ t.textContent && t.textContent.trim() === i && (t.innerHTML = R(t, `{{${c}_${u}}}`));
61
61
  break;
62
62
  }
63
63
  case "button": {
64
- const e = d, i = e.HREF, a = e.DEFAULT_HREF || "#!", s = t.tagName === "A" ? t : t.querySelector("a");
64
+ const e = d, c = e.HREF, i = e.DEFAULT_HREF || "#!", s = t.tagName === "A" ? t : t.querySelector("a");
65
65
  if (s) {
66
- const n = s.href || "", o = `${window.location.href}${a}`;
67
- (n === "" || n === "#" || n === o || n.endsWith(a) || n.endsWith("#!") || n === window.location.href) && (s.href = `{{${i}_${u}}}`);
66
+ const n = s.href || "", o = `${window.location.href}${i}`;
67
+ (n === "" || n === "#" || n === o || n.endsWith(i) || n.endsWith("#!") || n === window.location.href) && (s.href = `{{${c}_${u}}}`);
68
68
  }
69
69
  break;
70
70
  }
71
71
  case "itemLink": {
72
- const e = d, i = e.HREF, a = e.DEFAULT_HREF || "#!", s = t;
72
+ const e = d, c = e.HREF, i = e.DEFAULT_HREF || "#!", s = t;
73
73
  if (s.href) {
74
- const n = s.href, o = `${window.location.href}${a}`;
75
- (n === o || n.endsWith(a)) && (s.href = `{{${i}_${u}}}`);
74
+ const n = s.href, o = `${window.location.href}${i}`;
75
+ (n === o || n.endsWith(i)) && (s.href = `{{${c}_${u}}}`);
76
76
  }
77
77
  break;
78
78
  }
79
79
  default: {
80
80
  if ("ATTR" in d) {
81
81
  const e = d.ATTR;
82
- t.textContent && (t.innerHTML = C(t, `{{${e}_${u}}}`));
82
+ t.textContent && (t.innerHTML = R(t, `{{${e}_${u}}}`));
83
83
  }
84
84
  break;
85
85
  }
@@ -88,54 +88,54 @@ function V(L) {
88
88
  });
89
89
  });
90
90
  const k = H.match(/<!DOCTYPE[^>]*>/i), P = k ? `${k[0]}
91
- ` : "", D = g.querySelectorAll(".ins-product-td"), M = [];
91
+ ` : "", D = y.querySelectorAll(".ins-product-td"), M = [];
92
92
  D.forEach((r) => {
93
- const f = r.getAttribute("data-type") || "CART_ITEMS", p = r.getAttribute("data-number") || "1", c = r.getAttribute("data-nodup"), A = r.outerHTML;
93
+ const f = r.getAttribute("data-type") || "CART_ITEMS", p = r.getAttribute("data-number") || "1", l = r.outerHTML;
94
94
  M.push({
95
95
  element: r,
96
- outerHtml: A,
96
+ outerHtml: l,
97
97
  type: f,
98
- number: p,
99
- nodup: c || void 0
98
+ number: p
100
99
  });
101
100
  });
102
- let _ = P + g.documentElement.outerHTML;
101
+ let _ = P + y.documentElement.outerHTML;
103
102
  M.reverse().forEach(({ outerHtml: r, type: f, number: p }) => {
104
- let c = "";
103
+ let l = "";
105
104
  switch (f) {
106
105
  case "CART_ITEMS":
107
- c = "ins_apr_total_product_kind";
106
+ l = "ins_apr_total_product_kind";
108
107
  break;
109
108
  case "BROWSED_ITEMS":
110
- c = "browsed_item_total_product_kind";
109
+ l = "browsed_item_total_product_kind";
111
110
  break;
112
111
  case "PURCHASED_ITEMS":
113
- c = "purchased_item_total_product_kind";
112
+ l = "purchased_item_total_product_kind";
114
113
  break;
115
114
  }
116
- if (c) {
117
- const y = parseInt(p) - 1, T = `${`{% if ${c} > ${y} %}`}${r}{% endif %}`;
115
+ if (l) {
116
+ const $ = parseInt(p) - 1, T = `${`{% if ${l} > ${$} %}`}${r}{% endif %}`;
118
117
  _ = _.replace(r, T);
119
118
  }
120
119
  });
121
- const x = g.querySelectorAll('[product-attr="originalPrice"][data-type="CART_ITEMS"]'), R = [];
120
+ const x = y.querySelectorAll('[product-attr="originalPrice"][data-type="CART_ITEMS"]'), S = [];
122
121
  return x.forEach((r) => {
122
+ var $;
123
123
  const f = r.getAttribute("data-number"), p = r.getAttribute("data-type");
124
- if (!f || p !== "CART_ITEMS")
124
+ if (!f || p !== "CART_ITEMS" || (($ = r.closest(".ins-product-td")) == null ? void 0 : $.getAttribute("data-nodup")) === "false")
125
125
  return;
126
- const c = r.closest(".product-original-price-class");
127
- if (c) {
128
- const A = c.outerHTML;
129
- R.some((S) => S.tdOuterHtml === A) || R.push({ tdOuterHtml: A, number: f });
126
+ const h = r.closest(".product-original-price-class");
127
+ if (h) {
128
+ const C = h.outerHTML;
129
+ S.some((T) => T.tdOuterHtml === C) || S.push({ tdOuterHtml: C, number: f });
130
130
  }
131
- }), R.reverse().forEach(({ tdOuterHtml: r, number: f }) => {
131
+ }), S.reverse().forEach(({ tdOuterHtml: r, number: f }) => {
132
132
  const p = `{% if ins_apr_price_${f} != ins_apr_originalprice_${f} %}`;
133
133
  if (!_.includes(p) && !r.includes("{% if")) {
134
- const A = `${p}${r}{% endif %}`;
135
- _ = _.replace(r, A);
134
+ const h = `${p}${r}{% endif %}`;
135
+ _ = _.replace(r, h);
136
136
  }
137
137
  }), _.replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
138
138
  }
139
139
  export {
140
- V as pairProductVariables
140
+ v as pairProductVariables
141
141
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.13.0",
3
+ "version": "3.13.1-beta.77f8a06",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",