@useinsider/guido 3.16.0-beta.9e5f533 → 3.16.0-beta.ca26c4e

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 (33) hide show
  1. package/dist/config/migrator/index.js +8 -9
  2. package/dist/config/migrator/itemsBlockMigrator.js +1 -1
  3. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  4. package/dist/config/migrator/recommendation/extractors.js +24 -29
  5. package/dist/config/migrator/recommendation/htmlBuilder.js +130 -116
  6. package/dist/config/migrator/recommendationMigrator.js +15 -18
  7. package/dist/enums/recommendation.js +17 -17
  8. package/dist/extensions/Blocks/Items/enums/productEnums.js +45 -45
  9. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  10. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  11. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +22 -23
  12. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +26 -29
  13. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +152 -203
  14. package/dist/extensions/Blocks/Recommendation/extension.js +29 -31
  15. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +4 -23
  16. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  17. package/dist/extensions/Blocks/Recommendation/templates/utils.js +107 -85
  18. package/dist/src/config/migrator/recommendation/extractors.d.ts +0 -8
  19. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +1 -2
  20. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +0 -7
  21. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
  22. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  23. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +0 -4
  24. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +0 -7
  25. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +0 -1
  26. package/dist/static/styles/customEditorStyle.css.js +1 -3
  27. package/package.json +1 -1
  28. package/dist/config/migrator/recommendationTitleMigrator.js +0 -112
  29. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +0 -44
  30. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +0 -33
  31. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +0 -1
  32. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +0 -86
  33. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +0 -13
@@ -1,34 +1,33 @@
1
- var nt = Object.defineProperty;
2
- var lt = (h, p, t) => p in h ? nt(h, p, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[p] = t;
3
- var $ = (h, p, t) => lt(h, typeof p != "symbol" ? p + "" : p, t);
4
- import { UIElementType as _, UEAttr as O, ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as at } from "../../../common-control.js";
6
- import { ATTR_PRODUCT_IMAGE as F, ATTR_PRODUCT_NAME as ct, ATTR_PRODUCT_PRICE as C, ATTR_PRODUCT_OLD_PRICE as L, ATTR_PRODUCT_OMNIBUS_PRICE as dt, ATTR_PRODUCT_OMNIBUS_DISCOUNT as ut, ATTR_PRODUCT_BUTTON as M, ATTR_RECOMMENDATION_TITLE as I, ATTR_DATA_CARD_COMPOSITION as K, ATTR_DATA_CUSTOM_ATTRIBUTES as W, ATTR_CUSTOM_PREFIX as N, SELECTOR_ATTRIBUTE_ROW as v, SELECTOR_TITLE_CELL as mt, ATTR_DATA_ATTRIBUTE_TYPE as E, BUILT_IN_DEFAULT_ATTRIBUTES as ht } from "../../constants/selectors.js";
7
- import { DEFAULT_COMPOSITION as z, DEFAULT_VISIBILITY as G } 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 Y } from "../../templates/utils.js";
14
- import { normalizeCompositionKeys as Nt, normalizeCustomAttrValues as vt, compositionKeyToProductAttr as k, resolveRowCompositionKey as Et, filterToProductAttrValue as T, findAttributeRow as Rt, rewriteLegacyRowKeyHtml as X, bareAttributeName as D, isDefaultProductAttr as Lt, productAttrToCompositionKey as U } from "../../utils/compositionKeys.js";
15
- import { getTableDisplayValue as Ot } from "../../utils/tagName.js";
16
- import { isPartnerManagedBlock as Dt, regenerateProductRowsWithStyles as Pt, getCurrentLayout as Ht } from "../main/utils.js";
17
- const wt = "ui-elements-recommendation-card-composition", q = ".product-card-wrapper > tbody", Bt = "table.container", J = ".product-info-cell > table > tbody", P = "data-visibility", Q = {
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 = {
18
17
  ADD_ATTRIBUTE: "addAttribute"
19
- }, f = 5, H = "reorderIcon_", kt = '<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: F, label: "Product Image" },
21
- { key: ct, label: "Product Name" },
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" },
22
21
  { key: C, label: "Product Price" },
23
- { key: L, label: "Product Original Price" },
24
- { key: dt, label: "Omnibus Price" },
25
- { key: ut, label: "Omnibus Discount" },
26
- { key: M, label: "Product Button" }
27
- ], R = { key: I, label: "Title" }, Ut = new Set(m.map((h) => h.key)), A = "customAttr_", w = "deleteAttr_";
28
- class te extends at {
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 {
29
28
  constructor() {
30
29
  super(...arguments);
31
- $(this, "store", pt());
30
+ $(this, "store", ut());
32
31
  $(this, "unsubscribeStore", null);
33
32
  $(this, "eventController", null);
34
33
  /**
@@ -38,7 +37,7 @@ class te extends at {
38
37
  $(this, "reorderInProgress", !1);
39
38
  }
40
39
  getId() {
41
- return wt;
40
+ return Et;
42
41
  }
43
42
  // ========================================================================
44
43
  // Lifecycle
@@ -49,11 +48,11 @@ class te extends at {
49
48
  ${this._GuToggle(`visibility_${d.key}`)}
50
49
  </div>
51
50
  `).join(""), e = Array.from(
52
- { length: f },
51
+ { length: b },
53
52
  (d, c) => `
54
- <div data-custom-select-key="${A}${c}" style="display: none;">
53
+ <div data-custom-select-key="${T}${c}" style="display: none;">
55
54
  ${this._GuSelect({
56
- name: `${A}${c}`,
55
+ name: `${T}${c}`,
57
56
  placeholder: this.api.translate("Select Attribute"),
58
57
  options: [],
59
58
  // A partner's attribute list runs long; search beats scrolling.
@@ -61,34 +60,34 @@ class te extends at {
61
60
  })}
62
61
  </div>
63
62
  `
64
- ).join(""), r = m.length + f, i = Array.from(
63
+ ).join(""), r = m.length + b, i = Array.from(
65
64
  { length: r },
66
65
  (d, c) => `
67
- <div data-reorder-icon-key="${H}${c}" style="display: none;">
68
- <${_.BUTTON}
66
+ <div data-reorder-icon-key="${L}${c}" style="display: none;">
67
+ <${g.BUTTON}
69
68
  class="drag-handle-btn flat-inline flat-white"
70
- ${O.BUTTON.name}="${H}${c}"
69
+ ${N.BUTTON.name}="${L}${c}"
71
70
  >
72
- <${_.ICON}
71
+ <${g.ICON}
73
72
  src="reorder"
74
73
  class="icon-button"
75
- ></${_.ICON}>
76
- </${_.BUTTON}>
74
+ ></${g.ICON}>
75
+ </${g.BUTTON}>
77
76
  </div>
78
77
  `
79
78
  ).join(""), o = Array.from(
80
- { length: f },
79
+ { length: b },
81
80
  (d, c) => `
82
- <div data-custom-delete-key="${w}${c}" style="display: none;">
83
- <${_.BUTTON}
81
+ <div data-custom-delete-key="${P}${c}" style="display: none;">
82
+ <${g.BUTTON}
84
83
  class="custom-attr-delete flat-inline flat-white"
85
- ${O.BUTTON.name}="${w}${c}"
84
+ ${N.BUTTON.name}="${P}${c}"
86
85
  >
87
- <${_.ICON}
86
+ <${g.ICON}
88
87
  src="delete"
89
88
  class="icon-button"
90
- ></${_.ICON}>
91
- </${_.BUTTON}>
89
+ ></${g.ICON}>
90
+ </${g.BUTTON}>
92
91
  </div>
93
92
  `
94
93
  ).join(""), s = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
@@ -121,19 +120,10 @@ class te extends at {
121
120
  ${i}
122
121
  </div>
123
122
 
124
- <div class="orderable-list">
125
- <div class="orderable-item title-item" data-key="${R.key}">
126
- <span class="item-label">${this.api.translate(R.label)}</span>
127
- <div class="item-action">
128
- ${this._GuToggle(`visibility_${R.key}`)}
129
- </div>
130
- </div>
131
- </div>
132
-
133
123
  <div class="orderable-list" data-composition-list></div>
134
124
 
135
125
  ${this._GuButton({
136
- name: Q.ADD_ATTRIBUTE,
126
+ name: X.ADD_ATTRIBUTE,
137
127
  label: this.api.translate("Add Attribute"),
138
128
  id: "guido__btn-add-attribute"
139
129
  })}
@@ -154,7 +144,7 @@ class te extends at {
154
144
  const t = (r = this.getContainer()) == null ? void 0 : r.querySelector("[data-card-composition-control]");
155
145
  if (!t)
156
146
  return;
157
- const e = Dt(this.currentNode);
147
+ const e = vt(this.currentNode);
158
148
  t.style.pointerEvents = e ? "none" : "", t.style.opacity = e ? "0.5" : "";
159
149
  }
160
150
  onTemplateNodeUpdated(t) {
@@ -171,13 +161,13 @@ class te extends at {
171
161
  this.api.updateValues(o), i && this._initializeCustomSelects(e), this._updateAddButtonState();
172
162
  }
173
163
  _registerValueChangeListeners() {
174
- [R, ...m].forEach((t) => {
164
+ m.forEach((t) => {
175
165
  this.api.onValueChanged(`visibility_${t.key}`, (e) => {
176
166
  this._applyVisibilityToBlock(t.key, e);
177
167
  });
178
168
  });
179
- for (let t = 0; t < f; t++) {
180
- const e = `${A}${t}`, r = t;
169
+ for (let t = 0; t < b; t++) {
170
+ const e = `${T}${t}`, r = t;
181
171
  this.api.onValueChanged(e, (i) => {
182
172
  this._onCustomAttributeChanged(r, i);
183
173
  });
@@ -188,24 +178,24 @@ class te extends at {
188
178
  // ========================================================================
189
179
  _readCompositionFromNode() {
190
180
  if (!this.currentNode || !("getAttribute" in this.currentNode))
191
- return [...z];
192
- const t = this.currentNode.getAttribute(K);
181
+ return [...K];
182
+ const t = this.currentNode.getAttribute(V);
193
183
  if (t)
194
184
  return this._normalizeComposition(t.split(",").filter(Boolean));
195
- const { composition: e } = g.getConfig(this.currentNode);
196
- return e != null && e.length ? this._normalizeComposition([...e]) : [...z];
185
+ const { composition: e } = _.getConfig(this.currentNode);
186
+ return e != null && e.length ? this._normalizeComposition([...e]) : [...K];
197
187
  }
198
188
  /** Upgrades legacy bare-name custom keys to the canonical form. (SD-147101) */
199
189
  _normalizeComposition(t) {
200
- return Nt(t, this.currentNode, this.store.filterList);
190
+ return Ct(t, this.currentNode, this.store.filterList);
201
191
  }
202
192
  _readCustomAttributesFromNode() {
203
193
  if (!this.currentNode || !("getAttribute" in this.currentNode))
204
194
  return [];
205
- const t = this.currentNode.getAttribute(W);
195
+ const t = this.currentNode.getAttribute(j);
206
196
  if (t)
207
197
  try {
208
- return vt(
198
+ return St(
209
199
  JSON.parse(t).map((e) => String(e)),
210
200
  this.currentNode,
211
201
  this.store.filterList
@@ -213,33 +203,26 @@ class te extends at {
213
203
  } catch {
214
204
  return [];
215
205
  }
216
- return this._readCompositionFromNode().filter((e) => e.startsWith(N)).map(k);
206
+ return this._readCompositionFromNode().filter((e) => e.startsWith(I)).map(w);
217
207
  }
218
208
  _readVisibilityFromRows() {
219
209
  if (!this.currentNode)
220
210
  return this._getDefaultVisibilities();
221
- const t = Array.from(this.currentNode.querySelectorAll(v)), e = this._extractVisibilityFromRows(t);
211
+ const t = Array.from(this.currentNode.querySelectorAll(R)), e = this._extractVisibilityFromRows(t);
222
212
  if (Object.keys(e).length > 0)
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(mt));
213
+ return this._mergeWithDefaults(e);
214
+ const r = _.getConfig(this.currentNode).visibility;
215
+ return this._mergeWithDefaults({ ...r });
233
216
  }
234
217
  _getDefaultVisibilities() {
235
- return { ...G };
218
+ return { ...W };
236
219
  }
237
220
  _extractVisibilityFromRows(t) {
238
221
  const e = {};
239
222
  return t.forEach((r) => {
240
223
  if (!("getAttribute" in r))
241
224
  return;
242
- const i = Et(r), o = r.getAttribute(P);
225
+ const i = At(r), o = r.getAttribute(O);
243
226
  i && o !== null && (e[i] = this._parseVisibilityValue(o));
244
227
  }), e;
245
228
  }
@@ -247,12 +230,12 @@ class te extends at {
247
230
  return t === "1" || t === "true";
248
231
  }
249
232
  _mergeWithDefaults(t) {
250
- return Object.entries(G).forEach(([e, r]) => {
233
+ return Object.entries(W).forEach(([e, r]) => {
251
234
  e in t || (t[e] = r);
252
235
  }), t;
253
236
  }
254
237
  _buildVisibilityValues(t) {
255
- return [R, ...m].reduce((e, r) => (e[`visibility_${r.key}`] = t[r.key] ?? !0, e), {});
238
+ return m.reduce((e, r) => (e[`visibility_${r.key}`] = t[r.key] ?? !0, e), {});
256
239
  }
257
240
  // ========================================================================
258
241
  // UI Rendering (Orderable List)
@@ -269,22 +252,22 @@ class te extends at {
269
252
  const i = r.querySelector("[data-composition-list]");
270
253
  if (!i)
271
254
  return !1;
272
- const o = !g.getConfig(this.currentNode).priceMovedToNextLine;
255
+ const o = !_.getConfig(this.currentNode).priceMovedToNextLine;
273
256
  if (!(i.dataset.inlinePrices !== String(o)) && this._tryReorderInPlace(i, t))
274
257
  return !1;
275
258
  i.dataset.inlinePrices = String(o);
276
- const n = new Set(e), l = At(t);
259
+ const n = new Set(e), l = ft(t);
277
260
  let a = 0, d = 0;
278
261
  const c = t.map((u) => {
279
- if (o && (u === C || u === L))
262
+ if (o && (u === C || u === v))
280
263
  return u === l.anchor ? this._createPriceGroupItemHtml(d++, l.originalFirst) : "";
281
- if (Ut.has(u)) {
282
- const b = m.find((S) => S.key === u);
283
- return this._createBuiltInItemHtml(b, d++);
264
+ if (Ot.has(u)) {
265
+ const f = m.find((S) => S.key === u);
266
+ return this._createBuiltInItemHtml(f, d++);
284
267
  }
285
- if (u.startsWith(N)) {
286
- const b = k(u);
287
- if (n.has(b))
268
+ if (u.startsWith(I)) {
269
+ const f = w(u);
270
+ if (n.has(f))
288
271
  return this._createCustomItemHtml(u, a++, d++);
289
272
  }
290
273
  return "";
@@ -305,7 +288,7 @@ class te extends at {
305
288
  if (i.length !== e.length)
306
289
  return !1;
307
290
  const o = [...i].sort().join(","), s = [...e].sort().join(",");
308
- if (o !== s || e.some((a) => a.startsWith(N)))
291
+ if (o !== s || e.some((a) => a.startsWith(I)))
309
292
  return !1;
310
293
  const n = /* @__PURE__ */ new Map();
311
294
  r.forEach((a) => {
@@ -343,11 +326,11 @@ class te extends at {
343
326
  */
344
327
  _createPriceGroupItemHtml(t, e) {
345
328
  var n, l;
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", o = (a, d) => `
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) => `
347
330
  <div class="price-suborderable-item" draggable="true" data-subkey="${a}">
348
- <span class="sub-drag-handle">${kt}</span>
331
+ <span class="sub-drag-handle">${Dt}</span>
349
332
  <span class="item-label">${this.api.translate(d)}</span>
350
- </div>`, s = e ? o(L, i) + o(C, r) : o(C, r) + o(L, i);
333
+ </div>`, s = e ? o(v, i) + o(C, r) : o(C, r) + o(v, i);
351
334
  return `
352
335
  <div class="orderable-item price-group-item" draggable="true"
353
336
  data-key="${C}" data-group="prices">
@@ -394,13 +377,13 @@ class te extends at {
394
377
  const i = /* @__PURE__ */ new Map();
395
378
  r.forEach((s) => i.set(s.attributeName, (i.get(s.attributeName) ?? 0) + 1));
396
379
  const o = new Set(e);
397
- return o.delete(t), r.filter((s) => !o.has(T(s))).map((s) => ({
380
+ return o.delete(t), r.filter((s) => !o.has(y(s))).map((s) => ({
398
381
  text: this._toOptionLabel(
399
382
  s.displayName,
400
383
  s.type === "defaultAttribute",
401
384
  (i.get(s.attributeName) ?? 0) > 1
402
385
  ),
403
- value: T(s)
386
+ value: y(s)
404
387
  }));
405
388
  }
406
389
  /**
@@ -411,8 +394,8 @@ class te extends at {
411
394
  _initializeCustomSelects(t) {
412
395
  t.length !== 0 && setTimeout(() => {
413
396
  t.forEach((e, r) => {
414
- const i = `${A}${r}`, o = this._getSelectOptions(e, t);
415
- this.api.setUIEAttribute(i, O.SELECTPICKER.items, o), this.api.updateValues({ [i]: e });
397
+ const i = `${T}${r}`, o = this._getSelectOptions(e, t);
398
+ this.api.setUIEAttribute(i, N.SELECTPICKER.items, o), this.api.updateValues({ [i]: e });
416
399
  });
417
400
  }, 0);
418
401
  }
@@ -435,7 +418,7 @@ class te extends at {
435
418
  */
436
419
  _moveSelectsIntoItems(t, e) {
437
420
  for (let r = 0; r < e; r++) {
438
- const i = `${A}${r}`, o = t.querySelector(`[data-custom-select-key="${i}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
421
+ const i = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${i}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
439
422
  if (o && s) {
440
423
  const n = o.querySelector("ue-select");
441
424
  n && s.appendChild(n);
@@ -462,8 +445,8 @@ class te extends at {
462
445
  * Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
463
446
  */
464
447
  _rescueSelectsToStore(t) {
465
- for (let e = 0; e < f; e++) {
466
- const r = `${A}${e}`, i = t.querySelector(`[data-custom-select-key="${r}"]`), o = t.querySelector(`[data-custom-select-slot="${e}"]`);
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}"]`);
467
450
  if (o) {
468
451
  const s = o.querySelector("ue-select");
469
452
  s && i && i.appendChild(s);
@@ -476,7 +459,7 @@ class te extends at {
476
459
  */
477
460
  _moveDeleteButtonsIntoItems(t, e) {
478
461
  for (let r = 0; r < e; r++) {
479
- const i = `${w}${r}`, o = t.querySelector(`[data-custom-delete-key="${i}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
462
+ const i = `${P}${r}`, o = t.querySelector(`[data-custom-delete-key="${i}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
480
463
  if (o && s) {
481
464
  const n = o.querySelector("ue-button");
482
465
  n && s.appendChild(n);
@@ -488,8 +471,8 @@ class te extends at {
488
471
  * Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
489
472
  */
490
473
  _rescueDeleteButtonsToStore(t) {
491
- for (let e = 0; e < f; e++) {
492
- const r = `${w}${e}`, i = t.querySelector(`[data-custom-delete-key="${r}"]`), o = t.querySelector(`[data-custom-delete-slot="${e}"]`);
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}"]`);
493
476
  if (o) {
494
477
  const s = o.querySelector("ue-button");
495
478
  s && i && i.appendChild(s);
@@ -502,7 +485,7 @@ class te extends at {
502
485
  */
503
486
  _moveReorderIconsIntoItems(t, e) {
504
487
  for (let r = 0; r < e; r++) {
505
- const i = `${H}${r}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
488
+ const i = `${L}${r}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
506
489
  if (o && s) {
507
490
  const n = o.querySelector("ue-button");
508
491
  n && s.appendChild(n);
@@ -514,9 +497,9 @@ class te extends at {
514
497
  * Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
515
498
  */
516
499
  _rescueReorderIconsToStore(t) {
517
- const e = m.length + f;
500
+ const e = m.length + b;
518
501
  for (let r = 0; r < e; r++) {
519
- const i = `${H}${r}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
502
+ const i = `${L}${r}`, o = t.querySelector(`[data-reorder-icon-key="${i}"]`), s = t.querySelector(`[data-reorder-icon-slot="${r}"]`);
520
503
  if (s) {
521
504
  const n = s.querySelector("ue-button");
522
505
  n && o && o.appendChild(n);
@@ -533,8 +516,8 @@ class te extends at {
533
516
  return;
534
517
  const r = e.querySelector("[data-composition-list]"), i = e.querySelector("#guido__btn-add-attribute");
535
518
  r && (this._setupDragAndDrop(r, t), this._setupDeleteHandler(r, t)), i && i.addEventListener("click", () => {
536
- const o = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !o.has(T(n)));
537
- s && this._onAddAttribute(T(s), s.displayName);
519
+ const o = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !o.has(y(n)));
520
+ s && this._onAddAttribute(y(s), s.displayName);
538
521
  }, { signal: t });
539
522
  }
540
523
  /**
@@ -615,7 +598,7 @@ class te extends at {
615
598
  // Actions (Add, Delete, Reorder)
616
599
  // ========================================================================
617
600
  _onAddAttribute(t, e) {
618
- const r = U(t), i = this._readCompositionFromNode();
601
+ const r = k(t), i = this._readCompositionFromNode();
619
602
  i.push(r);
620
603
  const o = [...this._readCustomAttributesFromNode(), t];
621
604
  this._updateBothAttributes(i, o), this._injectCustomAttributeHtml(t, e, r, i), this._renderOrderableItems(i, o), this._initializeCustomSelects(o), this._updateAddButtonState();
@@ -639,18 +622,18 @@ class te extends at {
639
622
  const r = this._readCustomAttributesFromNode(), i = r[t];
640
623
  if (i === void 0 || i === e)
641
624
  return;
642
- const o = U(e), s = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(s, t);
625
+ const o = k(e), s = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(s, t);
643
626
  n !== -1 && (s[n] = o), r[t] = e;
644
627
  const l = this._getDisplayNameForAttribute(e);
645
628
  this._updateBothAttributes(s, r), this._injectCustomAttributeHtml(e, l, o, s), this._renderOrderableItems(s, r), this._initializeCustomSelects(r);
646
629
  }
647
630
  _onReorder(t) {
648
- const e = t.filter((r) => r.startsWith(N)).map(k);
631
+ const e = t.filter((r) => r.startsWith(I)).map(w);
649
632
  this.reorderInProgress = !0;
650
633
  try {
651
634
  this._updateBothAttributes(t, e);
652
- const r = !g.getConfig(this.currentNode).priceMovedToNextLine;
653
- this._getCurrentLayout() === "grid" && !r ? this._reorderProductAttributes(t) : this.currentNode && Pt({
635
+ const r = !_.getConfig(this.currentNode).priceMovedToNextLine;
636
+ this._getCurrentLayout() === "grid" && !r ? this._reorderProductAttributes(t) : this.currentNode && Nt({
654
637
  currentNode: this.currentNode,
655
638
  documentModifier: this.api.getDocumentModifier()
656
639
  });
@@ -668,13 +651,13 @@ class te extends at {
668
651
  * DOM converge on the next composition change without writing on open.
669
652
  */
670
653
  _getExistingRowHtml(t, e) {
671
- const r = Rt(t, e);
654
+ const r = Tt(t, e);
672
655
  if (r && "getOuterHTML" in r)
673
- return X(r.getOuterHTML(), e);
656
+ return G(r.getOuterHTML(), e);
674
657
  const i = t.querySelector(
675
- `${v}[${E}="${e}"]`
658
+ `${R}[${E}="${e}"]`
676
659
  );
677
- return i && "getOuterHTML" in i ? X(i.getOuterHTML(), e) : "";
660
+ return i && "getOuterHTML" in i ? G(i.getOuterHTML(), e) : "";
678
661
  }
679
662
  _injectCustomAttributeHtml(t, e, r, i) {
680
663
  if (!this.currentNode)
@@ -682,45 +665,45 @@ class te extends at {
682
665
  this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, e, r, i) : this._injectListAttributeRow(t, e, r, i);
683
666
  }
684
667
  _injectGridAttributeRow(t, e, r, i) {
685
- const o = this.currentNode.querySelectorAll(q);
668
+ const o = this.currentNode.querySelectorAll(U);
686
669
  if (!(o != null && o.length))
687
670
  return;
688
- const s = g.getConfig(this.currentNode), l = `0 ${Math.floor(s.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), d = this.store.recommendationProducts.length;
671
+ const s = _.getConfig(this.currentNode), l = `0 ${Math.floor(s.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), d = this.store.recommendationProducts.length;
689
672
  let c = 0;
690
673
  o.forEach((u) => {
691
- var V;
692
- const b = u.querySelector(v), S = ((V = b == null ? void 0 : b.querySelectorAll(`.${_t}`)) == null ? void 0 : V.length) || 1, x = (100 / S).toFixed(2), { bgStyle: Z, bgAttr: tt } = this._extractSegmentBgFromCard(u), B = d > 0 ? Math.min(S, d - c) : S, et = i.map((j) => {
693
- if (j === r) {
694
- const rt = Array.from(
695
- { length: B },
696
- (qt, ot) => {
697
- const st = this._resolveAttributeContent(
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(
698
681
  t,
699
682
  e,
700
- c + ot
683
+ c + rt
701
684
  );
702
685
  return this._getGridCellHtml(
703
686
  t,
704
- st,
687
+ it,
705
688
  x,
706
- Z,
707
- tt,
689
+ J,
690
+ Q,
708
691
  l
709
692
  );
710
693
  }
711
- ).join(""), it = bt(x, l).repeat(S - B);
712
- return `<tr class="recommendation-attribute-row" ${E}="${r}" ${P}="1">${rt}${it}</tr>`;
694
+ ).join(""), et = gt(x, l).repeat(S - H);
695
+ return `<tr class="recommendation-attribute-row" ${E}="${r}" ${O}="1">${tt}${et}</tr>`;
713
696
  }
714
- return this._getExistingRowHtml(u, j);
697
+ return this._getExistingRowHtml(u, M);
715
698
  }).join("");
716
- c += B, d > 0 && c >= d && (c = 0), a.modifyHtml(u).setInnerHtml(et);
717
- }), a.apply(new y(`${this.api.translate("Add custom attribute")}: ${e}`));
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}`));
718
701
  }
719
702
  _injectListAttributeRow(t, e, r, i) {
720
- const o = this.currentNode.querySelectorAll(J);
703
+ const o = this.currentNode.querySelectorAll(Y);
721
704
  if (!(o != null && o.length))
722
705
  return;
723
- const s = i.filter((l) => l !== F && l !== M), n = this.api.getDocumentModifier();
706
+ const s = i.filter((l) => l !== B && l !== q), n = this.api.getDocumentModifier();
724
707
  o.forEach((l, a) => {
725
708
  const d = s.map((c) => {
726
709
  if (c === r) {
@@ -730,7 +713,7 @@ class te extends at {
730
713
  return this._getExistingRowHtml(l, c);
731
714
  }).join("");
732
715
  n.modifyHtml(l).setInnerHtml(d);
733
- }), n.apply(new y(`${this.api.translate("Add custom attribute")}: ${e}`));
716
+ }), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${e}`));
734
717
  }
735
718
  /**
736
719
  * Removes a custom attribute by rebuilding product card content without it.
@@ -741,19 +724,19 @@ class te extends at {
741
724
  return;
742
725
  const e = this._getCurrentLayout(), r = this.api.getDocumentModifier();
743
726
  if (e === "grid") {
744
- const i = this.currentNode.querySelectorAll(q);
727
+ const i = this.currentNode.querySelectorAll(U);
745
728
  i == null || i.forEach((o) => {
746
729
  const s = this._buildCompositionHtml(o, t);
747
730
  r.modifyHtml(o).setInnerHtml(s);
748
731
  });
749
732
  } else {
750
- const i = t.filter((s) => s !== F && s !== M), o = this.currentNode.querySelectorAll(J);
733
+ const i = t.filter((s) => s !== B && s !== q), o = this.currentNode.querySelectorAll(Y);
751
734
  o == null || o.forEach((s) => {
752
735
  const n = this._buildCompositionHtml(s, i);
753
736
  r.modifyHtml(s).setInnerHtml(n);
754
737
  });
755
738
  }
756
- r.apply(new y(this.api.translate("Remove custom attribute")));
739
+ r.apply(new A(this.api.translate("Remove custom attribute")));
757
740
  }
758
741
  // ========================================================================
759
742
  // DOM Mutation (Block Root Attributes, Reorder)
@@ -769,10 +752,10 @@ class te extends at {
769
752
  if (!this.currentNode)
770
753
  return;
771
754
  const r = {
772
- ...g.getConfig(this.currentNode),
755
+ ..._.getConfig(this.currentNode),
773
756
  composition: t
774
757
  };
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")));
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")));
776
759
  }
777
760
  /**
778
761
  * Reorders attribute rows within each product card based on composition order.
@@ -781,14 +764,14 @@ class te extends at {
781
764
  _reorderProductAttributes(t) {
782
765
  if (!this.currentNode)
783
766
  return;
784
- const e = this.currentNode.querySelectorAll(q);
767
+ const e = this.currentNode.querySelectorAll(U);
785
768
  if (!(e != null && e.length))
786
769
  return;
787
770
  const r = this.api.getDocumentModifier();
788
771
  e.forEach((i) => {
789
772
  const o = this._buildCompositionHtml(i, t);
790
773
  r.modifyHtml(i).setInnerHtml(o);
791
- }), r.apply(new y(this.api.translate("Reorder product attributes")));
774
+ }), r.apply(new A(this.api.translate("Reorder product attributes")));
792
775
  }
793
776
  /**
794
777
  * Builds HTML string with attributes ordered according to composition.
@@ -803,53 +786,19 @@ class te extends at {
803
786
  _applyVisibilityToBlock(t, e) {
804
787
  if (!this.currentNode)
805
788
  return;
806
- if (t === I) {
807
- this._applyTitleVisibilityToBlock(e);
808
- return;
809
- }
810
- const r = this.currentNode.querySelectorAll(`${v}[${E}="${t}"]`);
789
+ const r = this.currentNode.querySelectorAll(`${R}[${E}="${t}"]`);
811
790
  if (!(r != null && r.length))
812
791
  return;
813
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();
814
793
  r.forEach((a) => {
815
- const d = Ot(a), c = e ? d : "none";
816
- n.modifyHtml(a).setStyle("display", c).setAttribute(P, i);
794
+ const d = It(a), c = e ? d : "none";
795
+ n.modifyHtml(a).setStyle("display", c).setAttribute(O, i);
817
796
  });
818
797
  const l = {
819
- ...g.getConfig(this.currentNode),
798
+ ..._.getConfig(this.currentNode),
820
799
  visibility: { ...this._readVisibilityFromRows(), [t]: e }
821
800
  };
822
- n.modifyHtml(this.currentNode).setNodeConfig(l), n.apply(new y(s));
823
- }
824
- _applyTitleVisibilityToBlock(t) {
825
- const e = this._findTitleRows(), r = this._findTitleContainerBody(), i = t ? this._hasTitle() : e.length === 0;
826
- if (!this.currentNode || i || t && !r)
827
- return;
828
- const o = g.getConfig(this.currentNode), s = this.api.getDocumentModifier();
829
- t && r ? s.modifyHtml(r).setInnerHtml(Tt(this._defaultTitleParagraph(), !0, o.rowSpacing) + this._readInnerHtml(r)) : e.forEach((l) => s.modifyHtml(l).delete()), s.modifyHtml(this.currentNode).setNodeConfig({
830
- ...o,
831
- visibility: { ...this._readVisibilityFromRows(), [I]: t }
832
- });
833
- const n = t ? this.api.translate("visible") : this.api.translate("hidden");
834
- s.apply(new y(
835
- `${this.api.translate("Set visibility")}: ${I} → ${n}`
836
- ));
837
- }
838
- _findTitleRows() {
839
- var t;
840
- return Array.from(((t = this.currentNode) == null ? void 0 : t.querySelectorAll(
841
- `${v}[${E}="${I}"]`
842
- )) ?? []);
843
- }
844
- _findTitleContainerBody() {
845
- var t, e;
846
- return (e = (t = this.currentNode) == null ? void 0 : t.querySelector(Bt)) == null ? void 0 : e.querySelector("tbody");
847
- }
848
- _readInnerHtml(t) {
849
- return t && "getInnerHTML" in t && typeof t.getInnerHTML == "function" ? t.getInnerHTML().trim() : "";
850
- }
851
- _defaultTitleParagraph() {
852
- return Ct.replace("{-{-TITLE-}-}", this.api.translate(St));
801
+ n.modifyHtml(this.currentNode).setNodeConfig(l), n.apply(new A(s));
853
802
  }
854
803
  // ========================================================================
855
804
  // Utilities
@@ -862,7 +811,7 @@ class te extends at {
862
811
  _findNthCustomKeyIndex(t, e) {
863
812
  let r = 0;
864
813
  for (let i = 0; i < t.length; i++)
865
- if (t[i].startsWith(N)) {
814
+ if (t[i].startsWith(I)) {
866
815
  if (r === e)
867
816
  return i;
868
817
  r++;
@@ -870,7 +819,7 @@ class te extends at {
870
819
  return -1;
871
820
  }
872
821
  _getCurrentLayout() {
873
- return this.store.recommendationConfigs.orientation || Ht(this.currentNode);
822
+ return this.store.recommendationConfigs.orientation || Rt(this.currentNode);
874
823
  }
875
824
  /**
876
825
  * Extracts background color properties from existing card elements.
@@ -922,10 +871,10 @@ class te extends at {
922
871
  * or when all available filters have already been added (no unused attributes left).
923
872
  */
924
873
  _updateAddButtonState() {
925
- const t = this._readCustomAttributesFromNode(), e = t.length >= f, r = new Set(t), i = this._getAddableFilters(), o = i.length > 0 && i.every((s) => r.has(T(s)));
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)));
926
875
  this.api.setUIEAttribute(
927
- Q.ADD_ATTRIBUTE,
928
- O.BUTTON.disabled,
876
+ X.ADD_ATTRIBUTE,
877
+ N.BUTTON.disabled,
929
878
  e || o ? "true" : "false"
930
879
  );
931
880
  }
@@ -954,8 +903,8 @@ class te extends at {
954
903
  */
955
904
  _getAddableFilters() {
956
905
  const t = /* @__PURE__ */ new Set();
957
- return Object.values(this.store.filterList).filter((e) => !(e.type === "defaultAttribute" && ht.has(e.attributeName))).filter((e) => {
958
- const r = T(e);
906
+ return Object.values(this.store.filterList).filter((e) => !(e.type === "defaultAttribute" && dt.has(e.attributeName))).filter((e) => {
907
+ const r = y(e);
959
908
  return t.has(r) ? !1 : (t.add(r), !0);
960
909
  });
961
910
  }
@@ -965,8 +914,8 @@ class te extends at {
965
914
  * resolve to their own entry. Falls back to Title Case of the bare name.
966
915
  */
967
916
  _getDisplayNameForAttribute(t) {
968
- const e = Object.values(this.store.filterList).find((r) => T(r) === t);
969
- return e ? e.displayName : It(D(t));
917
+ const e = Object.values(this.store.filterList).find((r) => y(r) === t);
918
+ return e ? e.displayName : _t(D(t));
970
919
  }
971
920
  /**
972
921
  * Resolves the display content for a custom attribute cell.
@@ -974,29 +923,29 @@ class te extends at {
974
923
  */
975
924
  _resolveAttributeContent(t, e, r) {
976
925
  var l;
977
- const o = this.store.recommendationProducts[r], s = D(t), n = Lt(t) ? o == null ? void 0 : o[s] : (l = o == null ? void 0 : o.product_attributes) == null ? void 0 : l[s];
978
- return $t(n) ?? e;
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;
979
928
  }
980
929
  _getGridCellHtml(t, e, r, i = "", o = "", s = "") {
981
- const n = U(t), l = D(t), a = Y(gt, [n], this.store.filterList), d = {
930
+ const n = k(t), l = D(t), a = z(ht, [n], this.store.filterList), d = {
982
931
  [l]: e,
983
932
  product_attributes: { [l]: e }
984
933
  };
985
934
  let c = a[n](d);
986
935
  return c = c.replace("<td", `<td width="${r}%"`), s && (c = c.replace(
987
- `padding: ${ft}`,
936
+ `padding: ${pt}`,
988
937
  `padding: ${s}`
989
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;
990
939
  }
991
940
  _getListRowHtml(t, e, r) {
992
- const i = D(t), o = Y(yt, [r], this.store.filterList), s = {
941
+ const i = D(t), o = z(bt, [r], this.store.filterList), s = {
993
942
  [i]: e,
994
943
  product_attributes: { [i]: e }
995
944
  }, l = o[r](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
996
- return `<tr class="recommendation-attribute-row" ${E}="${r}" ${P}="1">${l}</tr>`;
945
+ return `<tr class="recommendation-attribute-row" ${E}="${r}" ${O}="1">${l}</tr>`;
997
946
  }
998
947
  }
999
948
  export {
1000
- wt as COMPOSITION_CONTROL_BLOCK_ID,
1001
- te as RecommendationCardCompositionControl
949
+ Et as COMPOSITION_CONTROL_BLOCK_ID,
950
+ Wt as RecommendationCardCompositionControl
1002
951
  };