@useinsider/guido 3.16.0-beta.efbb91f → 3.16.0-beta.fe1df65

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.
Files changed (81) hide show
  1. package/dist/components/Guido.vue.js +8 -8
  2. package/dist/components/Guido.vue2.js +76 -78
  3. package/dist/components/organisms/AutoSaveController.vue2.js +8 -9
  4. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  5. package/dist/components/organisms/header/EditorActions.vue2.js +43 -74
  6. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  7. package/dist/components/organisms/header/LeftSlot.vue2.js +23 -45
  8. package/dist/components/wrappers/WpDrawer.vue.js +7 -9
  9. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  10. package/dist/composables/useHtmlValidator.js +0 -1
  11. package/dist/composables/useRecommendation.js +20 -19
  12. package/dist/composables/useSave.js +41 -84
  13. package/dist/composables/validators/useCouponBlockValidator.js +21 -24
  14. package/dist/composables/validators/useUnsubscribeBlockValidator.js +27 -34
  15. package/dist/config/migrator/index.js +9 -8
  16. package/dist/config/migrator/itemsBlockMigrator.js +1 -1
  17. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  18. package/dist/config/migrator/recommendation/extractors.js +29 -24
  19. package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
  20. package/dist/config/migrator/recommendationMigrator.js +18 -15
  21. package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
  22. package/dist/enums/recommendation.js +17 -17
  23. package/dist/extensions/Blocks/Items/enums/productEnums.js +45 -45
  24. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  25. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  26. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +23 -22
  27. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +29 -26
  28. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +306 -238
  29. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +37 -26
  30. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +29 -28
  31. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
  32. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
  33. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  34. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
  35. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +26 -32
  36. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  37. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
  38. package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
  39. package/dist/extensions/Blocks/Recommendation/utils/productIds.js +6 -0
  40. package/dist/guido.css +1 -1
  41. package/dist/src/components/Guido.vue.d.ts +1 -17
  42. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -17
  43. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -17
  44. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -17
  45. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +3 -4
  46. package/dist/src/composables/useHtmlValidator.d.ts +0 -14
  47. package/dist/src/composables/useSave.d.ts +1 -6
  48. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +0 -3
  49. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +0 -10
  50. package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
  51. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +1 -0
  52. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
  53. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
  54. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
  55. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  56. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +4 -0
  57. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +10 -0
  58. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  59. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
  60. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
  61. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -5
  62. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
  63. package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +6 -0
  64. package/dist/src/stores/config.d.ts +0 -5
  65. package/dist/src/utils/templatePreparation.d.ts +0 -30
  66. package/dist/static/styles/customEditorStyle.css.js +3 -1
  67. package/dist/stores/config.js +6 -13
  68. package/dist/utils/templatePreparation.js +25 -28
  69. package/package.json +1 -1
  70. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +0 -20
  71. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +0 -61
  72. package/dist/composables/useSaveValidation.js +0 -276
  73. package/dist/composables/useSaveValidationRollout.js +0 -9
  74. package/dist/enums/save-validation.js +0 -4
  75. package/dist/src/@types/save-validation.d.ts +0 -19
  76. package/dist/src/components/organisms/validation/ValidationErrorDrawer.vue.d.ts +0 -2
  77. package/dist/src/composables/useSaveValidation.d.ts +0 -6
  78. package/dist/src/composables/useSaveValidationRollout.d.ts +0 -3
  79. package/dist/src/enums/save-validation.d.ts +0 -27
  80. package/dist/src/stores/save-validation.d.ts +0 -22
  81. package/dist/stores/save-validation.js +0 -30
@@ -1,33 +1,34 @@
1
- var ot = Object.defineProperty;
2
- var st = (h, p, t) => p in h ? ot(h, p, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[p] = t;
3
- var $ = (h, p, t) => st(h, typeof p != "symbol" ? p + "" : p, t);
4
- import { UIElementType as g, UEAttr as N, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as nt } from "../../../common-control.js";
6
- import { ATTR_PRODUCT_IMAGE as B, ATTR_PRODUCT_NAME as lt, ATTR_PRODUCT_PRICE as C, ATTR_PRODUCT_OLD_PRICE as v, ATTR_PRODUCT_OMNIBUS_PRICE as at, ATTR_PRODUCT_OMNIBUS_DISCOUNT as ct, ATTR_PRODUCT_BUTTON as q, ATTR_DATA_CARD_COMPOSITION as V, ATTR_DATA_CUSTOM_ATTRIBUTES as j, ATTR_CUSTOM_PREFIX as I, SELECTOR_ATTRIBUTE_ROW as R, ATTR_DATA_ATTRIBUTE_TYPE as E, BUILT_IN_DEFAULT_ATTRIBUTES as dt } from "../../constants/selectors.js";
7
- import { DEFAULT_COMPOSITION as K, DEFAULT_VISIBILITY as W } from "../../constants/defaultConfig.js";
8
- import { RecommendationConfigService as _ } from "../../services/configService.js";
9
- import { useRecommendationExtensionStore as ut } from "../../store/recommendation.js";
10
- import { ATTRIBUTE_CELL_CLASS as mt, gridElementRenderer as ht, DEFAULT_CELL_PADDING as pt, buildFillerCell as gt } from "../../templates/grid/elementRenderer.js";
11
- import { listElementRenderer as bt } from "../../templates/list/elementRenderer.js";
12
- import { resolveInlinePriceOrder as ft, toDisplayName as _t, toDisplayableAttributeValue as yt, buildElementRenderer as z } from "../../templates/utils.js";
13
- import { normalizeCompositionKeys as Ct, normalizeCustomAttrValues as St, compositionKeyToProductAttr as w, resolveRowCompositionKey as At, filterToProductAttrValue as y, findAttributeRow as Tt, rewriteLegacyRowKeyHtml as G, bareAttributeName as D, isDefaultProductAttr as $t, productAttrToCompositionKey as k } from "../../utils/compositionKeys.js";
14
- import { getTableDisplayValue as It } from "../../utils/tagName.js";
15
- import { isPartnerManagedBlock as vt, regenerateProductRowsWithStyles as Nt, getCurrentLayout as Rt } from "../main/utils.js";
16
- const Et = "ui-elements-recommendation-card-composition", U = ".product-card-wrapper > tbody", Y = ".product-info-cell > table > tbody", O = "data-visibility", X = {
1
+ var lt = Object.defineProperty;
2
+ var at = (h, p, t) => p in h ? lt(h, p, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[p] = t;
3
+ var $ = (h, p, t) => at(h, typeof p != "symbol" ? p + "" : p, t);
4
+ import { UIElementType as _, UEAttr as D, ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { CommonControl as ct } from "../../../common-control.js";
6
+ import { ATTR_PRODUCT_IMAGE as x, ATTR_PRODUCT_NAME as dt, ATTR_PRODUCT_PRICE as C, ATTR_PRODUCT_OLD_PRICE as L, ATTR_PRODUCT_OMNIBUS_PRICE as ut, ATTR_PRODUCT_OMNIBUS_DISCOUNT as mt, ATTR_PRODUCT_BUTTON as F, ATTR_RECOMMENDATION_TITLE as I, ATTR_DATA_CARD_COMPOSITION as K, ATTR_DATA_CUSTOM_ATTRIBUTES as W, ATTR_CUSTOM_PREFIX as v, SELECTOR_ATTRIBUTE_ROW as N, SELECTOR_TITLE_CELL as z, ATTR_DATA_ATTRIBUTE_TYPE as R, BUILT_IN_DEFAULT_ATTRIBUTES as ht } from "../../constants/selectors.js";
7
+ import { DEFAULT_COMPOSITION as G, DEFAULT_VISIBILITY as Y } from "../../constants/defaultConfig.js";
8
+ import { RecommendationConfigService as g } from "../../services/configService.js";
9
+ import { useRecommendationExtensionStore as pt } from "../../store/recommendation.js";
10
+ import { ATTRIBUTE_CELL_CLASS as _t, gridElementRenderer as gt, DEFAULT_CELL_PADDING as ft, buildFillerCell as bt } from "../../templates/grid/elementRenderer.js";
11
+ import { listElementRenderer as yt } from "../../templates/list/elementRenderer.js";
12
+ import { buildTitleRows as Tt, DEFAULT_TITLE_PARAGRAPH as Ct, DEFAULT_TITLE_TEXT as St } from "../../templates/titleRows.js";
13
+ import { resolveInlinePriceOrder as At, toDisplayName as It, toDisplayableAttributeValue as $t, buildElementRenderer as X } from "../../templates/utils.js";
14
+ import { normalizeCompositionKeys as vt, normalizeCustomAttrValues as Nt, compositionKeyToProductAttr as k, resolveRowCompositionKey as Rt, filterToProductAttrValue as T, findAttributeRow as Et, rewriteLegacyRowKeyHtml as J, bareAttributeName as O, isDefaultProductAttr as Lt, productAttrToCompositionKey as U } from "../../utils/compositionKeys.js";
15
+ import { getTableDisplayValue as Dt } from "../../utils/tagName.js";
16
+ import { isPartnerManagedBlock as Ot, regenerateProductRowsWithStyles as wt, getMainContainerTbody as Pt, getCurrentLayout as Ht } from "../main/utils.js";
17
+ const Bt = "ui-elements-recommendation-card-composition", q = ".product-card-wrapper > tbody", Q = ".product-info-cell > table > tbody", w = "data-visibility", kt = "spacer", Z = {
17
18
  ADD_ATTRIBUTE: "addAttribute"
18
- }, b = 5, L = "reorderIcon_", Dt = '<svg width="14" height="10" viewBox="0 0 14 10" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><circle cx="2" cy="2.5" r="1.2"/><circle cx="7" cy="2.5" r="1.2"/><circle cx="12" cy="2.5" r="1.2"/><circle cx="2" cy="7.5" r="1.2"/><circle cx="7" cy="7.5" r="1.2"/><circle cx="12" cy="7.5" r="1.2"/></svg>', m = [
19
- { key: B, label: "Product Image" },
20
- { key: lt, label: "Product Name" },
19
+ }, f = 5, P = "reorderIcon_", Ut = '<svg width="14" height="10" viewBox="0 0 14 10" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><circle cx="2" cy="2.5" r="1.2"/><circle cx="7" cy="2.5" r="1.2"/><circle cx="12" cy="2.5" r="1.2"/><circle cx="2" cy="7.5" r="1.2"/><circle cx="7" cy="7.5" r="1.2"/><circle cx="12" cy="7.5" r="1.2"/></svg>', m = [
20
+ { key: x, label: "Product Image" },
21
+ { key: dt, label: "Product Name" },
21
22
  { key: C, label: "Product Price" },
22
- { key: v, label: "Product Original Price" },
23
- { key: at, label: "Omnibus Price" },
24
- { key: ct, label: "Omnibus Discount" },
25
- { key: q, label: "Product Button" }
26
- ], Ot = new Set(m.map((h) => h.key)), T = "customAttr_", P = "deleteAttr_";
27
- class Wt extends nt {
23
+ { key: L, label: "Product Original Price" },
24
+ { key: ut, label: "Omnibus Price" },
25
+ { key: mt, label: "Omnibus Discount" },
26
+ { key: F, label: "Product Button" }
27
+ ], E = { key: I, label: "Title" }, qt = new Set(m.map((h) => h.key)), A = "customAttr_", H = "deleteAttr_";
28
+ class ee extends ct {
28
29
  constructor() {
29
30
  super(...arguments);
30
- $(this, "store", ut());
31
+ $(this, "store", pt());
31
32
  $(this, "unsubscribeStore", null);
32
33
  $(this, "eventController", null);
33
34
  /**
@@ -37,7 +38,7 @@ class Wt extends nt {
37
38
  $(this, "reorderInProgress", !1);
38
39
  }
39
40
  getId() {
40
- return Et;
41
+ return Bt;
41
42
  }
42
43
  // ========================================================================
43
44
  // Lifecycle
@@ -48,11 +49,11 @@ class Wt extends nt {
48
49
  ${this._GuToggle(`visibility_${d.key}`)}
49
50
  </div>
50
51
  `).join(""), e = Array.from(
51
- { length: b },
52
+ { length: f },
52
53
  (d, c) => `
53
- <div data-custom-select-key="${T}${c}" style="display: none;">
54
+ <div data-custom-select-key="${A}${c}" style="display: none;">
54
55
  ${this._GuSelect({
55
- name: `${T}${c}`,
56
+ name: `${A}${c}`,
56
57
  placeholder: this.api.translate("Select Attribute"),
57
58
  options: [],
58
59
  // A partner's attribute list runs long; search beats scrolling.
@@ -60,37 +61,37 @@ class Wt extends nt {
60
61
  })}
61
62
  </div>
62
63
  `
63
- ).join(""), r = m.length + b, i = Array.from(
64
+ ).join(""), r = m.length + f, i = Array.from(
64
65
  { length: r },
65
66
  (d, c) => `
66
- <div data-reorder-icon-key="${L}${c}" style="display: none;">
67
- <${g.BUTTON}
67
+ <div data-reorder-icon-key="${P}${c}" style="display: none;">
68
+ <${_.BUTTON}
68
69
  class="drag-handle-btn flat-inline flat-white"
69
- ${N.BUTTON.name}="${L}${c}"
70
+ ${D.BUTTON.name}="${P}${c}"
70
71
  >
71
- <${g.ICON}
72
+ <${_.ICON}
72
73
  src="reorder"
73
74
  class="icon-button"
74
- ></${g.ICON}>
75
- </${g.BUTTON}>
75
+ ></${_.ICON}>
76
+ </${_.BUTTON}>
76
77
  </div>
77
78
  `
78
- ).join(""), o = Array.from(
79
- { length: b },
79
+ ).join(""), s = Array.from(
80
+ { length: f },
80
81
  (d, c) => `
81
- <div data-custom-delete-key="${P}${c}" style="display: none;">
82
- <${g.BUTTON}
82
+ <div data-custom-delete-key="${H}${c}" style="display: none;">
83
+ <${_.BUTTON}
83
84
  class="custom-attr-delete flat-inline flat-white"
84
- ${N.BUTTON.name}="${P}${c}"
85
+ ${D.BUTTON.name}="${H}${c}"
85
86
  >
86
- <${g.ICON}
87
+ <${_.ICON}
87
88
  src="delete"
88
89
  class="icon-button"
89
- ></${g.ICON}>
90
- </${g.BUTTON}>
90
+ ></${_.ICON}>
91
+ </${_.BUTTON}>
91
92
  </div>
92
93
  `
93
- ).join(""), s = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
94
+ ).join(""), o = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
94
95
  "Drag and drop the card elements to reorder them, adjust their visibility or add new attributes up to 5."
95
96
  ), l = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
96
97
  return `
@@ -100,7 +101,7 @@ class Wt extends nt {
100
101
  ${n}
101
102
  ${l}
102
103
  <!-- cspell:disable-next-line -->
103
- <a href="${s}" target="_blank" rel="noopener noreferrer">${a}</a>.
104
+ <a href="${o}" target="_blank" rel="noopener noreferrer">${a}</a>.
104
105
  </p>
105
106
  </div>
106
107
 
@@ -113,17 +114,26 @@ class Wt extends nt {
113
114
  </div>
114
115
 
115
116
  <div class="custom-delete-store" style="display: none;">
116
- ${o}
117
+ ${s}
117
118
  </div>
118
119
 
119
120
  <div class="reorder-icon-store" style="display: none;">
120
121
  ${i}
121
122
  </div>
122
123
 
124
+ <div class="orderable-list">
125
+ <div class="orderable-item title-item" data-key="${E.key}">
126
+ <span class="item-label">${this.api.translate(E.label)}</span>
127
+ <div class="item-action">
128
+ ${this._GuToggle(`visibility_${E.key}`)}
129
+ </div>
130
+ </div>
131
+ </div>
132
+
123
133
  <div class="orderable-list" data-composition-list></div>
124
134
 
125
135
  ${this._GuButton({
126
- name: X.ADD_ATTRIBUTE,
136
+ name: Z.ADD_ATTRIBUTE,
127
137
  label: this.api.translate("Add Attribute"),
128
138
  id: "guido__btn-add-attribute"
129
139
  })}
@@ -144,7 +154,7 @@ class Wt extends nt {
144
154
  const t = (r = this.getContainer()) == null ? void 0 : r.querySelector("[data-card-composition-control]");
145
155
  if (!t)
146
156
  return;
147
- const e = vt(this.currentNode);
157
+ const e = Ot(this.currentNode);
148
158
  t.style.pointerEvents = e ? "none" : "", t.style.opacity = e ? "0.5" : "";
149
159
  }
150
160
  onTemplateNodeUpdated(t) {
@@ -157,17 +167,17 @@ class Wt extends nt {
157
167
  // Initialization
158
168
  // ========================================================================
159
169
  _initializeComposition() {
160
- const t = this._readCompositionFromNode(), e = this._readCustomAttributesFromNode(), r = this._readVisibilityFromRows(), i = this._renderOrderableItems(t, e), o = this._buildVisibilityValues(r);
161
- this.api.updateValues(o), i && this._initializeCustomSelects(e), this._updateAddButtonState();
170
+ const t = this._readCompositionFromNode(), e = this._readCustomAttributesFromNode(), r = this._readVisibilityFromRows(), i = this._renderOrderableItems(t, e), s = this._buildVisibilityValues(r);
171
+ this.api.updateValues(s), i && this._initializeCustomSelects(e), this._updateAddButtonState();
162
172
  }
163
173
  _registerValueChangeListeners() {
164
- m.forEach((t) => {
174
+ [E, ...m].forEach((t) => {
165
175
  this.api.onValueChanged(`visibility_${t.key}`, (e) => {
166
176
  this._applyVisibilityToBlock(t.key, e);
167
177
  });
168
178
  });
169
- for (let t = 0; t < b; t++) {
170
- const e = `${T}${t}`, r = t;
179
+ for (let t = 0; t < f; t++) {
180
+ const e = `${A}${t}`, r = t;
171
181
  this.api.onValueChanged(e, (i) => {
172
182
  this._onCustomAttributeChanged(r, i);
173
183
  });
@@ -178,24 +188,24 @@ class Wt extends nt {
178
188
  // ========================================================================
179
189
  _readCompositionFromNode() {
180
190
  if (!this.currentNode || !("getAttribute" in this.currentNode))
181
- return [...K];
182
- const t = this.currentNode.getAttribute(V);
191
+ return [...G];
192
+ const t = this.currentNode.getAttribute(K);
183
193
  if (t)
184
194
  return this._normalizeComposition(t.split(",").filter(Boolean));
185
- const { composition: e } = _.getConfig(this.currentNode);
186
- return e != null && e.length ? this._normalizeComposition([...e]) : [...K];
195
+ const { composition: e } = g.getConfig(this.currentNode);
196
+ return e != null && e.length ? this._normalizeComposition([...e]) : [...G];
187
197
  }
188
198
  /** Upgrades legacy bare-name custom keys to the canonical form. (SD-147101) */
189
199
  _normalizeComposition(t) {
190
- return Ct(t, this.currentNode, this.store.filterList);
200
+ return vt(t, this.currentNode, this.store.filterList);
191
201
  }
192
202
  _readCustomAttributesFromNode() {
193
203
  if (!this.currentNode || !("getAttribute" in this.currentNode))
194
204
  return [];
195
- const t = this.currentNode.getAttribute(j);
205
+ const t = this.currentNode.getAttribute(W);
196
206
  if (t)
197
207
  try {
198
- return St(
208
+ return Nt(
199
209
  JSON.parse(t).map((e) => String(e)),
200
210
  this.currentNode,
201
211
  this.store.filterList
@@ -203,39 +213,46 @@ class Wt extends nt {
203
213
  } catch {
204
214
  return [];
205
215
  }
206
- return this._readCompositionFromNode().filter((e) => e.startsWith(I)).map(w);
216
+ return this._readCompositionFromNode().filter((e) => e.startsWith(v)).map(k);
207
217
  }
208
218
  _readVisibilityFromRows() {
209
219
  if (!this.currentNode)
210
220
  return this._getDefaultVisibilities();
211
- const t = Array.from(this.currentNode.querySelectorAll(R)), e = this._extractVisibilityFromRows(t);
221
+ const t = Array.from(this.currentNode.querySelectorAll(N)), e = this._extractVisibilityFromRows(t);
212
222
  if (Object.keys(e).length > 0)
213
- return this._mergeWithDefaults(e);
214
- const r = _.getConfig(this.currentNode).visibility;
215
- return this._mergeWithDefaults({ ...r });
223
+ return this._withTitlePresence(this._mergeWithDefaults(e));
224
+ const r = g.getConfig(this.currentNode).visibility;
225
+ return this._withTitlePresence(this._mergeWithDefaults({ ...r }));
226
+ }
227
+ _withTitlePresence(t) {
228
+ return t[I] = this._hasTitle(), t;
229
+ }
230
+ _hasTitle() {
231
+ var t;
232
+ return !!((t = this.currentNode) != null && t.querySelector(z));
216
233
  }
217
234
  _getDefaultVisibilities() {
218
- return { ...W };
235
+ return { ...Y };
219
236
  }
220
237
  _extractVisibilityFromRows(t) {
221
238
  const e = {};
222
239
  return t.forEach((r) => {
223
240
  if (!("getAttribute" in r))
224
241
  return;
225
- const i = At(r), o = r.getAttribute(O);
226
- i && o !== null && (e[i] = this._parseVisibilityValue(o));
242
+ const i = Rt(r), s = r.getAttribute(w);
243
+ i && s !== null && (e[i] = this._parseVisibilityValue(s));
227
244
  }), e;
228
245
  }
229
246
  _parseVisibilityValue(t) {
230
247
  return t === "1" || t === "true";
231
248
  }
232
249
  _mergeWithDefaults(t) {
233
- return Object.entries(W).forEach(([e, r]) => {
250
+ return Object.entries(Y).forEach(([e, r]) => {
234
251
  e in t || (t[e] = r);
235
252
  }), t;
236
253
  }
237
254
  _buildVisibilityValues(t) {
238
- return m.reduce((e, r) => (e[`visibility_${r.key}`] = t[r.key] ?? !0, e), {});
255
+ return [E, ...m].reduce((e, r) => (e[`visibility_${r.key}`] = t[r.key] ?? !0, e), {});
239
256
  }
240
257
  // ========================================================================
241
258
  // UI Rendering (Orderable List)
@@ -252,22 +269,22 @@ class Wt extends nt {
252
269
  const i = r.querySelector("[data-composition-list]");
253
270
  if (!i)
254
271
  return !1;
255
- const o = !_.getConfig(this.currentNode).priceMovedToNextLine;
256
- if (!(i.dataset.inlinePrices !== String(o)) && this._tryReorderInPlace(i, t))
272
+ const s = !g.getConfig(this.currentNode).priceMovedToNextLine;
273
+ if (!(i.dataset.inlinePrices !== String(s)) && this._tryReorderInPlace(i, t))
257
274
  return !1;
258
- i.dataset.inlinePrices = String(o);
259
- const n = new Set(e), l = ft(t);
275
+ i.dataset.inlinePrices = String(s);
276
+ const n = new Set(e), l = At(t);
260
277
  let a = 0, d = 0;
261
278
  const c = t.map((u) => {
262
- if (o && (u === C || u === v))
279
+ if (s && (u === C || u === L))
263
280
  return u === l.anchor ? this._createPriceGroupItemHtml(d++, l.originalFirst) : "";
264
- if (Ot.has(u)) {
265
- const f = m.find((S) => S.key === u);
266
- return this._createBuiltInItemHtml(f, d++);
281
+ if (qt.has(u)) {
282
+ const b = m.find((S) => S.key === u);
283
+ return this._createBuiltInItemHtml(b, d++);
267
284
  }
268
- if (u.startsWith(I)) {
269
- const f = w(u);
270
- if (n.has(f))
285
+ if (u.startsWith(v)) {
286
+ const b = k(u);
287
+ if (n.has(b))
271
288
  return this._createCustomItemHtml(u, a++, d++);
272
289
  }
273
290
  return "";
@@ -287,8 +304,8 @@ class Wt extends nt {
287
304
  const i = r.map((a) => a.dataset.key).filter(Boolean);
288
305
  if (i.length !== e.length)
289
306
  return !1;
290
- const o = [...i].sort().join(","), s = [...e].sort().join(",");
291
- if (o !== s || e.some((a) => a.startsWith(I)))
307
+ const s = [...i].sort().join(","), o = [...e].sort().join(",");
308
+ if (s !== o || e.some((a) => a.startsWith(v)))
292
309
  return !1;
293
310
  const n = /* @__PURE__ */ new Map();
294
311
  r.forEach((a) => {
@@ -326,11 +343,11 @@ class Wt extends nt {
326
343
  */
327
344
  _createPriceGroupItemHtml(t, e) {
328
345
  var n, l;
329
- const r = ((n = m.find((a) => a.key === C)) == null ? void 0 : n.label) ?? "Product Price", i = ((l = m.find((a) => a.key === v)) == null ? void 0 : l.label) ?? "Product Original Price", o = (a, d) => `
346
+ const r = ((n = m.find((a) => a.key === C)) == null ? void 0 : n.label) ?? "Product Price", i = ((l = m.find((a) => a.key === L)) == null ? void 0 : l.label) ?? "Product Original Price", s = (a, d) => `
330
347
  <div class="price-suborderable-item" draggable="true" data-subkey="${a}">
331
- <span class="sub-drag-handle">${Dt}</span>
348
+ <span class="sub-drag-handle">${Ut}</span>
332
349
  <span class="item-label">${this.api.translate(d)}</span>
333
- </div>`, s = e ? o(v, i) + o(C, r) : o(C, r) + o(v, i);
350
+ </div>`, o = e ? s(L, i) + s(C, r) : s(C, r) + s(L, i);
334
351
  return `
335
352
  <div class="orderable-item price-group-item" draggable="true"
336
353
  data-key="${C}" data-group="prices">
@@ -339,7 +356,7 @@ class Wt extends nt {
339
356
  <span class="item-label">${this.api.translate("Product Prices")}</span>
340
357
  <div class="item-action" data-action-for="${C}"></div>
341
358
  </div>
342
- <div class="price-suborderable-list">${s}</div>
359
+ <div class="price-suborderable-list">${o}</div>
343
360
  </div>
344
361
  `;
345
362
  }
@@ -375,15 +392,15 @@ class Wt extends nt {
375
392
  if (r.length === 0)
376
393
  return [{ text: this._getDisplayNameForAttribute(t), value: t }];
377
394
  const i = /* @__PURE__ */ new Map();
378
- r.forEach((s) => i.set(s.attributeName, (i.get(s.attributeName) ?? 0) + 1));
379
- const o = new Set(e);
380
- return o.delete(t), r.filter((s) => !o.has(y(s))).map((s) => ({
395
+ r.forEach((o) => i.set(o.attributeName, (i.get(o.attributeName) ?? 0) + 1));
396
+ const s = new Set(e);
397
+ return s.delete(t), r.filter((o) => !s.has(T(o))).map((o) => ({
381
398
  text: this._toOptionLabel(
382
- s.displayName,
383
- s.type === "defaultAttribute",
384
- (i.get(s.attributeName) ?? 0) > 1
399
+ o.displayName,
400
+ o.type === "defaultAttribute",
401
+ (i.get(o.attributeName) ?? 0) > 1
385
402
  ),
386
- value: y(s)
403
+ value: T(o)
387
404
  }));
388
405
  }
389
406
  /**
@@ -394,8 +411,8 @@ class Wt extends nt {
394
411
  _initializeCustomSelects(t) {
395
412
  t.length !== 0 && setTimeout(() => {
396
413
  t.forEach((e, r) => {
397
- const i = `${T}${r}`, o = this._getSelectOptions(e, t);
398
- this.api.setUIEAttribute(i, N.SELECTPICKER.items, o), this.api.updateValues({ [i]: e });
414
+ const i = `${A}${r}`, s = this._getSelectOptions(e, t);
415
+ this.api.setUIEAttribute(i, D.SELECTPICKER.items, s), this.api.updateValues({ [i]: e });
399
416
  });
400
417
  }, 0);
401
418
  }
@@ -407,8 +424,8 @@ class Wt extends nt {
407
424
  m.forEach((e) => {
408
425
  const r = t.querySelector(`[data-toggle-key="${e.key}"]`), i = t.querySelector(`[data-action-for="${e.key}"]`);
409
426
  if (r && i) {
410
- const o = r.querySelector("ue-switcher");
411
- o && i.appendChild(o);
427
+ const s = r.querySelector("ue-switcher");
428
+ s && i.appendChild(s);
412
429
  }
413
430
  });
414
431
  }
@@ -418,10 +435,10 @@ class Wt extends nt {
418
435
  */
419
436
  _moveSelectsIntoItems(t, e) {
420
437
  for (let r = 0; r < e; r++) {
421
- const i = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${i}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
422
- if (o && s) {
423
- const n = o.querySelector("ue-select");
424
- n && s.appendChild(n);
438
+ const i = `${A}${r}`, s = t.querySelector(`[data-custom-select-key="${i}"]`), o = t.querySelector(`[data-custom-select-slot="${r}"]`);
439
+ if (s && o) {
440
+ const n = s.querySelector("ue-select");
441
+ n && o.appendChild(n);
425
442
  }
426
443
  }
427
444
  }
@@ -435,8 +452,8 @@ class Wt extends nt {
435
452
  m.forEach((e) => {
436
453
  const r = t.querySelector(`[data-toggle-key="${e.key}"]`), i = t.querySelector(`[data-action-for="${e.key}"]`);
437
454
  if (i) {
438
- const o = i.querySelector("ue-switcher");
439
- o && r && r.appendChild(o);
455
+ const s = i.querySelector("ue-switcher");
456
+ s && r && r.appendChild(s);
440
457
  }
441
458
  });
442
459
  }
@@ -445,11 +462,11 @@ class Wt extends nt {
445
462
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
446
463
  */
447
464
  _rescueSelectsToStore(t) {
448
- for (let e = 0; e < b; e++) {
449
- const r = `${T}${e}`, i = t.querySelector(`[data-custom-select-key="${r}"]`), o = t.querySelector(`[data-custom-select-slot="${e}"]`);
450
- if (o) {
451
- const s = o.querySelector("ue-select");
452
- s && i && i.appendChild(s);
465
+ for (let e = 0; e < f; e++) {
466
+ const r = `${A}${e}`, i = t.querySelector(`[data-custom-select-key="${r}"]`), s = t.querySelector(`[data-custom-select-slot="${e}"]`);
467
+ if (s) {
468
+ const o = s.querySelector("ue-select");
469
+ o && i && i.appendChild(o);
453
470
  }
454
471
  }
455
472
  }
@@ -459,10 +476,10 @@ class Wt extends nt {
459
476
  */
460
477
  _moveDeleteButtonsIntoItems(t, e) {
461
478
  for (let r = 0; r < e; r++) {
462
- const i = `${P}${r}`, o = t.querySelector(`[data-custom-delete-key="${i}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
463
- if (o && s) {
464
- const n = o.querySelector("ue-button");
465
- n && s.appendChild(n);
479
+ const i = `${H}${r}`, s = t.querySelector(`[data-custom-delete-key="${i}"]`), o = t.querySelector(`[data-custom-delete-slot="${r}"]`);
480
+ if (s && o) {
481
+ const n = s.querySelector("ue-button");
482
+ n && o.appendChild(n);
466
483
  }
467
484
  }
468
485
  }
@@ -471,11 +488,11 @@ class Wt extends nt {
471
488
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
472
489
  */
473
490
  _rescueDeleteButtonsToStore(t) {
474
- for (let e = 0; e < b; e++) {
475
- const r = `${P}${e}`, i = t.querySelector(`[data-custom-delete-key="${r}"]`), o = t.querySelector(`[data-custom-delete-slot="${e}"]`);
476
- if (o) {
477
- const s = o.querySelector("ue-button");
478
- s && i && i.appendChild(s);
491
+ for (let e = 0; e < f; e++) {
492
+ const r = `${H}${e}`, i = t.querySelector(`[data-custom-delete-key="${r}"]`), s = t.querySelector(`[data-custom-delete-slot="${e}"]`);
493
+ if (s) {
494
+ const o = s.querySelector("ue-button");
495
+ o && i && i.appendChild(o);
479
496
  }
480
497
  }
481
498
  }
@@ -485,10 +502,10 @@ class Wt extends nt {
485
502
  */
486
503
  _moveReorderIconsIntoItems(t, e) {
487
504
  for (let r = 0; r < e; r++) {
488
- const i = `${L}${r}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
489
- if (o && s) {
490
- const n = o.querySelector("ue-button");
491
- n && s.appendChild(n);
505
+ const i = `${P}${r}`, s = t.querySelector(`[data-reorder-icon-key="${i}"]`), o = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
506
+ if (s && o) {
507
+ const n = s.querySelector("ue-button");
508
+ n && o.appendChild(n);
492
509
  }
493
510
  }
494
511
  }
@@ -497,12 +514,12 @@ class Wt extends nt {
497
514
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
498
515
  */
499
516
  _rescueReorderIconsToStore(t) {
500
- const e = m.length + b;
517
+ const e = m.length + f;
501
518
  for (let r = 0; r < e; r++) {
502
- const i = `${L}${r}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
503
- if (s) {
504
- const n = s.querySelector("ue-button");
505
- n && o && o.appendChild(n);
519
+ const i = `${P}${r}`, s = t.querySelector(`[data-reorder-icon-key="${i}"]`), o = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
520
+ if (o) {
521
+ const n = o.querySelector("ue-button");
522
+ n && s && s.appendChild(n);
506
523
  }
507
524
  }
508
525
  }
@@ -516,8 +533,8 @@ class Wt extends nt {
516
533
  return;
517
534
  const r = e.querySelector("[data-composition-list]"), i = e.querySelector("#guido__btn-add-attribute");
518
535
  r && (this._setupDragAndDrop(r, t), this._setupDeleteHandler(r, t)), i && i.addEventListener("click", () => {
519
- const o = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !o.has(y(n)));
520
- s && this._onAddAttribute(y(s), s.displayName);
536
+ const s = new Set(this._readCustomAttributesFromNode()), o = this._getAddableFilters().find((n) => !s.has(T(n)));
537
+ o && this._onAddAttribute(T(o), o.displayName);
521
538
  }, { signal: t });
522
539
  }
523
540
  /**
@@ -529,9 +546,9 @@ class Wt extends nt {
529
546
  const e = [];
530
547
  return t.querySelectorAll(".orderable-item").forEach((r) => {
531
548
  const i = r;
532
- i.dataset.group === "prices" ? i.querySelectorAll(".price-suborderable-item").forEach((o) => {
533
- const s = o.dataset.subkey;
534
- s && e.push(s);
549
+ i.dataset.group === "prices" ? i.querySelectorAll(".price-suborderable-item").forEach((s) => {
550
+ const o = s.dataset.subkey;
551
+ o && e.push(o);
535
552
  }) : i.dataset.key && e.push(i.dataset.key);
536
553
  }), e;
537
554
  }
@@ -555,42 +572,42 @@ class Wt extends nt {
555
572
  * identically.
556
573
  */
557
574
  _registerDragHandlers(t, e, r) {
558
- let i = null, o = null;
559
- const s = (n) => n.target.closest(r.itemSelector);
575
+ let i = null, s = null;
576
+ const o = (n) => n.target.closest(r.itemSelector);
560
577
  t.addEventListener("dragstart", (n) => {
561
578
  var d;
562
579
  const l = n.target;
563
580
  if (r.ignoreSelector && l.closest(r.ignoreSelector))
564
581
  return;
565
- const a = s(n);
582
+ const a = o(n);
566
583
  a && (i = a, a.classList.add("dragging"), (d = n.dataTransfer) == null || d.setData("text/plain", a.dataset.key ?? a.dataset.subkey ?? ""));
567
584
  }, { signal: e }), t.addEventListener("dragend", () => {
568
- i == null || i.classList.remove("dragging"), o == null || o.classList.remove("drag-over"), i = null, o = null;
585
+ i == null || i.classList.remove("dragging"), s == null || s.classList.remove("drag-over"), i = null, s = null;
569
586
  }, { signal: e }), t.addEventListener("dragover", (n) => {
570
587
  if (!i)
571
588
  return;
572
- const l = s(n);
589
+ const l = o(n);
573
590
  if (!l)
574
591
  return;
575
592
  n.preventDefault();
576
593
  const a = l !== i ? l : null;
577
- a !== o && (o == null || o.classList.remove("drag-over"), o = a, o == null || o.classList.add("drag-over"));
594
+ a !== s && (s == null || s.classList.remove("drag-over"), s = a, s == null || s.classList.add("drag-over"));
578
595
  }, { signal: e }), t.addEventListener("drop", (n) => {
579
596
  var c;
580
- const l = i && s(n);
597
+ const l = i && o(n);
581
598
  if (!i || !l || l === i)
582
599
  return;
583
600
  n.preventDefault();
584
601
  const a = l.getBoundingClientRect(), d = n.clientY < a.top + a.height / 2;
585
- (c = r.getDropParent(l)) == null || c.insertBefore(i, d ? l : l.nextSibling), o == null || o.classList.remove("drag-over"), i.classList.remove("dragging"), i = null, o = null, this._onReorder(this._extractCompositionOrder(t));
602
+ (c = r.getDropParent(l)) == null || c.insertBefore(i, d ? l : l.nextSibling), s == null || s.classList.remove("drag-over"), i.classList.remove("dragging"), i = null, s = null, this._onReorder(this._extractCompositionOrder(t));
586
603
  }, { signal: e });
587
604
  }
588
605
  _setupDeleteHandler(t, e) {
589
606
  t.addEventListener("click", (r) => {
590
- const o = r.target.closest(".custom-attr-delete");
591
- if (!o)
607
+ const s = r.target.closest(".custom-attr-delete");
608
+ if (!s)
592
609
  return;
593
- const s = o.closest("[data-custom-index]"), n = s == null ? void 0 : s.dataset.customIndex;
610
+ const o = s.closest("[data-custom-index]"), n = o == null ? void 0 : o.dataset.customIndex;
594
611
  n !== void 0 && this._onDeleteCustomAttribute(Number(n));
595
612
  }, { signal: e });
596
613
  }
@@ -598,10 +615,10 @@ class Wt extends nt {
598
615
  // Actions (Add, Delete, Reorder)
599
616
  // ========================================================================
600
617
  _onAddAttribute(t, e) {
601
- const r = k(t), i = this._readCompositionFromNode();
618
+ const r = U(t), i = this._readCompositionFromNode();
602
619
  i.push(r);
603
- const o = [...this._readCustomAttributesFromNode(), t];
604
- this._updateBothAttributes(i, o), this._injectCustomAttributeHtml(t, e, r, i), this._renderOrderableItems(i, o), this._initializeCustomSelects(o), this._updateAddButtonState();
620
+ const s = [...this._readCustomAttributesFromNode(), t];
621
+ this._updateBothAttributes(i, s), this._injectCustomAttributeHtml(t, e, r, i), this._renderOrderableItems(i, s), this._initializeCustomSelects(s), this._updateAddButtonState();
605
622
  }
606
623
  /**
607
624
  * Removes a single custom attribute by its index in the customAttrs array.
@@ -611,8 +628,8 @@ class Wt extends nt {
611
628
  const e = this._readCustomAttributesFromNode();
612
629
  if (e[t] === void 0)
613
630
  return;
614
- const i = this._readCompositionFromNode(), o = this._findNthCustomKeyIndex(i, t), s = i.filter((l, a) => a !== o), n = e.filter((l, a) => a !== t);
615
- this._updateBothAttributes(s, n), this._removeCustomAttributeHtml(s), this._renderOrderableItems(s, n), this._initializeCustomSelects(n), this._updateAddButtonState();
631
+ const i = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(i, t), o = i.filter((l, a) => a !== s), n = e.filter((l, a) => a !== t);
632
+ this._updateBothAttributes(o, n), this._removeCustomAttributeHtml(o), this._renderOrderableItems(o, n), this._initializeCustomSelects(n), this._updateAddButtonState();
616
633
  }
617
634
  /**
618
635
  * Handles changing a custom attribute's selection via its inline _GuSelect.
@@ -622,18 +639,18 @@ class Wt extends nt {
622
639
  const r = this._readCustomAttributesFromNode(), i = r[t];
623
640
  if (i === void 0 || i === e)
624
641
  return;
625
- const o = k(e), s = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(s, t);
626
- n !== -1 && (s[n] = o), r[t] = e;
642
+ const s = U(e), o = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(o, t);
643
+ n !== -1 && (o[n] = s), r[t] = e;
627
644
  const l = this._getDisplayNameForAttribute(e);
628
- this._updateBothAttributes(s, r), this._injectCustomAttributeHtml(e, l, o, s), this._renderOrderableItems(s, r), this._initializeCustomSelects(r);
645
+ this._updateBothAttributes(o, r), this._injectCustomAttributeHtml(e, l, s, o), this._renderOrderableItems(o, r), this._initializeCustomSelects(r);
629
646
  }
630
647
  _onReorder(t) {
631
- const e = t.filter((r) => r.startsWith(I)).map(w);
648
+ const e = t.filter((r) => r.startsWith(v)).map(k);
632
649
  this.reorderInProgress = !0;
633
650
  try {
634
651
  this._updateBothAttributes(t, e);
635
- const r = !_.getConfig(this.currentNode).priceMovedToNextLine;
636
- this._getCurrentLayout() === "grid" && !r ? this._reorderProductAttributes(t) : this.currentNode && Nt({
652
+ const r = !g.getConfig(this.currentNode).priceMovedToNextLine;
653
+ this._getCurrentLayout() === "grid" && !r ? this._reorderProductAttributes(t) : this.currentNode && wt({
637
654
  currentNode: this.currentNode,
638
655
  documentModifier: this.api.getDocumentModifier()
639
656
  });
@@ -651,13 +668,13 @@ class Wt extends nt {
651
668
  * DOM converge on the next composition change without writing on open.
652
669
  */
653
670
  _getExistingRowHtml(t, e) {
654
- const r = Tt(t, e);
671
+ const r = Et(t, e);
655
672
  if (r && "getOuterHTML" in r)
656
- return G(r.getOuterHTML(), e);
673
+ return J(r.getOuterHTML(), e);
657
674
  const i = t.querySelector(
658
- `${R}[${E}="${e}"]`
675
+ `${N}[${R}="${e}"]`
659
676
  );
660
- return i && "getOuterHTML" in i ? G(i.getOuterHTML(), e) : "";
677
+ return i && "getOuterHTML" in i ? J(i.getOuterHTML(), e) : "";
661
678
  }
662
679
  _injectCustomAttributeHtml(t, e, r, i) {
663
680
  if (!this.currentNode)
@@ -665,47 +682,47 @@ class Wt extends nt {
665
682
  this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, e, r, i) : this._injectListAttributeRow(t, e, r, i);
666
683
  }
667
684
  _injectGridAttributeRow(t, e, r, i) {
668
- const o = this.currentNode.querySelectorAll(U);
669
- if (!(o != null && o.length))
685
+ const s = this.currentNode.querySelectorAll(q);
686
+ if (!(s != null && s.length))
670
687
  return;
671
- const s = _.getConfig(this.currentNode), l = `0 ${Math.floor(s.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), d = this.store.recommendationProducts.length;
688
+ const o = g.getConfig(this.currentNode), l = `0 ${Math.floor(o.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), d = this.store.recommendationProducts.length;
672
689
  let c = 0;
673
- o.forEach((u) => {
674
- var F;
675
- const f = u.querySelector(R), S = ((F = f == null ? void 0 : f.querySelectorAll(`.${mt}`)) == null ? void 0 : F.length) || 1, x = (100 / S).toFixed(2), { bgStyle: J, bgAttr: Q } = this._extractSegmentBgFromCard(u), H = d > 0 ? Math.min(S, d - c) : S, Z = i.map((M) => {
676
- if (M === r) {
677
- const tt = Array.from(
678
- { length: H },
679
- (Lt, rt) => {
680
- const it = this._resolveAttributeContent(
690
+ s.forEach((u) => {
691
+ var V;
692
+ const b = u.querySelector(N), S = ((V = b == null ? void 0 : b.querySelectorAll(`.${_t}`)) == null ? void 0 : V.length) || 1, M = (100 / S).toFixed(2), { bgStyle: tt, bgAttr: et } = this._extractSegmentBgFromCard(u), B = d > 0 ? Math.min(S, d - c) : S, rt = i.map((j) => {
693
+ if (j === r) {
694
+ const it = Array.from(
695
+ { length: B },
696
+ (xt, ot) => {
697
+ const nt = this._resolveAttributeContent(
681
698
  t,
682
699
  e,
683
- c + rt
700
+ c + ot
684
701
  );
685
702
  return this._getGridCellHtml(
686
703
  t,
687
- it,
688
- x,
689
- J,
690
- Q,
704
+ nt,
705
+ M,
706
+ tt,
707
+ et,
691
708
  l
692
709
  );
693
710
  }
694
- ).join(""), et = gt(x, l).repeat(S - H);
695
- return `<tr class="recommendation-attribute-row" ${E}="${r}" ${O}="1">${tt}${et}</tr>`;
711
+ ).join(""), st = bt(M, l).repeat(S - B);
712
+ return `<tr class="recommendation-attribute-row" ${R}="${r}" ${w}="1">${it}${st}</tr>`;
696
713
  }
697
- return this._getExistingRowHtml(u, M);
714
+ return this._getExistingRowHtml(u, j);
698
715
  }).join("");
699
- c += H, d > 0 && c >= d && (c = 0), a.modifyHtml(u).setInnerHtml(Z);
700
- }), a.apply(new A(`${this.api.translate("Add custom attribute")}: ${e}`));
716
+ c += B, d > 0 && c >= d && (c = 0), a.modifyHtml(u).setInnerHtml(rt);
717
+ }), a.apply(new y(`${this.api.translate("Add custom attribute")}: ${e}`));
701
718
  }
702
719
  _injectListAttributeRow(t, e, r, i) {
703
- const o = this.currentNode.querySelectorAll(Y);
704
- if (!(o != null && o.length))
720
+ const s = this.currentNode.querySelectorAll(Q);
721
+ if (!(s != null && s.length))
705
722
  return;
706
- const s = i.filter((l) => l !== B && l !== q), n = this.api.getDocumentModifier();
707
- o.forEach((l, a) => {
708
- const d = s.map((c) => {
723
+ const o = i.filter((l) => l !== x && l !== F), n = this.api.getDocumentModifier();
724
+ s.forEach((l, a) => {
725
+ const d = o.map((c) => {
709
726
  if (c === r) {
710
727
  const u = this._resolveAttributeContent(t, e, a);
711
728
  return this._getListRowHtml(t, u, r);
@@ -713,7 +730,7 @@ class Wt extends nt {
713
730
  return this._getExistingRowHtml(l, c);
714
731
  }).join("");
715
732
  n.modifyHtml(l).setInnerHtml(d);
716
- }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${e}`));
733
+ }), n.apply(new y(`${this.api.translate("Add custom attribute")}: ${e}`));
717
734
  }
718
735
  /**
719
736
  * Removes a custom attribute by rebuilding product card content without it.
@@ -724,19 +741,19 @@ class Wt extends nt {
724
741
  return;
725
742
  const e = this._getCurrentLayout(), r = this.api.getDocumentModifier();
726
743
  if (e === "grid") {
727
- const i = this.currentNode.querySelectorAll(U);
728
- i == null || i.forEach((o) => {
729
- const s = this._buildCompositionHtml(o, t);
730
- r.modifyHtml(o).setInnerHtml(s);
744
+ const i = this.currentNode.querySelectorAll(q);
745
+ i == null || i.forEach((s) => {
746
+ const o = this._buildCompositionHtml(s, t);
747
+ r.modifyHtml(s).setInnerHtml(o);
731
748
  });
732
749
  } else {
733
- const i = t.filter((s) => s !== B && s !== q), o = this.currentNode.querySelectorAll(Y);
734
- o == null || o.forEach((s) => {
735
- const n = this._buildCompositionHtml(s, i);
736
- r.modifyHtml(s).setInnerHtml(n);
750
+ const i = t.filter((o) => o !== x && o !== F), s = this.currentNode.querySelectorAll(Q);
751
+ s == null || s.forEach((o) => {
752
+ const n = this._buildCompositionHtml(o, i);
753
+ r.modifyHtml(o).setInnerHtml(n);
737
754
  });
738
755
  }
739
- r.apply(new A(this.api.translate("Remove custom attribute")));
756
+ r.apply(new y(this.api.translate("Remove custom attribute")));
740
757
  }
741
758
  // ========================================================================
742
759
  // DOM Mutation (Block Root Attributes, Reorder)
@@ -752,10 +769,10 @@ class Wt extends nt {
752
769
  if (!this.currentNode)
753
770
  return;
754
771
  const r = {
755
- ..._.getConfig(this.currentNode),
772
+ ...g.getConfig(this.currentNode),
756
773
  composition: t
757
774
  };
758
- this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(V, t.join(",")).setAttribute(j, JSON.stringify(e)).setNodeConfig(r).apply(new A(this.api.translate("Update card composition")));
775
+ this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(K, t.join(",")).setAttribute(W, JSON.stringify(e)).setNodeConfig(r).apply(new y(this.api.translate("Update card composition")));
759
776
  }
760
777
  /**
761
778
  * Reorders attribute rows within each product card based on composition order.
@@ -764,14 +781,14 @@ class Wt extends nt {
764
781
  _reorderProductAttributes(t) {
765
782
  if (!this.currentNode)
766
783
  return;
767
- const e = this.currentNode.querySelectorAll(U);
784
+ const e = this.currentNode.querySelectorAll(q);
768
785
  if (!(e != null && e.length))
769
786
  return;
770
787
  const r = this.api.getDocumentModifier();
771
788
  e.forEach((i) => {
772
- const o = this._buildCompositionHtml(i, t);
773
- r.modifyHtml(i).setInnerHtml(o);
774
- }), r.apply(new A(this.api.translate("Reorder product attributes")));
789
+ const s = this._buildCompositionHtml(i, t);
790
+ r.modifyHtml(i).setInnerHtml(s);
791
+ }), r.apply(new y(this.api.translate("Reorder product attributes")));
775
792
  }
776
793
  /**
777
794
  * Builds HTML string with attributes ordered according to composition.
@@ -786,19 +803,70 @@ class Wt extends nt {
786
803
  _applyVisibilityToBlock(t, e) {
787
804
  if (!this.currentNode)
788
805
  return;
789
- const r = this.currentNode.querySelectorAll(`${R}[${E}="${t}"]`);
806
+ if (t === I) {
807
+ this._applyTitleVisibilityToBlock(e);
808
+ return;
809
+ }
810
+ const r = this.currentNode.querySelectorAll(`${N}[${R}="${t}"]`);
790
811
  if (!(r != null && r.length))
791
812
  return;
792
- const i = e ? "1" : "0", o = e ? this.api.translate("visible") : this.api.translate("hidden"), s = `${this.api.translate("Set visibility")}: ${t} → ${o}`, n = this.api.getDocumentModifier();
813
+ const i = e ? "1" : "0", s = e ? this.api.translate("visible") : this.api.translate("hidden"), o = `${this.api.translate("Set visibility")}: ${t} → ${s}`, n = this.api.getDocumentModifier();
793
814
  r.forEach((a) => {
794
- const d = It(a), c = e ? d : "none";
795
- n.modifyHtml(a).setStyle("display", c).setAttribute(O, i);
815
+ const d = Dt(a), c = e ? d : "none";
816
+ n.modifyHtml(a).setStyle("display", c).setAttribute(w, i);
796
817
  });
797
818
  const l = {
798
- ..._.getConfig(this.currentNode),
819
+ ...g.getConfig(this.currentNode),
799
820
  visibility: { ...this._readVisibilityFromRows(), [t]: e }
800
821
  };
801
- n.modifyHtml(this.currentNode).setNodeConfig(l), n.apply(new A(s));
822
+ n.modifyHtml(this.currentNode).setNodeConfig(l), n.apply(new y(o));
823
+ }
824
+ _applyTitleVisibilityToBlock(t) {
825
+ const e = g.getConfig(this.currentNode), r = t ? this._resolveTitleInjection(e.rowSpacing) : null, i = t ? [] : this._findTitleRows(), s = t ? this._hasTitle() || !r : i.length === 0;
826
+ if (!this.currentNode || s)
827
+ return;
828
+ const o = this.api.getDocumentModifier();
829
+ r ? o.modifyHtml(r.containerBody).setInnerHtml(r.html) : i.forEach((l) => o.modifyHtml(l).delete()), o.modifyHtml(this.currentNode).setNodeConfig({
830
+ ...e,
831
+ visibility: { ...this._readVisibilityFromRows(), [I]: t }
832
+ });
833
+ const n = t ? this.api.translate("visible") : this.api.translate("hidden");
834
+ o.apply(new y(
835
+ `${this.api.translate("Set visibility")}: ${I} → ${n}`
836
+ ));
837
+ }
838
+ _resolveTitleInjection(t) {
839
+ const e = this._findTitleContainerBody(), r = e ? this._readInnerHtml(e) : null;
840
+ return !e || r === null ? null : {
841
+ containerBody: e,
842
+ html: Tt(this._defaultTitleParagraph(), !0, t) + r
843
+ };
844
+ }
845
+ _findTitleRows() {
846
+ var e;
847
+ const t = Array.from(((e = this.currentNode) == null ? void 0 : e.querySelectorAll(
848
+ `${N}[${R}="${I}"]`
849
+ )) ?? []);
850
+ return t.length > 0 ? t : this._findTitleRowsByClass();
851
+ }
852
+ _findTitleRowsByClass() {
853
+ const t = this._findTitleContainerBody(), e = t && "children" in t ? t.children() : [], r = e.findIndex((s) => !!s.querySelector(z));
854
+ if (r === -1)
855
+ return [];
856
+ const i = e[r + 1];
857
+ return i && this._isSpacerRow(i) ? [e[r], i] : [e[r]];
858
+ }
859
+ _isSpacerRow(t) {
860
+ return "children" in t && t.children().some((e) => "hasClass" in e && e.hasClass(kt));
861
+ }
862
+ _findTitleContainerBody() {
863
+ return (this.currentNode ? Pt(this.currentNode) : null) ?? void 0;
864
+ }
865
+ _readInnerHtml(t) {
866
+ return "getInnerHTML" in t && typeof t.getInnerHTML == "function" ? t.getInnerHTML().trim() : null;
867
+ }
868
+ _defaultTitleParagraph() {
869
+ return Ct.replace("{-{-TITLE-}-}", this.api.translate(St));
802
870
  }
803
871
  // ========================================================================
804
872
  // Utilities
@@ -811,7 +879,7 @@ class Wt extends nt {
811
879
  _findNthCustomKeyIndex(t, e) {
812
880
  let r = 0;
813
881
  for (let i = 0; i < t.length; i++)
814
- if (t[i].startsWith(I)) {
882
+ if (t[i].startsWith(v)) {
815
883
  if (r === e)
816
884
  return i;
817
885
  r++;
@@ -819,7 +887,7 @@ class Wt extends nt {
819
887
  return -1;
820
888
  }
821
889
  _getCurrentLayout() {
822
- return this.store.recommendationConfigs.orientation || Rt(this.currentNode);
890
+ return this.store.recommendationConfigs.orientation || Ht(this.currentNode);
823
891
  }
824
892
  /**
825
893
  * Extracts background color properties from existing card elements.
@@ -831,18 +899,18 @@ class Wt extends nt {
831
899
  var i;
832
900
  const e = t.querySelector(".product-card-segment");
833
901
  if (e && "getAttribute" in e) {
834
- const s = (e.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
835
- if (s) {
902
+ const o = (e.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
903
+ if (o) {
836
904
  const n = e.getAttribute("bgcolor") || "";
837
- return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
905
+ return { bgStyle: `background-color: ${o[1].trim()};`, bgAttr: n };
838
906
  }
839
907
  }
840
908
  const r = (i = this.currentNode) == null ? void 0 : i.querySelector(".product-card-wrapper");
841
909
  if (r && "getStyle" in r) {
842
- const o = r.getStyle("background-color");
843
- if (o && o !== "transparent") {
844
- const s = "getAttribute" in r && r.getAttribute("bgcolor") || "";
845
- return { bgStyle: `background-color: ${o};`, bgAttr: s };
910
+ const s = r.getStyle("background-color");
911
+ if (s && s !== "transparent") {
912
+ const o = "getAttribute" in r && r.getAttribute("bgcolor") || "";
913
+ return { bgStyle: `background-color: ${s};`, bgAttr: o };
846
914
  }
847
915
  }
848
916
  return { bgStyle: "", bgAttr: "" };
@@ -871,11 +939,11 @@ class Wt extends nt {
871
939
  * or when all available filters have already been added (no unused attributes left).
872
940
  */
873
941
  _updateAddButtonState() {
874
- const t = this._readCustomAttributesFromNode(), e = t.length >= b, r = new Set(t), i = this._getAddableFilters(), o = i.length > 0 && i.every((s) => r.has(y(s)));
942
+ const t = this._readCustomAttributesFromNode(), e = t.length >= f, r = new Set(t), i = this._getAddableFilters(), s = i.length > 0 && i.every((o) => r.has(T(o)));
875
943
  this.api.setUIEAttribute(
876
- X.ADD_ATTRIBUTE,
877
- N.BUTTON.disabled,
878
- e || o ? "true" : "false"
944
+ Z.ADD_ATTRIBUTE,
945
+ D.BUTTON.disabled,
946
+ e || s ? "true" : "false"
879
947
  );
880
948
  }
881
949
  /**
@@ -903,8 +971,8 @@ class Wt extends nt {
903
971
  */
904
972
  _getAddableFilters() {
905
973
  const t = /* @__PURE__ */ new Set();
906
- return Object.values(this.store.filterList).filter((e) => !(e.type === "defaultAttribute" && dt.has(e.attributeName))).filter((e) => {
907
- const r = y(e);
974
+ return Object.values(this.store.filterList).filter((e) => !(e.type === "defaultAttribute" && ht.has(e.attributeName))).filter((e) => {
975
+ const r = T(e);
908
976
  return t.has(r) ? !1 : (t.add(r), !0);
909
977
  });
910
978
  }
@@ -914,8 +982,8 @@ class Wt extends nt {
914
982
  * resolve to their own entry. Falls back to Title Case of the bare name.
915
983
  */
916
984
  _getDisplayNameForAttribute(t) {
917
- const e = Object.values(this.store.filterList).find((r) => y(r) === t);
918
- return e ? e.displayName : _t(D(t));
985
+ const e = Object.values(this.store.filterList).find((r) => T(r) === t);
986
+ return e ? e.displayName : It(O(t));
919
987
  }
920
988
  /**
921
989
  * Resolves the display content for a custom attribute cell.
@@ -923,29 +991,29 @@ class Wt extends nt {
923
991
  */
924
992
  _resolveAttributeContent(t, e, r) {
925
993
  var l;
926
- const o = this.store.recommendationProducts[r], s = D(t), n = $t(t) ? o == null ? void 0 : o[s] : (l = o == null ? void 0 : o.product_attributes) == null ? void 0 : l[s];
927
- return yt(n) ?? e;
994
+ const s = this.store.recommendationProducts[r], o = O(t), n = Lt(t) ? s == null ? void 0 : s[o] : (l = s == null ? void 0 : s.product_attributes) == null ? void 0 : l[o];
995
+ return $t(n) ?? e;
928
996
  }
929
- _getGridCellHtml(t, e, r, i = "", o = "", s = "") {
930
- const n = k(t), l = D(t), a = z(ht, [n], this.store.filterList), d = {
997
+ _getGridCellHtml(t, e, r, i = "", s = "", o = "") {
998
+ const n = U(t), l = O(t), a = X(gt, [n], this.store.filterList), d = {
931
999
  [l]: e,
932
1000
  product_attributes: { [l]: e }
933
1001
  };
934
1002
  let c = a[n](d);
935
- return c = c.replace("<td", `<td width="${r}%"`), s && (c = c.replace(
936
- `padding: ${pt}`,
937
- `padding: ${s}`
938
- )), i && (c = c.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${i}"`)), o && (c = c.replace(/border="0"/, `border="0" bgcolor="${o}"`)), c;
1003
+ return c = c.replace("<td", `<td width="${r}%"`), o && (c = c.replace(
1004
+ `padding: ${ft}`,
1005
+ `padding: ${o}`
1006
+ )), i && (c = c.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${i}"`)), s && (c = c.replace(/border="0"/, `border="0" bgcolor="${s}"`)), c;
939
1007
  }
940
1008
  _getListRowHtml(t, e, r) {
941
- const i = D(t), o = z(bt, [r], this.store.filterList), s = {
1009
+ const i = O(t), s = X(yt, [r], this.store.filterList), o = {
942
1010
  [i]: e,
943
1011
  product_attributes: { [i]: e }
944
- }, l = o[r](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
945
- return `<tr class="recommendation-attribute-row" ${E}="${r}" ${O}="1">${l}</tr>`;
1012
+ }, l = s[r](o).replace(/<tr>/, "").replace(/<\/tr>/, "");
1013
+ return `<tr class="recommendation-attribute-row" ${R}="${r}" ${w}="1">${l}</tr>`;
946
1014
  }
947
1015
  }
948
1016
  export {
949
- Et as COMPOSITION_CONTROL_BLOCK_ID,
950
- Wt as RecommendationCardCompositionControl
1017
+ Bt as COMPOSITION_CONTROL_BLOCK_ID,
1018
+ ee as RecommendationCardCompositionControl
951
1019
  };