@searchspring/snap-controller 0.73.7 → 0.75.0

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 (25) hide show
  1. package/dist/cjs/Autocomplete/AutocompleteController.d.ts +0 -1
  2. package/dist/cjs/Autocomplete/AutocompleteController.d.ts.map +1 -1
  3. package/dist/cjs/Autocomplete/AutocompleteController.js +124 -68
  4. package/dist/cjs/Finder/FinderController.d.ts.map +1 -1
  5. package/dist/cjs/Finder/FinderController.js +3 -0
  6. package/dist/cjs/Recommendation/RecommendationController.d.ts.map +1 -1
  7. package/dist/cjs/Recommendation/RecommendationController.js +84 -58
  8. package/dist/cjs/Search/SearchController.d.ts.map +1 -1
  9. package/dist/cjs/Search/SearchController.js +142 -66
  10. package/dist/cjs/utils/isClickWithinProductLink.d.ts +1 -1
  11. package/dist/cjs/utils/isClickWithinProductLink.d.ts.map +1 -1
  12. package/dist/cjs/utils/isClickWithinProductLink.js +14 -12
  13. package/dist/esm/Autocomplete/AutocompleteController.d.ts +0 -1
  14. package/dist/esm/Autocomplete/AutocompleteController.d.ts.map +1 -1
  15. package/dist/esm/Autocomplete/AutocompleteController.js +101 -28
  16. package/dist/esm/Finder/FinderController.d.ts.map +1 -1
  17. package/dist/esm/Finder/FinderController.js +3 -0
  18. package/dist/esm/Recommendation/RecommendationController.d.ts.map +1 -1
  19. package/dist/esm/Recommendation/RecommendationController.js +64 -22
  20. package/dist/esm/Search/SearchController.d.ts.map +1 -1
  21. package/dist/esm/Search/SearchController.js +106 -22
  22. package/dist/esm/utils/isClickWithinProductLink.d.ts +1 -1
  23. package/dist/esm/utils/isClickWithinProductLink.d.ts.map +1 -1
  24. package/dist/esm/utils/isClickWithinProductLink.js +13 -12
  25. package/package.json +10 -10
@@ -73,6 +73,9 @@ var types_1 = require("../types");
73
73
  var isClickWithinProductLink_1 = require("../utils/isClickWithinProductLink");
74
74
  var defaultConfig = {
75
75
  id: 'recommend',
76
+ beacon: {
77
+ enabled: true,
78
+ },
76
79
  tag: '',
77
80
  batched: true,
78
81
  realtime: false,
@@ -89,29 +92,46 @@ var RecommendationController = /** @class */ (function (_super) {
89
92
  _this.track = {
90
93
  product: {
91
94
  clickThrough: function (e, result) {
92
- var _a, _b, _c, _d;
95
+ var _a, _b, _c, _d, _e, _f;
96
+ if (!result) {
97
+ _this.log.warn('No result provided to track.product.clickThrough');
98
+ return;
99
+ }
93
100
  var responseId = result.responseId;
101
+ if (!_this.events[responseId]) {
102
+ _this.log.warn('No responseId found in controller, ensure correct controller is used');
103
+ return;
104
+ }
94
105
  if ((_b = (_a = _this.events[responseId]) === null || _a === void 0 ? void 0 : _a.product[result.id]) === null || _b === void 0 ? void 0 : _b.productClickThrough)
95
106
  return;
96
- var beaconResult = {
97
- type: result.type,
98
- uid: result.id,
99
- parentId: result.id,
100
- sku: (_c = result.mappings.core) === null || _c === void 0 ? void 0 : _c.sku,
101
- };
107
+ var type = (['product', 'banner'].includes(result.type) ? result.type : 'product');
108
+ var beaconResult = __assign({ type: type, uid: result.id ? '' + result.id : '' }, (type === 'product'
109
+ ? {
110
+ parentId: result.id ? '' + result.id : '',
111
+ sku: ((_c = result.mappings.core) === null || _c === void 0 ? void 0 : _c.sku) ? '' + ((_d = result.mappings.core) === null || _d === void 0 ? void 0 : _d.sku) : undefined,
112
+ }
113
+ : {}));
102
114
  var data = {
103
115
  tag: _this.store.profile.tag,
104
116
  responseId: responseId,
105
117
  results: [beaconResult],
106
118
  };
107
119
  _this.eventManager.fire('track.product.clickThrough', { controller: _this, event: e, product: result, trackEvent: data });
108
- _this.tracker.events.recommendations.clickThrough({ data: data, siteId: (_d = _this.config.globals) === null || _d === void 0 ? void 0 : _d.siteId });
120
+ ((_e = _this.config.beacon) === null || _e === void 0 ? void 0 : _e.enabled) && _this.tracker.events.recommendations.clickThrough({ data: data, siteId: (_f = _this.config.globals) === null || _f === void 0 ? void 0 : _f.siteId });
109
121
  _this.events[responseId].product[result.id] = _this.events[responseId].product[result.id] || {};
110
122
  _this.events[responseId].product[result.id].productClickThrough = true;
111
123
  },
112
124
  click: function (e, result) {
113
125
  var _a, _b, _c, _d, _e;
126
+ if (!result) {
127
+ _this.log.warn('No result provided to track.product.click');
128
+ return;
129
+ }
114
130
  var responseId = result.responseId;
131
+ if (!_this.events[responseId]) {
132
+ _this.log.warn('No responseId found in controller, ensure correct controller is used');
133
+ return;
134
+ }
115
135
  if (result.type === 'banner') {
116
136
  if ((_b = (_a = _this.events[responseId]) === null || _a === void 0 ? void 0 : _a.product[result.id]) === null || _b === void 0 ? void 0 : _b.inlineBannerClickThrough) {
117
137
  return;
@@ -136,17 +156,26 @@ var RecommendationController = /** @class */ (function (_super) {
136
156
  }
137
157
  },
138
158
  impression: function (result) {
139
- var _a, _b, _c, _d;
159
+ var _a, _b, _c, _d, _e, _f;
160
+ if (!result) {
161
+ _this.log.warn('No result provided to track.product.impression');
162
+ return;
163
+ }
140
164
  var responseId = result.responseId;
141
- if ((_b = (_a = _this.events[responseId]) === null || _a === void 0 ? void 0 : _a.product[result.id]) === null || _b === void 0 ? void 0 : _b.impression) {
165
+ if (!_this.events[responseId]) {
166
+ _this.log.warn('No responseId found in controller, ensure correct controller is used');
142
167
  return;
143
168
  }
144
- var item = {
145
- type: result.type,
146
- uid: result.id,
147
- parentId: result.id,
148
- sku: (_c = result.mappings.core) === null || _c === void 0 ? void 0 : _c.sku,
149
- };
169
+ else if ((_b = (_a = _this.events[responseId]) === null || _a === void 0 ? void 0 : _a.product[result.id]) === null || _b === void 0 ? void 0 : _b.impression) {
170
+ return;
171
+ }
172
+ var type = (['product', 'banner'].includes(result.type) ? result.type : 'product');
173
+ var item = __assign({ type: type, uid: result.id ? '' + result.id : '' }, (type === 'product'
174
+ ? {
175
+ parentId: result.id ? '' + result.id : '',
176
+ sku: ((_c = result.mappings.core) === null || _c === void 0 ? void 0 : _c.sku) ? '' + ((_d = result.mappings.core) === null || _d === void 0 ? void 0 : _d.sku) : undefined,
177
+ }
178
+ : {}));
150
179
  var data = {
151
180
  tag: _this.store.profile.tag,
152
181
  responseId: responseId,
@@ -154,13 +183,21 @@ var RecommendationController = /** @class */ (function (_super) {
154
183
  banners: [],
155
184
  };
156
185
  _this.eventManager.fire('track.product.impression', { controller: _this, product: result, trackEvent: data });
157
- _this.tracker.events.recommendations.impression({ data: data, siteId: (_d = _this.config.globals) === null || _d === void 0 ? void 0 : _d.siteId });
186
+ ((_e = _this.config.beacon) === null || _e === void 0 ? void 0 : _e.enabled) && _this.tracker.events.recommendations.impression({ data: data, siteId: (_f = _this.config.globals) === null || _f === void 0 ? void 0 : _f.siteId });
158
187
  _this.events[responseId].product[result.id] = _this.events[responseId].product[result.id] || {};
159
188
  _this.events[responseId].product[result.id].impression = true;
160
189
  },
161
190
  addToCart: function (result) {
162
- var _a, _b, _c;
191
+ var _a, _b, _c, _d;
192
+ if (!result) {
193
+ _this.log.warn('No result provided to track.product.addToCart');
194
+ return;
195
+ }
163
196
  var responseId = result.responseId;
197
+ if (!_this.events[responseId]) {
198
+ _this.log.warn('No responseId found in controller, ensure correct controller is used');
199
+ return;
200
+ }
164
201
  var product = {
165
202
  parentId: result.id,
166
203
  uid: result.id,
@@ -174,36 +211,37 @@ var RecommendationController = /** @class */ (function (_super) {
174
211
  results: [product],
175
212
  };
176
213
  _this.eventManager.fire('track.product.addToCart', { controller: _this, product: result, trackEvent: data });
177
- _this.tracker.events.recommendations.addToCart({ data: data, siteId: (_c = _this.config.globals) === null || _c === void 0 ? void 0 : _c.siteId });
214
+ ((_c = _this.config.beacon) === null || _c === void 0 ? void 0 : _c.enabled) && _this.tracker.events.recommendations.addToCart({ data: data, siteId: (_d = _this.config.globals) === null || _d === void 0 ? void 0 : _d.siteId });
178
215
  },
179
216
  },
180
217
  };
181
218
  _this.search = function () { return __awaiter(_this, void 0, void 0, function () {
182
- var params, err_1, searchProfile, response, responseId, afterSearchProfile, err_2, afterStoreProfile, err_3, err_4;
183
- return __generator(this, function (_a) {
184
- switch (_a.label) {
219
+ var params, err_1, searchProfile, response, responseId, afterSearchProfile, err_2, data, afterStoreProfile, err_3, err_4;
220
+ var _a, _b;
221
+ return __generator(this, function (_c) {
222
+ switch (_c.label) {
185
223
  case 0:
186
- _a.trys.push([0, 16, 17, 18]);
224
+ _c.trys.push([0, 16, 17, 18]);
187
225
  if (!!this.initialized) return [3 /*break*/, 2];
188
226
  return [4 /*yield*/, this.init()];
189
227
  case 1:
190
- _a.sent();
191
- _a.label = 2;
228
+ _c.sent();
229
+ _c.label = 2;
192
230
  case 2:
193
231
  params = this.params;
194
232
  this.store.loading = true;
195
- _a.label = 3;
233
+ _c.label = 3;
196
234
  case 3:
197
- _a.trys.push([3, 5, , 6]);
235
+ _c.trys.push([3, 5, , 6]);
198
236
  return [4 /*yield*/, this.eventManager.fire('beforeSearch', {
199
237
  controller: this,
200
238
  request: params,
201
239
  })];
202
240
  case 4:
203
- _a.sent();
241
+ _c.sent();
204
242
  return [3 /*break*/, 6];
205
243
  case 5:
206
- err_1 = _a.sent();
244
+ err_1 = _c.sent();
207
245
  if ((err_1 === null || err_1 === void 0 ? void 0 : err_1.message) == 'cancelled') {
208
246
  this.log.warn("'beforeSearch' middleware cancelled");
209
247
  return [2 /*return*/];
@@ -217,25 +255,25 @@ var RecommendationController = /** @class */ (function (_super) {
217
255
  searchProfile = this.profiler.create({ type: 'event', name: 'search', context: params }).start();
218
256
  return [4 /*yield*/, this.client.recommend(params)];
219
257
  case 7:
220
- response = _a.sent();
258
+ response = _c.sent();
221
259
  searchProfile.stop();
222
260
  this.log.profile(searchProfile);
223
261
  responseId = response.responseId;
224
262
  this.events[responseId] = this.events[responseId] || { product: {} };
225
263
  afterSearchProfile = this.profiler.create({ type: 'event', name: 'afterSearch', context: params }).start();
226
- _a.label = 8;
264
+ _c.label = 8;
227
265
  case 8:
228
- _a.trys.push([8, 10, , 11]);
266
+ _c.trys.push([8, 10, , 11]);
229
267
  return [4 /*yield*/, this.eventManager.fire('afterSearch', {
230
268
  controller: this,
231
269
  request: params,
232
270
  response: response,
233
271
  })];
234
272
  case 9:
235
- _a.sent();
273
+ _c.sent();
236
274
  return [3 /*break*/, 11];
237
275
  case 10:
238
- err_2 = _a.sent();
276
+ err_2 = _c.sent();
239
277
  if ((err_2 === null || err_2 === void 0 ? void 0 : err_2.message) == 'cancelled') {
240
278
  this.log.warn("'afterSearch' middleware cancelled");
241
279
  afterSearchProfile.stop();
@@ -251,20 +289,22 @@ var RecommendationController = /** @class */ (function (_super) {
251
289
  this.log.profile(afterSearchProfile);
252
290
  // update the store
253
291
  this.store.update(response);
292
+ data = { responseId: responseId, tag: this.store.profile.tag };
293
+ ((_a = this.config.beacon) === null || _a === void 0 ? void 0 : _a.enabled) && this.tracker.events.recommendations.render({ data: data, siteId: (_b = this.config.globals) === null || _b === void 0 ? void 0 : _b.siteId });
254
294
  afterStoreProfile = this.profiler.create({ type: 'event', name: 'afterStore', context: params }).start();
255
- _a.label = 12;
295
+ _c.label = 12;
256
296
  case 12:
257
- _a.trys.push([12, 14, , 15]);
297
+ _c.trys.push([12, 14, , 15]);
258
298
  return [4 /*yield*/, this.eventManager.fire('afterStore', {
259
299
  controller: this,
260
300
  request: params,
261
301
  response: response,
262
302
  })];
263
303
  case 13:
264
- _a.sent();
304
+ _c.sent();
265
305
  return [3 /*break*/, 15];
266
306
  case 14:
267
- err_3 = _a.sent();
307
+ err_3 = _c.sent();
268
308
  if ((err_3 === null || err_3 === void 0 ? void 0 : err_3.message) == 'cancelled') {
269
309
  this.log.warn("'afterStore' middleware cancelled");
270
310
  afterStoreProfile.stop();
@@ -280,7 +320,7 @@ var RecommendationController = /** @class */ (function (_super) {
280
320
  this.log.profile(afterStoreProfile);
281
321
  return [3 /*break*/, 18];
282
322
  case 16:
283
- err_4 = _a.sent();
323
+ err_4 = _c.sent();
284
324
  if (err_4) {
285
325
  if (err_4.err && err_4.fetchDetails) {
286
326
  switch (err_4.fetchDetails.status) {
@@ -332,7 +372,11 @@ var RecommendationController = /** @class */ (function (_super) {
332
372
  var products;
333
373
  var _this = this;
334
374
  return __generator(this, function (_a) {
335
- products = typeof _products.slice == 'function' ? _products.slice() : [_products];
375
+ products = typeof (_products === null || _products === void 0 ? void 0 : _products.slice) == 'function' ? _products.slice() : [_products];
376
+ if (!_products || products.length === 0) {
377
+ this.log.warn('No products provided to recommendation controller.addToCart');
378
+ return [2 /*return*/];
379
+ }
336
380
  products.forEach(function (product) {
337
381
  _this.track.product.addToCart(product);
338
382
  });
@@ -357,24 +401,6 @@ var RecommendationController = /** @class */ (function (_super) {
357
401
  // deep merge config with defaults
358
402
  _this.config = (0, deepmerge_1.default)(defaultConfig, _this.config);
359
403
  _this.store.setConfig(_this.config);
360
- _this.eventManager.on('afterStore', function (search, next) { return __awaiter(_this, void 0, void 0, function () {
361
- var controller, responseId, data;
362
- var _a;
363
- return __generator(this, function (_b) {
364
- switch (_b.label) {
365
- case 0: return [4 /*yield*/, next()];
366
- case 1:
367
- _b.sent();
368
- controller = search.controller;
369
- responseId = search.response.responseId;
370
- if (controller.store.loaded && !controller.store.error) {
371
- data = { responseId: responseId, tag: controller.store.profile.tag };
372
- this.tracker.events.recommendations.render({ data: data, siteId: (_a = this.config.globals) === null || _a === void 0 ? void 0 : _a.siteId });
373
- }
374
- return [2 /*return*/];
375
- }
376
- });
377
- }); });
378
404
  // add 'afterStore' middleware
379
405
  // this.eventManager.on('afterStore', async (recommend: AfterStoreObj, next: Next): Promise<void | boolean> => {
380
406
  // await next();
@@ -1 +1 @@
1
- {"version":3,"file":"SearchController.d.ts","sourceRoot":"","sources":["../../../src/Search/SearchController.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAa,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAEpG,OAAO,EAAE,eAAe,EAAuB,MAAM,UAAU,CAAC;AAEhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAc,MAAM,+BAA+B,CAAC;AAC9F,OAAO,KAAK,EACX,sBAAsB,EAGtB,kBAAkB,EAClB,gBAAgB,EAIhB,MAAM,UAAU,CAAC;AAElB,OAAO,EACN,KAAK,kBAAkB,EAYvB,MAAM,2BAA2B,CAAC;AAsCnC,KAAK,kBAAkB,GAAG;IACzB,MAAM,EAAE;QACP,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,0BAA0B,KAAK,IAAI,CAAC;QAChF,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,0BAA0B,KAAK,IAAI,CAAC;QACvF,UAAU,EAAE,CAAC,mBAAmB,EAAE,0BAA0B,KAAK,IAAI,CAAC;KACtE,CAAC;IACF,OAAO,EAAE;QACR,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;QAChE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;QACzD,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;QAC/C,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;KACtC,CAAC;IACF,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7F,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,kBAAkB;IAChD,IAAI,kBAA0B;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;IACvC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,IAAI,CAEV;IACF,OAAO,CAAC,MAAM,CAgBP;gBAGN,MAAM,EAAE,sBAAsB,EAC9B,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAC1F,OAAO,CAAC,EAAE,gBAAgB;IAoP3B,KAAK,EAAE,kBAAkB,CAqKvB;IAEF,IAAI,MAAM,IAAI,kBAAkB,CA8C/B;IAED,MAAM,QAAa,QAAQ,IAAI,CAAC,CA0N9B;IAEF,SAAS,cAAqB,OAAO,EAAE,GAAG,OAAO,KAAG,QAAQ,IAAI,CAAC,CAQ/D;CACF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAiBxF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,MAAM,GAAG,SAAS,CAgCvG"}
1
+ {"version":3,"file":"SearchController.d.ts","sourceRoot":"","sources":["../../../src/Search/SearchController.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAa,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAEpG,OAAO,EAAE,eAAe,EAAuB,MAAM,UAAU,CAAC;AAEhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAc,MAAM,+BAA+B,CAAC;AAC9F,OAAO,KAAK,EACX,sBAAsB,EAGtB,kBAAkB,EAClB,gBAAgB,EAIhB,MAAM,UAAU,CAAC;AAElB,OAAO,EACN,KAAK,kBAAkB,EAYvB,MAAM,2BAA2B,CAAC;AAyCnC,KAAK,kBAAkB,GAAG;IACzB,MAAM,EAAE;QACP,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,0BAA0B,KAAK,IAAI,CAAC;QAChF,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,0BAA0B,KAAK,IAAI,CAAC;QACvF,UAAU,EAAE,CAAC,mBAAmB,EAAE,0BAA0B,KAAK,IAAI,CAAC;KACtE,CAAC;IACF,OAAO,EAAE;QACR,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;QAChE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;QACzD,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;QAC/C,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;KACtC,CAAC;IACF,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7F,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,kBAAkB;IAChD,IAAI,kBAA0B;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;IACvC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,IAAI,CAEV;IACF,OAAO,CAAC,MAAM,CAgBP;gBAGN,MAAM,EAAE,sBAAsB,EAC9B,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAC1F,OAAO,CAAC,EAAE,gBAAgB;IAiP3B,KAAK,EAAE,kBAAkB,CA4PvB;IAEF,IAAI,MAAM,IAAI,kBAAkB,CA8C/B;IAED,MAAM,QAAa,QAAQ,IAAI,CAAC,CA6N9B;IAEF,SAAS,cAAqB,OAAO,EAAE,GAAG,OAAO,KAAG,QAAQ,IAAI,CAAC,CAY/D;CACF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAiBxF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,MAAM,GAAG,SAAS,CAuCvG"}