@liquidcommercedev/rmn-sdk 1.5.0-beta.1 → 1.5.0-beta.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. package/dist/index.cjs +1192 -407
  2. package/dist/index.esm.js +1193 -408
  3. package/dist/types/common/helpers/utils.helper.d.ts +50 -0
  4. package/dist/types/enums.d.ts +6 -1
  5. package/dist/types/modules/element/element.interface.d.ts +5 -2
  6. package/dist/types/modules/event/event.interface.d.ts +6 -32
  7. package/dist/types/modules/event/event.service.d.ts +7 -22
  8. package/dist/types/modules/event/index.d.ts +0 -1
  9. package/dist/types/modules/{event/helpers → helper-service}/index.d.ts +1 -0
  10. package/dist/types/modules/{event/helpers → helper-service}/intersection.service.d.ts +1 -1
  11. package/dist/types/modules/helper-service/localstorage.service.d.ts +56 -0
  12. package/dist/types/modules/{event/pubsub.d.ts → helper-service/pubsub.service.d.ts} +8 -8
  13. package/dist/types/modules/{event/helpers → helper-service}/resize.service.d.ts +1 -1
  14. package/dist/types/modules/monitor/index.d.ts +2 -0
  15. package/dist/types/modules/monitor/monitor.enums.d.ts +4 -0
  16. package/dist/types/modules/monitor/monitor.interface.d.ts +11 -0
  17. package/dist/types/modules/monitor/monitor.service.d.ts +12 -0
  18. package/dist/types/modules/monitor/monitors/datalayer.monitor.d.ts +12 -0
  19. package/dist/types/modules/selection/selection.interface.d.ts +3 -1
  20. package/dist/types/rmn-client.d.ts +1 -1
  21. package/dist/types/types.d.ts +5 -4
  22. package/package.json +1 -1
  23. package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
  24. package/dist/types/modules/element/component/utils.d.ts +0 -1
  25. package/dist/types/modules/event/helpers/localstorage.service.d.ts +0 -26
  26. /package/dist/types/{static.constant.d.ts → example.constant.d.ts} +0 -0
package/dist/index.esm.js CHANGED
@@ -1,6 +1,7 @@
1
1
  var RMN_SPOT_TYPE;
2
2
  (function (RMN_SPOT_TYPE) {
3
3
  // Reserve Bar Spot Types
4
+ RMN_SPOT_TYPE["RB_HOMEPAGE_HERO"] = "rbHomepageHero";
4
5
  RMN_SPOT_TYPE["RB_HOMEPAGE_HERO_THREE_TILE"] = "rbHomepageHeroThreeTile";
5
6
  RMN_SPOT_TYPE["RB_HOMEPAGE_HERO_TWO_TILE"] = "rbHomepageHeroTwoTile";
6
7
  RMN_SPOT_TYPE["RB_HOMEPAGE_HERO_FULL_IMAGE"] = "rbHomepageHeroFullImage";
@@ -52,13 +53,18 @@ var RMN_FILTER_PROPERTIES;
52
53
  RMN_FILTER_PROPERTIES["PUBLISHERS"] = "publishers";
53
54
  RMN_FILTER_PROPERTIES["SECTION"] = "section";
54
55
  })(RMN_FILTER_PROPERTIES || (RMN_FILTER_PROPERTIES = {}));
56
+ var RMN_EVENT;
57
+ (function (RMN_EVENT) {
58
+ RMN_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
59
+ RMN_EVENT["SPOT_EVENT"] = "SPOT_EVENT";
60
+ })(RMN_EVENT || (RMN_EVENT = {}));
55
61
  var RMN_SPOT_EVENT;
56
62
  (function (RMN_SPOT_EVENT) {
57
- RMN_SPOT_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
58
63
  RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
59
64
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
60
65
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
61
66
  RMN_SPOT_EVENT["ADD_TO_CART"] = "ADD_TO_CART";
67
+ RMN_SPOT_EVENT["REMOVE_FROM_CART"] = "REMOVE_FROM_CART";
62
68
  RMN_SPOT_EVENT["ADD_TO_WISHLIST"] = "ADD_TO_WISHLIST";
63
69
  RMN_SPOT_EVENT["BUY_NOW"] = "BUY_NOW";
64
70
  })(RMN_SPOT_EVENT || (RMN_SPOT_EVENT = {}));
@@ -70,6 +76,511 @@ var RMN_ENV;
70
76
  RMN_ENV["PRODUCTION"] = "production";
71
77
  })(RMN_ENV || (RMN_ENV = {}));
72
78
 
79
+ const SPOT_EVENTS_EXAMPLE = [
80
+ {
81
+ event: RMN_SPOT_EVENT.CLICK,
82
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwidXIiOm51bGx9&s=hWz37kbxi_u95EVNn2aoQhc5Aas',
83
+ },
84
+ {
85
+ event: RMN_SPOT_EVENT.IMPRESSION,
86
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiYmEiOjEsImZxIjowfQ&s=djoysjCimurf-5T11AlNAwwLSS8',
87
+ },
88
+ {
89
+ event: RMN_SPOT_EVENT.PURCHASE,
90
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjU5fQ&s=AAPAw-3SfZ0JMzjEGFSwt9L-2S4',
91
+ },
92
+ {
93
+ event: RMN_SPOT_EVENT.ADD_TO_CART,
94
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYwfQ&s=uzQFcjgL7m9XqUG8FvTPVN5YkZY',
95
+ },
96
+ {
97
+ event: RMN_SPOT_EVENT.ADD_TO_WISHLIST,
98
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYzfQ&s=m3ISU_iIy-OFtXrTKpI6cJAEC0k',
99
+ },
100
+ {
101
+ event: RMN_SPOT_EVENT.BUY_NOW,
102
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjY5fQ&s=l6MOscQC-q-FkC2Ksd7w6jjySCQ',
103
+ },
104
+ ];
105
+ const RB_SPOTS_SELECTION_EXAMPLE = {
106
+ rbHomepageHero: [
107
+ {
108
+ id: 'abc123',
109
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
110
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
111
+ width: 1140,
112
+ height: 640,
113
+ header: 'Premium Wine Collection',
114
+ description: 'Discover our exclusive selection of vintage wines',
115
+ ctaText: 'Shop Wines',
116
+ textColor: '#ffffff',
117
+ ctaTextColor: '#ffffff',
118
+ primaryImage: 'https://placehold.co/1140x640/png?text=Wine+Collection',
119
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Wine',
120
+ events: SPOT_EVENTS_EXAMPLE,
121
+ productIds: [1, 2, 3],
122
+ },
123
+ {
124
+ id: 'jkl012',
125
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
126
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
127
+ width: 1140,
128
+ height: 640,
129
+ header: 'Whiskey Collection',
130
+ description: 'Premium whiskeys from around the world',
131
+ ctaText: 'Shop Whiskeys',
132
+ textColor: '#ffffff',
133
+ backgroundColor: '#2c1810',
134
+ ctaTextColor: '#2c1810',
135
+ primaryImage: 'https://placehold.co/1140x640/png?text=Whiskey',
136
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Whiskey',
137
+ events: SPOT_EVENTS_EXAMPLE,
138
+ productIds: [10, 11],
139
+ },
140
+ {
141
+ id: 'stu901',
142
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
143
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
144
+ width: 1140,
145
+ height: 640,
146
+ header: 'Summer Cocktails',
147
+ description: 'Essential spirits for summer mixing',
148
+ ctaText: 'Mix It Up',
149
+ textColor: '#ffffff',
150
+ backgroundColor: '#4d3a0a',
151
+ ctaTextColor: '#4d3a0a',
152
+ primaryImage: 'https://placehold.co/1140x640/png?text=Cocktails',
153
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Mixers',
154
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Cocktails',
155
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Mixers',
156
+ events: SPOT_EVENTS_EXAMPLE,
157
+ productIds: [16, 17, 18],
158
+ },
159
+ {
160
+ id: 'def456',
161
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
162
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
163
+ width: 1140,
164
+ height: 640,
165
+ header: 'Craft Beer Festival',
166
+ description: 'Local breweries and exclusive releases',
167
+ ctaText: 'Explore Beers',
168
+ textColor: '#ffffff',
169
+ ctaTextColor: '#ffffff',
170
+ primaryImage: 'https://placehold.co/1140x640/png?text=Beer+Festival',
171
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Beer',
172
+ events: SPOT_EVENTS_EXAMPLE,
173
+ productIds: [4, 5, 6],
174
+ },
175
+ {
176
+ id: 'mno345',
177
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
178
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
179
+ width: 1140,
180
+ height: 640,
181
+ header: 'Champagne Selection',
182
+ description: 'Finest champagnes for every occasion',
183
+ ctaText: 'View Champagnes',
184
+ textColor: '#ffffff',
185
+ backgroundColor: '#1a1a1a',
186
+ ctaTextColor: '#1a1a1a',
187
+ primaryImage: 'https://placehold.co/1140x640/png?text=Champagne',
188
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Champagne',
189
+ events: SPOT_EVENTS_EXAMPLE,
190
+ productIds: [12, 13],
191
+ },
192
+ {
193
+ id: 'vwx234',
194
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
195
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
196
+ width: 1140,
197
+ height: 640,
198
+ header: 'Wine Regions',
199
+ description: 'Explore wines from top regions',
200
+ ctaText: 'Tour Regions',
201
+ textColor: '#ffffff',
202
+ backgroundColor: '#4d0a0a',
203
+ ctaTextColor: '#4d0a0a',
204
+ primaryImage: 'https://placehold.co/1140x640/png?text=Wine+Regions',
205
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Vineyards',
206
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Regions',
207
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Vineyards',
208
+ events: SPOT_EVENTS_EXAMPLE,
209
+ productIds: [19, 20, 21],
210
+ },
211
+ {
212
+ id: 'ghi789',
213
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
214
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
215
+ width: 1140,
216
+ height: 640,
217
+ header: 'Rare Spirits',
218
+ description: 'Limited edition spirits collection',
219
+ ctaText: 'View Collection',
220
+ textColor: '#ffffff',
221
+ ctaTextColor: '#ffffff',
222
+ primaryImage: 'https://placehold.co/1140x640/png?text=Rare+Spirits',
223
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Spirits',
224
+ events: SPOT_EVENTS_EXAMPLE,
225
+ productIds: [7, 8, 9],
226
+ },
227
+ {
228
+ id: 'pqr678',
229
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
230
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
231
+ width: 1140,
232
+ height: 640,
233
+ header: 'Gin Collection',
234
+ description: 'Artisanal gins and botanicals',
235
+ ctaText: 'Explore Gins',
236
+ textColor: '#ffffff',
237
+ backgroundColor: '#0a4d4d',
238
+ ctaTextColor: '#0a4d4d',
239
+ primaryImage: 'https://placehold.co/1140x640/png?text=Gin',
240
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Gin',
241
+ events: SPOT_EVENTS_EXAMPLE,
242
+ productIds: [14, 15],
243
+ },
244
+ {
245
+ id: 'yz5678',
246
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
247
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
248
+ width: 1140,
249
+ height: 640,
250
+ header: 'Tequila Collection',
251
+ description: 'Premium tequilas and mezcals',
252
+ ctaText: 'Shop Tequila',
253
+ textColor: '#ffffff',
254
+ backgroundColor: '#0a4d2b',
255
+ ctaTextColor: '#0a4d2b',
256
+ primaryImage: 'https://placehold.co/1140x640/png?text=Tequila',
257
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Mezcal',
258
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Tequila',
259
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Mezcal',
260
+ events: SPOT_EVENTS_EXAMPLE,
261
+ productIds: [22, 23, 24],
262
+ },
263
+ ],
264
+ rbHomepageHeroFullImage: [
265
+ {
266
+ id: 'hjk567',
267
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
268
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
269
+ width: 1140,
270
+ height: 640,
271
+ header: 'Holiday Gift Guide',
272
+ description: 'Perfect spirits for every occasion',
273
+ ctaText: 'Shop Gifts',
274
+ textColor: '#ffffff',
275
+ ctaTextColor: '#ffffff',
276
+ primaryImage: 'https://placehold.co/1140x640/png?text=Gift+Guide',
277
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Gifts',
278
+ events: SPOT_EVENTS_EXAMPLE,
279
+ productIds: [25, 26],
280
+ },
281
+ {
282
+ id: 'qwe890',
283
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
284
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
285
+ width: 1140,
286
+ height: 640,
287
+ header: 'Summer Wine Festival',
288
+ description: 'Refreshing wines for summer',
289
+ ctaText: 'Shop Festival',
290
+ textColor: '#ffffff',
291
+ ctaTextColor: '#ffffff',
292
+ primaryImage: 'https://placehold.co/1140x640/png?text=Wine+Festival',
293
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Festival',
294
+ events: SPOT_EVENTS_EXAMPLE,
295
+ productIds: [27, 28],
296
+ },
297
+ ],
298
+ rbHomepageHeroTwoTile: [
299
+ {
300
+ id: 'iop987',
301
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
302
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
303
+ width: 1140,
304
+ height: 640,
305
+ header: 'Bourbon Selection',
306
+ description: "Kentucky's finest bourbons",
307
+ ctaText: 'Shop Bourbon',
308
+ textColor: '#ffffff',
309
+ backgroundColor: '#2c1810',
310
+ ctaTextColor: '#2c1810',
311
+ primaryImage: 'https://placehold.co/1140x640/png?text=Bourbon',
312
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Bourbon',
313
+ events: SPOT_EVENTS_EXAMPLE,
314
+ productIds: [29, 30],
315
+ },
316
+ {
317
+ id: 'lkj012',
318
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
319
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
320
+ width: 1140,
321
+ height: 640,
322
+ header: 'Vodka Collection',
323
+ description: 'Premium vodkas from around the world',
324
+ ctaText: 'Shop Vodka',
325
+ textColor: '#ffffff',
326
+ backgroundColor: '#1a1a1a',
327
+ ctaTextColor: '#1a1a1a',
328
+ primaryImage: 'https://placehold.co/1140x640/png?text=Vodka',
329
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Vodka',
330
+ events: SPOT_EVENTS_EXAMPLE,
331
+ productIds: [31, 32],
332
+ },
333
+ ],
334
+ rbHomepageHeroThreeTile: [
335
+ {
336
+ id: 'bnm345',
337
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
338
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
339
+ width: 1140,
340
+ height: 640,
341
+ header: 'Rum Collection',
342
+ description: 'Caribbean and craft rums',
343
+ ctaText: 'Shop Rum',
344
+ textColor: '#ffffff',
345
+ backgroundColor: '#4d3a0a',
346
+ ctaTextColor: '#4d3a0a',
347
+ primaryImage: 'https://placehold.co/1140x640/png?text=Rum',
348
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Craft+Rum',
349
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Rum',
350
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Craft',
351
+ events: SPOT_EVENTS_EXAMPLE,
352
+ productIds: [33, 34],
353
+ },
354
+ {
355
+ id: 'fgh678',
356
+ spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
357
+ variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
358
+ width: 1140,
359
+ height: 640,
360
+ header: 'Scotch Selection',
361
+ description: 'Single malts and blends',
362
+ ctaText: 'Shop Scotch',
363
+ textColor: '#ffffff',
364
+ backgroundColor: '#4d0a0a',
365
+ ctaTextColor: '#4d0a0a',
366
+ primaryImage: 'https://placehold.co/1140x640/png?text=Scotch',
367
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Single+Malts',
368
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Scotch',
369
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Malts',
370
+ events: SPOT_EVENTS_EXAMPLE,
371
+ productIds: [35, 36],
372
+ },
373
+ ],
374
+ rbLargeCategoryImageTout: [
375
+ {
376
+ id: 'cde567',
377
+ spot: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
378
+ variant: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
379
+ width: 468,
380
+ height: 410,
381
+ header: 'Rare & Limited Edition',
382
+ description: 'Discover our collection of hard-to-find and limited release spirits.',
383
+ textColor: '#ffffff',
384
+ ctaTextColor: '#ffffff',
385
+ primaryImage: 'https://placehold.co/468x410/png?text=Rare+Spirits',
386
+ mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Rare+Spirits',
387
+ ctaText: 'Shop Rare Spirits',
388
+ events: SPOT_EVENTS_EXAMPLE,
389
+ productIds: [37, 38, 39, 40, 41],
390
+ },
391
+ {
392
+ id: 'efg789',
393
+ spot: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
394
+ variant: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
395
+ width: 468,
396
+ height: 410,
397
+ header: 'Vintage Champagnes',
398
+ description: 'Explore our prestigious collection of aged champagnes.',
399
+ textColor: '#ffffff',
400
+ ctaTextColor: '#ffffff',
401
+ primaryImage: 'https://placehold.co/468x410/png?text=Vintage+Champagne',
402
+ mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Champagne',
403
+ ctaText: 'View Collection',
404
+ events: SPOT_EVENTS_EXAMPLE,
405
+ productIds: [42, 43, 44, 45, 46],
406
+ },
407
+ {
408
+ id: 'ghi012',
409
+ spot: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
410
+ variant: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
411
+ width: 468,
412
+ height: 410,
413
+ header: 'Small Batch Bourbon',
414
+ description: 'Hand-selected premium bourbon from craft distilleries.',
415
+ textColor: '#ffffff',
416
+ ctaTextColor: '#ffffff',
417
+ primaryImage: 'https://placehold.co/468x410/png?text=Craft+Bourbon',
418
+ mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Bourbon',
419
+ ctaText: 'Explore Bourbon',
420
+ events: SPOT_EVENTS_EXAMPLE,
421
+ productIds: [47, 48, 49, 50, 51],
422
+ },
423
+ ],
424
+ rbSmallDiscoverTout: [
425
+ {
426
+ id: 'jkl345',
427
+ spot: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
428
+ variant: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
429
+ width: 224,
430
+ height: 378,
431
+ header: 'Château Margaux 2015 Bordeaux',
432
+ textColor: '#ffffff',
433
+ primaryImage: 'https://placehold.co/224x378/png?text=Château+Margaux',
434
+ mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Château+Margaux',
435
+ events: SPOT_EVENTS_EXAMPLE,
436
+ productIds: [52, 53, 54, 55, 56],
437
+ },
438
+ {
439
+ id: 'lmn678',
440
+ spot: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
441
+ variant: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
442
+ width: 224,
443
+ height: 378,
444
+ header: 'Macallan 25 Year',
445
+ textColor: '#ffffff',
446
+ primaryImage: 'https://placehold.co/224x378/png?text=Macallan+25',
447
+ mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Macallan',
448
+ events: SPOT_EVENTS_EXAMPLE,
449
+ productIds: [57, 58, 59, 60, 61],
450
+ },
451
+ {
452
+ id: 'nop901',
453
+ spot: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
454
+ variant: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
455
+ width: 224,
456
+ height: 378,
457
+ header: 'Louis XIII Cognac',
458
+ textColor: '#ffffff',
459
+ primaryImage: 'https://placehold.co/224x378/png?text=Louis+XIII',
460
+ mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Louis+XIII',
461
+ events: SPOT_EVENTS_EXAMPLE,
462
+ productIds: [62, 63, 64, 65, 66],
463
+ },
464
+ ],
465
+ rbSmallCategoryImageTout: [
466
+ {
467
+ id: 'qrs234',
468
+ spot: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
469
+ variant: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
470
+ width: 224,
471
+ height: 410,
472
+ header: 'Japanese Sake',
473
+ textColor: '#ffffff',
474
+ primaryImage: 'https://placehold.co/224x410/png?text=Japanese+Sake',
475
+ mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Japanese+Sake',
476
+ events: SPOT_EVENTS_EXAMPLE,
477
+ productIds: [67, 68, 69, 70, 71],
478
+ },
479
+ {
480
+ id: 'stu567',
481
+ spot: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
482
+ variant: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
483
+ width: 224,
484
+ height: 410,
485
+ header: 'Craft Vermouth',
486
+ textColor: '#ffffff',
487
+ primaryImage: 'https://placehold.co/224x410/png?text=Craft+Vermouth',
488
+ mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Vermouth',
489
+ events: SPOT_EVENTS_EXAMPLE,
490
+ productIds: [72, 73, 74, 75, 76],
491
+ },
492
+ {
493
+ id: 'vwx890',
494
+ spot: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
495
+ variant: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
496
+ width: 224,
497
+ height: 410,
498
+ header: 'Premium Mezcal',
499
+ textColor: '#ffffff',
500
+ primaryImage: 'https://placehold.co/224x410/png?text=Premium+Mezcal',
501
+ mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Mezcal',
502
+ events: SPOT_EVENTS_EXAMPLE,
503
+ productIds: [77, 78, 79, 80, 81],
504
+ },
505
+ ],
506
+ rbCollectionBannerWithoutTextBlock: [
507
+ {
508
+ id: 'yz1234',
509
+ spot: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
510
+ variant: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
511
+ width: 887,
512
+ height: 344,
513
+ primaryImage: 'https://placehold.co/887x344/png?text=Summer+Cocktails',
514
+ mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Summer+Cocktails',
515
+ events: SPOT_EVENTS_EXAMPLE,
516
+ productIds: [82, 83, 84, 85, 86],
517
+ },
518
+ {
519
+ id: 'abc567',
520
+ spot: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
521
+ variant: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
522
+ width: 887,
523
+ height: 344,
524
+ primaryImage: 'https://placehold.co/887x344/png?text=Holiday+Spirits',
525
+ mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Holiday+Spirits',
526
+ events: SPOT_EVENTS_EXAMPLE,
527
+ productIds: [87, 88, 89, 90, 91],
528
+ },
529
+ {
530
+ id: 'def901',
531
+ spot: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
532
+ variant: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
533
+ width: 887,
534
+ height: 344,
535
+ primaryImage: 'https://placehold.co/887x344/png?text=Wine+Essentials',
536
+ mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Wine+Essentials',
537
+ events: SPOT_EVENTS_EXAMPLE,
538
+ productIds: [92, 93, 94, 95, 96],
539
+ },
540
+ ],
541
+ rbNavigationBanner: [
542
+ {
543
+ id: 'ghi234',
544
+ spot: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
545
+ variant: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
546
+ width: 440,
547
+ height: 220,
548
+ header: 'Explore Tequilas',
549
+ textColor: '#ffffff',
550
+ primaryImage: 'https://placehold.co/440x220/png?text=Tequila+Collection',
551
+ mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Tequila+Collection',
552
+ events: SPOT_EVENTS_EXAMPLE,
553
+ productIds: [97, 98, 99, 100, 101],
554
+ },
555
+ {
556
+ id: 'jkl678',
557
+ spot: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
558
+ variant: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
559
+ width: 440,
560
+ height: 220,
561
+ header: 'Craft Gin Selection',
562
+ textColor: '#ffffff',
563
+ primaryImage: 'https://placehold.co/440x220/png?text=Gin+Selection',
564
+ mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Gin+Selection',
565
+ events: SPOT_EVENTS_EXAMPLE,
566
+ productIds: [102, 103, 104, 105, 106],
567
+ },
568
+ {
569
+ id: 'mno012',
570
+ spot: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
571
+ variant: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
572
+ width: 440,
573
+ height: 220,
574
+ header: 'Premium Vodka',
575
+ textColor: '#ffffff',
576
+ primaryImage: 'https://placehold.co/440x220/png?text=Vodka+Premium',
577
+ mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Vodka+Premium',
578
+ events: SPOT_EVENTS_EXAMPLE,
579
+ productIds: [107, 108, 109, 110, 111],
580
+ },
581
+ ],
582
+ };
583
+
73
584
  const REQUEST_CLOUD_PARTNER_SITE = 'X-Liquid-Partner-Site';
74
585
  const REQUEST_CLOUD_PROTECTED_KEY = 'X-Liquid-Protected';
75
586
  const REQUEST_CLOUD_PROTECTED_TIMESTAMP = 'X-Liquid-Timestamp';
@@ -15139,29 +15650,230 @@ class AuthService extends BaseApi {
15139
15650
  if (isErr) {
15140
15651
  throw new Error(`There was an error during authentication: (${isErr === null || isErr === void 0 ? void 0 : isErr.errorMessage})`);
15141
15652
  }
15142
- if (isOk && (val === null || val === void 0 ? void 0 : val.data.token)) {
15143
- this.authInfo.token = val.data.token;
15144
- this.authInfo.authenticated = true;
15653
+ if (isOk && (val === null || val === void 0 ? void 0 : val.data.token)) {
15654
+ this.authInfo.token = val.data.token;
15655
+ this.authInfo.authenticated = true;
15656
+ }
15657
+ else {
15658
+ throw new Error('Auth response was not successful');
15659
+ }
15660
+ return this.authInfo;
15661
+ }
15662
+ }
15663
+
15664
+ const SPOT_ELEMENT_TAG = 'spot-element';
15665
+ const CAROUSEL_ELEMENT_TAG = 'spot-carousel-element';
15666
+ const GFONT_PRECONNECT = `
15667
+ <link rel="preconnect" href="https://fonts.googleapis.com">
15668
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15669
+ `;
15670
+ const GFONT_SOURCE_SANS_3 = `
15671
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15672
+ `;
15673
+ const GFONT_CORMORANT = `
15674
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15675
+ `;
15676
+
15677
+ /**
15678
+ * Determines the event type from a raw event string.
15679
+ *
15680
+ * @param {string} [event] - The raw event string to evaluate.
15681
+ * @returns {RMN_SPOT_EVENT | null} - The corresponding RMN_SPOT_EVENT or null if no match is found.
15682
+ */
15683
+ function getEventTypeFromRawEvent(event) {
15684
+ if (!event) {
15685
+ return null;
15686
+ }
15687
+ if (event.includes('cart')) {
15688
+ if (event.includes('add')) {
15689
+ return RMN_SPOT_EVENT.ADD_TO_CART;
15690
+ }
15691
+ if (event.includes('remove')) {
15692
+ return RMN_SPOT_EVENT.REMOVE_FROM_CART;
15693
+ }
15694
+ }
15695
+ if (event.includes('purchase')) {
15696
+ return RMN_SPOT_EVENT.PURCHASE;
15697
+ }
15698
+ // if(event.includes('refund')) {
15699
+ // return RMN_SPOT_EVENT.REFUND;
15700
+ // }
15701
+ if (event.includes('wishlist') && event.includes('add')) {
15702
+ return RMN_SPOT_EVENT.ADD_TO_WISHLIST;
15703
+ }
15704
+ return null;
15705
+ }
15706
+ /**
15707
+ * Recursively extracts ID values from a nested data structure.
15708
+ * Searches for specified property names and collects their primitive values (strings/numbers).
15709
+ *
15710
+ * @param data - The data structure to search through (can be nested objects/arrays)
15711
+ * @param propertyNames - Array of property names to look for
15712
+ * @returns Array of extracted ID values (strings/numbers only)
15713
+ *
15714
+ * @example
15715
+ * const data = {
15716
+ * id: [1, 2, 3],
15717
+ * nested: { id: 'abc' },
15718
+ * items: [{ id: 456 }]
15719
+ * };
15720
+ * extractDeepIds(data); // Returns [1, 2, 3, 'abc', 456]
15721
+ */
15722
+ function extractDeepIds(data, propertyNames) {
15723
+ const ids = [];
15724
+ const defaulPropertyNames = [
15725
+ 'id',
15726
+ 'upc',
15727
+ 'groupingId',
15728
+ 'sku',
15729
+ 'productId',
15730
+ 'item_id',
15731
+ 'isbn',
15732
+ 'asin',
15733
+ 'mpn',
15734
+ 'model_number',
15735
+ 'article_number',
15736
+ 'variant_id',
15737
+ 'item_number',
15738
+ 'catalog_id',
15739
+ 'reference_id',
15740
+ ];
15741
+ // Set for faster property name lookups
15742
+ const propertySet = new Set(defaulPropertyNames);
15743
+ /**
15744
+ * Processes a value and extracts IDs if it matches criteria
15745
+ * @param value - The value to process
15746
+ * @param currentKey - The property name of the current value
15747
+ */
15748
+ const processValue = (value, currentKey) => {
15749
+ // Early exit for null/undefined values
15750
+ if (value == null)
15751
+ return;
15752
+ // If current key matches our target properties
15753
+ if (currentKey && propertySet.has(currentKey)) {
15754
+ if (Array.isArray(value)) {
15755
+ // Filter and push valid array values in one pass
15756
+ ids.push(...value.filter((item) => typeof item === 'string' || typeof item === 'number'));
15757
+ }
15758
+ else if (typeof value === 'string' || typeof value === 'number') {
15759
+ ids.push(value);
15760
+ }
15761
+ return; // Stop processing this branch after handling the ID
15762
+ }
15763
+ // Recursively process nested structures
15764
+ if (Array.isArray(value)) {
15765
+ value.forEach((item) => processValue(item));
15145
15766
  }
15146
- else {
15147
- throw new Error('Auth response was not successful');
15767
+ else if (typeof value === 'object') {
15768
+ // Process all enumerable properties
15769
+ for (const [key, val] of Object.entries(value)) {
15770
+ processValue(val, key);
15771
+ }
15148
15772
  }
15149
- return this.authInfo;
15773
+ };
15774
+ processValue(data);
15775
+ return ids; // No need to filter nulls as we handle that during collection
15776
+ }
15777
+ // Fallback method using fetch if sendBeacon isn't available
15778
+ async function fallbackEventFire(url) {
15779
+ try {
15780
+ const racePromise = Promise.race([
15781
+ // Promise #1: The fetch request
15782
+ fetch(url, {
15783
+ method: 'POST',
15784
+ keepalive: true,
15785
+ }),
15786
+ // Promise #2: The timeout
15787
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Request timeout')), 2000)),
15788
+ ]);
15789
+ /**
15790
+ * Prevent requests from hanging indefinitely
15791
+ * Improve user experience by failing fast
15792
+ * Handle slow network conditions gracefully
15793
+ * Ensure resources are freed up in a timely manner
15794
+ */
15795
+ const response = await racePromise;
15796
+ return response.ok;
15797
+ }
15798
+ catch (_a) {
15799
+ return false;
15150
15800
  }
15151
15801
  }
15152
-
15153
- const SPOT_ELEMENT_TAG = 'spot-element';
15154
- const CAROUSEL_ELEMENT_TAG = 'spot-carousel-element';
15155
- const GFONT_PRECONNECT = `
15156
- <link rel="preconnect" href="https://fonts.googleapis.com">
15157
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15158
- `;
15159
- const GFONT_SOURCE_SANS_3 = `
15160
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15161
- `;
15162
- const GFONT_CORMORANT = `
15163
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15164
- `;
15802
+ /**
15803
+ * Extracts and decodes a URL from a base64-encoded query parameter.
15804
+ *
15805
+ * @param {string} url - The URL containing the base64-encoded query parameter.
15806
+ * @returns {string | null} - The decoded URL or null if not found or invalid.
15807
+ */
15808
+ function getRedirectUrlFromPayload(url) {
15809
+ try {
15810
+ const base64String = new URL(url).searchParams.get('e');
15811
+ if (!base64String) {
15812
+ return null;
15813
+ }
15814
+ const data = JSON.parse(atob(base64String));
15815
+ return data.ur || null;
15816
+ }
15817
+ catch (_a) {
15818
+ return null;
15819
+ }
15820
+ }
15821
+ /**
15822
+ * Fires an event using the navigator.sendBeacon method or a fallback method if sendBeacon is not available.
15823
+ * If the event is a click event and a redirect URL is found, it redirects the user to that URL.
15824
+ *
15825
+ * @param {IFireEventParams} params - The parameters for firing the event.
15826
+ * @param {RMN_SPOT_EVENT} params.event - The event type.
15827
+ * @param {string} params.eventUrl - The URL to which the event is sent.
15828
+ * @returns {Promise<void>} - A promise that resolves when the event is fired.
15829
+ */
15830
+ async function fireEvent({ event, eventUrl }) {
15831
+ var _a;
15832
+ try {
15833
+ const didFireEvent = ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.sendBeacon) === null || _a === void 0 ? void 0 : _a.call(navigator, eventUrl)) || (await fallbackEventFire(eventUrl));
15834
+ if (!didFireEvent) {
15835
+ return;
15836
+ }
15837
+ if (event === RMN_SPOT_EVENT.CLICK) {
15838
+ const redirectUrl = getRedirectUrlFromPayload(eventUrl);
15839
+ if (redirectUrl) {
15840
+ window.location.href = redirectUrl;
15841
+ }
15842
+ }
15843
+ }
15844
+ catch (_b) {
15845
+ // Handle errors silently
15846
+ }
15847
+ }
15848
+ function calculateScaleFactor(elementScale) {
15849
+ // Step 1: Apply square root for non-linear scaling
15850
+ // This creates a more gradual scaling effect, especially for larger changes
15851
+ // For example:
15852
+ // - elementScale of 0.25 (1/4 size) becomes 0.5
15853
+ // - elementScale of 1 (unchanged) remains 1
15854
+ // - elementScale of 4 (4x size) becomes 2
15855
+ const baseFactor = Math.sqrt(elementScale);
15856
+ // Step 2: Apply additional dampening to further soften the scaling effect
15857
+ // The dampening factor (0.5) can be adjusted:
15858
+ // - Lower values (closer to 0) make scaling more subtle
15859
+ // - Higher values (closer to 1) make scaling more pronounced
15860
+ const dampening = 0.35;
15861
+ // Calculate the scaleFactor:
15862
+ // 1. (baseFactor - 1) represents the change from the original size
15863
+ // 2. Multiply by dampening to reduce the effect
15864
+ // 3. Add 1 to center the scaling around the original size
15865
+ // For example, if baseFactor is 2:
15866
+ // scaleFactor = 1 + (2 - 1) * 0.5 = 1.5
15867
+ const scaleFactor = 1 + (baseFactor - 1) * dampening;
15868
+ // Step 3: Define the allowed range for the scale factor
15869
+ // This ensures that the font size never changes too drastically
15870
+ const minScale = 0.35; // Font will never be smaller than 50% of original
15871
+ const maxScale = 1.5; // Font will never be larger than 150% of original
15872
+ // Step 4: Clamp the scale factor to the defined range
15873
+ // Math.min ensures the value doesn't exceed maxScale
15874
+ // Math.max ensures the value isn't less than minScale
15875
+ return Math.max(minScale, Math.min(maxScale, scaleFactor));
15876
+ }
15165
15877
 
15166
15878
  class IntersectionObserverService {
15167
15879
  constructor(defaultOptions = {}) {
@@ -15203,8 +15915,21 @@ class IntersectionObserverService {
15203
15915
  }
15204
15916
  }
15205
15917
 
15206
- class LocalStorage {
15918
+ var ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX;
15919
+ (function (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX) {
15920
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PLACEMENT_ID"] = 0] = "PLACEMENT_ID";
15921
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_ID"] = 1] = "SPOT_ID";
15922
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_TYPE"] = 2] = "SPOT_TYPE";
15923
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["EVENTS"] = 3] = "EVENTS";
15924
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 4] = "PRODUCT_IDS";
15925
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 5] = "CREATED_AT";
15926
+ })(ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX || (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX = {}));
15927
+ class LocalStorageService {
15207
15928
  constructor() {
15929
+ if (typeof window.localStorage === 'undefined') {
15930
+ console.warn('Local storage is not supported in this environment');
15931
+ return;
15932
+ }
15208
15933
  this.spots = new Map();
15209
15934
  // Sync local storage with the current state
15210
15935
  this.syncLocalStorage();
@@ -15212,19 +15937,23 @@ class LocalStorage {
15212
15937
  this.removeExpiredSpots();
15213
15938
  }
15214
15939
  static getInstance() {
15215
- if (!LocalStorage.instance) {
15216
- LocalStorage.instance = new LocalStorage();
15940
+ if (!LocalStorageService.instance) {
15941
+ LocalStorageService.instance = new LocalStorageService();
15217
15942
  }
15218
- return LocalStorage.instance;
15943
+ return LocalStorageService.instance;
15219
15944
  }
15220
15945
  syncLocalStorage() {
15221
- const localStorageData = localStorage.getItem(LocalStorage.localStorageKey);
15222
- // TODO: Encrypt the data before storing it in the local storage
15946
+ const localStorageData = window.localStorage.getItem(LocalStorageService.localStorageKey);
15223
15947
  if (localStorageData) {
15224
15948
  try {
15225
- const parsedData = JSON.parse(localStorageData);
15949
+ const decryptedData = this.decryptData(localStorageData);
15950
+ const parsedData = JSON.parse(decryptedData);
15226
15951
  if (parsedData && typeof parsedData === 'object') {
15227
- this.spots = this.objToMap(parsedData);
15952
+ const data = {};
15953
+ for (const [key, value] of Object.entries(parsedData)) {
15954
+ data[key] = this.arrayToObject(value);
15955
+ }
15956
+ this.spots = this.objectToMap(data);
15228
15957
  }
15229
15958
  else {
15230
15959
  this.clearLocalStorage();
@@ -15237,43 +15966,176 @@ class LocalStorage {
15237
15966
  }
15238
15967
  }
15239
15968
  setSpot(spotId, data) {
15969
+ var _a;
15240
15970
  data.createdAt = Date.now();
15241
- this.spots.set(spotId, data);
15971
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.set(spotId, data);
15242
15972
  this.updateLocalStorage();
15243
15973
  }
15244
- getSpot(spotId) {
15245
- return this.spots.get(spotId);
15246
- }
15247
15974
  removeSpot(spotId) {
15248
- this.spots.delete(spotId);
15975
+ var _a;
15976
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.delete(spotId);
15249
15977
  this.updateLocalStorage();
15250
15978
  }
15979
+ getSpot(spotId) {
15980
+ var _a;
15981
+ return (_a = this.spots) === null || _a === void 0 ? void 0 : _a.get(spotId);
15982
+ }
15983
+ getSpots() {
15984
+ if (!this.spots)
15985
+ return undefined;
15986
+ return this.mapToObject(this.spots);
15987
+ }
15251
15988
  updateLocalStorage() {
15252
- const data = this.mapToObj(this.spots);
15253
- localStorage.setItem(LocalStorage.localStorageKey, JSON.stringify(data));
15989
+ if (!this.spots)
15990
+ return undefined;
15991
+ const data = this.mapToObject(this.spots);
15992
+ const dataArray = {};
15993
+ for (const [key, value] of Object.entries(data)) {
15994
+ dataArray[key] = this.objectToArray(value);
15995
+ }
15996
+ try {
15997
+ const encryptedData = this.encryptData(JSON.stringify(dataArray));
15998
+ window.localStorage.setItem(LocalStorageService.localStorageKey, encryptedData);
15999
+ }
16000
+ catch (_a) {
16001
+ // If there is an error parsing the data, clear the local storage to prevent any issues
16002
+ this.clearLocalStorage();
16003
+ }
15254
16004
  }
15255
16005
  clearLocalStorage() {
15256
- localStorage.removeItem(LocalStorage.localStorageKey);
16006
+ window.localStorage.removeItem(LocalStorageService.localStorageKey);
15257
16007
  }
15258
16008
  removeExpiredSpots() {
16009
+ var _a;
15259
16010
  const currentTime = Date.now();
15260
- this.spots.forEach((spot, spotId) => {
15261
- var _a;
15262
- if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorage.spotExpirationTime) {
15263
- this.spots.delete(spotId);
16011
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.forEach((spot, spotId) => {
16012
+ var _a, _b;
16013
+ if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorageService.spotExpirationTime) {
16014
+ (_b = this.spots) === null || _b === void 0 ? void 0 : _b.delete(spotId);
15264
16015
  }
15265
16016
  });
15266
16017
  this.updateLocalStorage();
15267
16018
  }
15268
- mapToObj(map) {
16019
+ mapToObject(map) {
15269
16020
  return Object.fromEntries(map);
15270
16021
  }
15271
- objToMap(obj) {
16022
+ objectToMap(obj) {
15272
16023
  return new Map(Object.entries(obj));
15273
16024
  }
16025
+ objectToArray(obj) {
16026
+ return [obj.placementId, obj.spotId, obj.spotType, obj.events, obj.productIds, obj.createdAt];
16027
+ }
16028
+ arrayToObject(arr) {
16029
+ return {
16030
+ placementId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PLACEMENT_ID],
16031
+ spotId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_ID],
16032
+ spotType: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_TYPE],
16033
+ events: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.EVENTS],
16034
+ productIds: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PRODUCT_IDS],
16035
+ createdAt: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.CREATED_AT],
16036
+ };
16037
+ }
16038
+ encryptData(data) {
16039
+ if (!LocalStorageService.encryptData)
16040
+ return data;
16041
+ // For now, we are using base64 encoding to encrypt the data
16042
+ // Later we will use Jose encryption
16043
+ const encryptedData = btoa(data);
16044
+ return encryptedData;
16045
+ }
16046
+ decryptData(data) {
16047
+ if (!LocalStorageService.encryptData)
16048
+ return data;
16049
+ // For now, we are using base64 encoding to encrypt
16050
+ // Later we will use Jose encryption
16051
+ const decryptedData = atob(data);
16052
+ return decryptedData;
16053
+ }
16054
+ }
16055
+ LocalStorageService.localStorageKey = 'lc_rmn';
16056
+ LocalStorageService.spotExpirationTime = 1000 * 60 * 60 * 24 * 7; // 7 days
16057
+ LocalStorageService.encryptData = true;
16058
+
16059
+ /**
16060
+ * PubsubService class
16061
+ * Manages event subscriptions and publications
16062
+ * @template IRmnEventMap A record type defining the structure of events and their data
16063
+ */
16064
+ class PubsubService {
16065
+ constructor() {
16066
+ /**
16067
+ * Object to store subscribers for each event type
16068
+ */
16069
+ this.subscribers = {};
16070
+ }
16071
+ static getInstance() {
16072
+ if (!PubsubService.instance) {
16073
+ PubsubService.instance = new PubsubService();
16074
+ }
16075
+ return PubsubService.instance;
16076
+ }
16077
+ /**
16078
+ * Subscribe to an event
16079
+ * @param eventType - The type of event to subscribe to
16080
+ * @param callback - The function to be called when the event is published
16081
+ * @returns A function to unsubscribe from the event
16082
+ *
16083
+ * @Example:
16084
+ * const unsubscribe = pubSub.subscribe('userLogin', (data) => {
16085
+ * console.log(`User ${data.username} logged in`);
16086
+ * });
16087
+ */
16088
+ subscribe(eventType, callback) {
16089
+ if (!this.subscribers[eventType]) {
16090
+ this.subscribers[eventType] = [];
16091
+ }
16092
+ this.subscribers[eventType].push(callback);
16093
+ // Return an unsubscribe function
16094
+ return () => {
16095
+ this.subscribers[eventType] = this.subscribers[eventType].filter((cb) => cb !== callback);
16096
+ };
16097
+ }
16098
+ /**
16099
+ * Publish an event
16100
+ * @param eventType - The type of event to publish
16101
+ * @param data - The data to be passed to the event subscribers
16102
+ *
16103
+ * @Example:
16104
+ * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
16105
+ */
16106
+ publish(eventType, data) {
16107
+ if (!this.subscribers[eventType]) {
16108
+ return;
16109
+ }
16110
+ this.subscribers[eventType].forEach((callback) => callback(data));
16111
+ }
15274
16112
  }
15275
- LocalStorage.localStorageKey = 'lc_rmn';
15276
- LocalStorage.spotExpirationTime = 1000 * 60 * 60 * 24 * 7; // 7 days
16113
+ /**
16114
+ * Usage Example:
16115
+ *
16116
+ * interface IRmnEventMap {
16117
+ * userLogin: { username: string; timestamp: number };
16118
+ * pageView: { url: string; timestamp: number };
16119
+ * }
16120
+ *
16121
+ * const pubSub = new PubsubService<IRmnEventMap>();
16122
+ *
16123
+ * // Subscribe to events
16124
+ * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
16125
+ * console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
16126
+ * });
16127
+ *
16128
+ * pubSub.subscribe('pageView', (data) => {
16129
+ * console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
16130
+ * });
16131
+ *
16132
+ * // Publish events
16133
+ * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
16134
+ * pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
16135
+ *
16136
+ * // Unsubscribe from an event
16137
+ * unsubscribeLogin();
16138
+ */
15277
16139
 
15278
16140
  class ResizeObserverService {
15279
16141
  constructor({ element, maxSize, minScale }) {
@@ -15343,36 +16205,6 @@ class ResizeObserverService {
15343
16205
  }
15344
16206
  }
15345
16207
 
15346
- function calculateScaleFactor(elementScale) {
15347
- // Step 1: Apply square root for non-linear scaling
15348
- // This creates a more gradual scaling effect, especially for larger changes
15349
- // For example:
15350
- // - elementScale of 0.25 (1/4 size) becomes 0.5
15351
- // - elementScale of 1 (unchanged) remains 1
15352
- // - elementScale of 4 (4x size) becomes 2
15353
- const baseFactor = Math.sqrt(elementScale);
15354
- // Step 2: Apply additional dampening to further soften the scaling effect
15355
- // The dampening factor (0.5) can be adjusted:
15356
- // - Lower values (closer to 0) make scaling more subtle
15357
- // - Higher values (closer to 1) make scaling more pronounced
15358
- const dampening = 0.35;
15359
- // Calculate the scaleFactor:
15360
- // 1. (baseFactor - 1) represents the change from the original size
15361
- // 2. Multiply by dampening to reduce the effect
15362
- // 3. Add 1 to center the scaling around the original size
15363
- // For example, if baseFactor is 2:
15364
- // scaleFactor = 1 + (2 - 1) * 0.5 = 1.5
15365
- const scaleFactor = 1 + (baseFactor - 1) * dampening;
15366
- // Step 3: Define the allowed range for the scale factor
15367
- // This ensures that the font size never changes too drastically
15368
- const minScale = 0.35; // Font will never be smaller than 50% of original
15369
- const maxScale = 1.5; // Font will never be larger than 150% of original
15370
- // Step 4: Clamp the scale factor to the defined range
15371
- // Math.min ensures the value doesn't exceed maxScale
15372
- // Math.max ensures the value isn't less than minScale
15373
- return Math.max(minScale, Math.min(maxScale, scaleFactor));
15374
- }
15375
-
15376
16208
  const CAROUSEL_COMPONENT_STYLE = ({ width, height, fluid }) => `
15377
16209
  :host {
15378
16210
  position: relative;
@@ -15387,11 +16219,13 @@ const CAROUSEL_COMPONENT_STYLE = ({ width, height, fluid }) => `
15387
16219
  position: relative;
15388
16220
  height: 100%;
15389
16221
  width: 100%;
16222
+ display: flex;
16223
+ transition: transform 0.5s ease-in-out;
15390
16224
  }
15391
16225
 
15392
16226
  .slide {
15393
- display: none;
15394
-
16227
+ flex: 0 0 100%;
16228
+ display: flex;
15395
16229
  justify-content: center;
15396
16230
  align-items: center;
15397
16231
  height: 100%;
@@ -15696,9 +16530,9 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
15696
16530
  renderSlides() {
15697
16531
  const slidesContainer = document.createElement('div');
15698
16532
  slidesContainer.className = 'slides';
15699
- this.slides.forEach((slide, index) => {
16533
+ this.slides.forEach((slide) => {
15700
16534
  const slideElement = document.createElement('div');
15701
- slideElement.className = `slide ${index === this.currentSlide ? 'active' : ''}`;
16535
+ slideElement.className = 'slide';
15702
16536
  if (slide instanceof HTMLElement) {
15703
16537
  slideElement.appendChild(slide);
15704
16538
  }
@@ -15777,10 +16611,9 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
15777
16611
  updateCarousel() {
15778
16612
  if (!this.slidesContainer)
15779
16613
  return;
15780
- const slides = Array.from(this.slidesContainer.children);
15781
- slides.forEach((slide, index) => {
15782
- slide.classList.toggle('active', index === this.currentSlide);
15783
- });
16614
+ // Calculate the translation distance based on current slide
16615
+ const translateX = -this.currentSlide * 100;
16616
+ this.slidesContainer.style.transform = `translateX(${translateX}%)`;
15784
16617
  this.updateDots();
15785
16618
  }
15786
16619
  updateDots() {
@@ -16204,12 +17037,13 @@ function spotHtmlStringToElement(htmlString) {
16204
17037
  spot.className = 'spot';
16205
17038
  spot.innerHTML = htmlString;
16206
17039
  Object.assign(spot.style, {
16207
- position: 'relative',
16208
17040
  display: 'block',
16209
17041
  width: '100%',
16210
17042
  height: '100%',
16211
17043
  margin: '0',
16212
17044
  padding: '0',
17045
+ containerType: 'inline-size',
17046
+ position: 'relative',
16213
17047
  });
16214
17048
  return spot;
16215
17049
  }
@@ -17079,7 +17913,6 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17079
17913
  box-sizing: border-box;
17080
17914
  color: ${textColor};
17081
17915
  cursor: pointer;
17082
- container-type: inline-size;
17083
17916
  }
17084
17917
 
17085
17918
  .${prefix}__text {
@@ -17095,7 +17928,7 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17095
17928
  .${prefix}__header {
17096
17929
  font-size: 24px;
17097
17930
  margin: 0;
17098
- font-family: "Cormorant";
17931
+ font-family: "Cormorant", system-ui;
17099
17932
  font-style: normal;
17100
17933
  font-weight: 300;
17101
17934
  line-height: normal;
@@ -17214,7 +18047,6 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17214
18047
  height: 100%;
17215
18048
  display: block;
17216
18049
  position: relative;
17217
- container-type: inline-size;
17218
18050
  }
17219
18051
 
17220
18052
  .${prefix}__content {
@@ -17405,15 +18237,20 @@ function rbHomepageHeroThreeTileTemplate(spot, config) {
17405
18237
  const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextColor = textColor, primaryImage, mobilePrimaryImage = primaryImage, }, { prefix }) => `
17406
18238
  <style>
17407
18239
  .${prefix} {
18240
+ width: 100%;
18241
+ height: 100%;
18242
+ background-color: transparent;
18243
+ cursor: pointer;
18244
+ position: relative;
18245
+ }
18246
+
18247
+ .${prefix}__content {
17408
18248
  width: 100%;
17409
18249
  height: 100%;
17410
18250
  display: flex;
17411
18251
  flex-direction: column-reverse;
17412
18252
  background-color: transparent;
17413
18253
  gap: 6px;
17414
- cursor: pointer;
17415
- container-type: inline-size;
17416
- position: relative;
17417
18254
  }
17418
18255
 
17419
18256
  .${prefix}__image {
@@ -17444,7 +18281,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17444
18281
  font-size: 18px;
17445
18282
  margin: 0;
17446
18283
  color: inherit;
17447
- font-family: "Cormorant";
18284
+ font-family: "Cormorant", system-ui;
17448
18285
  font-style: normal;
17449
18286
  font-weight: 700;
17450
18287
  line-height: normal;
@@ -17486,7 +18323,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17486
18323
  }
17487
18324
 
17488
18325
  @container (min-width: 768px) {
17489
- .${prefix} {
18326
+ .${prefix}__content {
17490
18327
  flex-direction: row;
17491
18328
  }
17492
18329
  .${prefix}__image {
@@ -17541,12 +18378,14 @@ function rbHomepageHeroTwoTileTemplate(spot, config) {
17541
18378
  ${GFONT_CORMORANT}
17542
18379
  ${STYLES$4(spot, config)}
17543
18380
  <div class="${prefix}">
17544
- <div class="${prefix}__text">
17545
- ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17546
- ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
17547
- ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
17548
- </div>
17549
- <div class="${prefix}__image"></div>
18381
+ <div class="${prefix}__content">
18382
+ <div class="${prefix}__text">
18383
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
18384
+ ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
18385
+ ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
18386
+ </div>
18387
+ <div class="${prefix}__image"></div>
18388
+ </div>
17550
18389
  </div>
17551
18390
  `;
17552
18391
  }
@@ -17569,12 +18408,10 @@ const STYLES$3 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17569
18408
  overflow: hidden;
17570
18409
  cursor: pointer;
17571
18410
  color: ${textColor};
17572
- container-type: inline-size;
17573
18411
  }
17574
18412
 
17575
18413
  .${prefix}__text {
17576
18414
  padding: 20px;
17577
- width: 70%;
17578
18415
  display: flex;
17579
18416
  flex-direction: column;
17580
18417
  justify-content: center;
@@ -17586,7 +18423,7 @@ const STYLES$3 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17586
18423
  color: inherit;
17587
18424
  margin: 0;
17588
18425
  font-size: 20px;
17589
- font-family: "Cormorant";
18426
+ font-family: "Cormorant", system-ui;
17590
18427
  font-style: normal;
17591
18428
  font-weight: 300;
17592
18429
  line-height: normal;
@@ -17705,7 +18542,6 @@ const STYLES$2 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
17705
18542
  background-size: cover;
17706
18543
  background-position: center;
17707
18544
  background-repeat: no-repeat;
17708
- container-type: inline-size;
17709
18545
  position: relative;
17710
18546
  }
17711
18547
 
@@ -17775,12 +18611,7 @@ const STYLES$1 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
17775
18611
  border-radius: 5px;
17776
18612
  overflow: hidden;
17777
18613
  cursor: pointer;
17778
- container-type: inline-size;
17779
- }
17780
-
17781
- .${prefix}__text {
17782
- padding: 10px;
17783
- width: 70%;
18614
+ position: relative;
17784
18615
  }
17785
18616
 
17786
18617
  .${prefix}__header {
@@ -17791,6 +18622,7 @@ const STYLES$1 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
17791
18622
  font-style: normal;
17792
18623
  font-weight: 400;
17793
18624
  margin: 0;
18625
+ padding: 10px;
17794
18626
  }
17795
18627
 
17796
18628
  @container (min-width: 640px) {
@@ -17808,9 +18640,7 @@ function rbSmallCategoryImageToutTemplate(spot, config) {
17808
18640
  ${GFONT_CORMORANT}
17809
18641
  ${STYLES$1(spot, config)}
17810
18642
  <div class="${prefix}">
17811
- <div class="${prefix}__text">
17812
- ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17813
- </div>
18643
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17814
18644
  </div>
17815
18645
  `;
17816
18646
  }
@@ -17825,7 +18655,6 @@ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primar
17825
18655
  display: flex;
17826
18656
  flex-direction: column;
17827
18657
  border-radius: 5px;
17828
- container-type: inline-size;
17829
18658
  }
17830
18659
 
17831
18660
  .${prefix}__image {
@@ -17961,94 +18790,198 @@ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
17961
18790
  return spotHtmlStringToElement(spotHtmlString);
17962
18791
  };
17963
18792
 
17964
- /**
17965
- * PubSub class
17966
- * Manages event subscriptions and publications
17967
- * @template IEventMap A record type defining the structure of events and their data
17968
- */
17969
- class PubSub {
18793
+ // For the moment, we will only focus on sites that use Google Analytics,
18794
+ // but we will add support for other analytics tools in the future.
18795
+ var AnalyticsTool;
18796
+ (function (AnalyticsTool) {
18797
+ AnalyticsTool["GoogleAnalytics"] = "google-analytics";
18798
+ AnalyticsTool["Other"] = "Other";
18799
+ })(AnalyticsTool || (AnalyticsTool = {}));
18800
+
18801
+ class DataLayerMonitor {
18802
+ constructor() {
18803
+ if (!window.dataLayer) {
18804
+ return;
18805
+ }
18806
+ this.originalPush = window.dataLayer.push;
18807
+ }
18808
+ static getInstance() {
18809
+ if (!DataLayerMonitor.instance) {
18810
+ DataLayerMonitor.instance = new DataLayerMonitor();
18811
+ }
18812
+ return DataLayerMonitor.instance;
18813
+ }
18814
+ setListener(listener) {
18815
+ this.listener = listener;
18816
+ }
18817
+ start() {
18818
+ window.dataLayer.push = (...args) => {
18819
+ const result = this.originalPush.apply(window.dataLayer, args);
18820
+ const pushedEvent = args[0];
18821
+ if (this.listener) {
18822
+ const normalizedData = this.cleanEventData(pushedEvent);
18823
+ if (normalizedData) {
18824
+ this.listener(normalizedData);
18825
+ }
18826
+ }
18827
+ return result;
18828
+ };
18829
+ }
18830
+ cleanEventData(data) {
18831
+ const eventName = getEventTypeFromRawEvent(data.event);
18832
+ if (!eventName) {
18833
+ return null;
18834
+ }
18835
+ const productIds = extractDeepIds(data.value);
18836
+ return {
18837
+ event: eventName,
18838
+ productIds,
18839
+ };
18840
+ }
18841
+ stop() {
18842
+ if (this.originalPush) {
18843
+ window.dataLayer.push = this.originalPush;
18844
+ }
18845
+ this.listener = undefined;
18846
+ }
18847
+ }
18848
+
18849
+ // @TODO: Add support for user to push events to our own data layer, if they don't use any analytics tool.
18850
+ // window.rmnDataLayer = window.rmnDataLayer || [];
18851
+ class MonitorService {
17970
18852
  constructor() {
17971
- /**
17972
- * Object to store subscribers for each event type
17973
- */
17974
- this.subscribers = {};
18853
+ const analyticsTool = this.detectAnalyticsTool();
18854
+ switch (analyticsTool) {
18855
+ case AnalyticsTool.GoogleAnalytics:
18856
+ this.implementedMonitor = DataLayerMonitor.getInstance();
18857
+ break;
18858
+ case AnalyticsTool.Other:
18859
+ default:
18860
+ console.warn('This site uses an unsupported analytics tool.');
18861
+ break;
18862
+ }
18863
+ if (analyticsTool === AnalyticsTool.Other) {
18864
+ return;
18865
+ }
18866
+ this.pubSubService = PubsubService.getInstance();
18867
+ this.localStorageService = LocalStorageService.getInstance();
17975
18868
  }
17976
18869
  static getInstance() {
17977
- if (!PubSub.instance) {
17978
- PubSub.instance = new PubSub();
18870
+ if (!MonitorService.instance) {
18871
+ MonitorService.instance = new MonitorService();
17979
18872
  }
17980
- return PubSub.instance;
18873
+ return MonitorService.instance;
17981
18874
  }
17982
- /**
17983
- * Subscribe to an event
17984
- * @param eventType - The type of event to subscribe to
17985
- * @param callback - The function to be called when the event is published
17986
- * @returns A function to unsubscribe from the event
17987
- *
17988
- * @Example:
17989
- * const unsubscribe = pubSub.subscribe('userLogin', (data) => {
17990
- * console.log(`User ${data.username} logged in`);
17991
- * });
17992
- */
17993
- subscribe(eventType, callback) {
17994
- if (!this.subscribers[eventType]) {
17995
- this.subscribers[eventType] = [];
18875
+ start() {
18876
+ if (!this.implementedMonitor)
18877
+ return;
18878
+ this.implementedMonitor.setListener(async (eventData) => {
18879
+ var _a;
18880
+ await this.matchAndFireEvent(eventData, (_a = this.localStorageService) === null || _a === void 0 ? void 0 : _a.getSpots());
18881
+ });
18882
+ this.implementedMonitor.start();
18883
+ }
18884
+ async matchAndFireEvent(eventData, spots) {
18885
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
18886
+ if (!spots)
18887
+ return;
18888
+ const eventProductIds = new Set(eventData.productIds);
18889
+ for (const spot of Object.values(spots)) {
18890
+ if (!spot.productIds.length)
18891
+ continue;
18892
+ const hasCommonProductIds = spot.productIds.find((productId) => eventProductIds.has(productId));
18893
+ if (hasCommonProductIds) {
18894
+ switch (eventData.event) {
18895
+ case RMN_SPOT_EVENT.ADD_TO_CART:
18896
+ await this.fireAndPublishSpotEvent({
18897
+ spotEvent: RMN_SPOT_EVENT.ADD_TO_CART,
18898
+ eventUrl: (_b = (_a = spot.events.find((event) => event.event === RMN_SPOT_EVENT.ADD_TO_CART)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
18899
+ placementId: spot.placementId,
18900
+ spotId: spot.spotId,
18901
+ });
18902
+ break;
18903
+ case RMN_SPOT_EVENT.REMOVE_FROM_CART:
18904
+ await this.fireAndPublishSpotEvent({
18905
+ spotEvent: RMN_SPOT_EVENT.REMOVE_FROM_CART,
18906
+ eventUrl: (_d = (_c = spot.events.find((event) => event.event === RMN_SPOT_EVENT.REMOVE_FROM_CART)) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : '',
18907
+ placementId: spot.placementId,
18908
+ spotId: spot.spotId,
18909
+ });
18910
+ break;
18911
+ case RMN_SPOT_EVENT.PURCHASE:
18912
+ await this.fireAndPublishSpotEvent({
18913
+ spotEvent: RMN_SPOT_EVENT.PURCHASE,
18914
+ eventUrl: (_f = (_e = spot.events.find((event) => event.event === RMN_SPOT_EVENT.PURCHASE)) === null || _e === void 0 ? void 0 : _e.url) !== null && _f !== void 0 ? _f : '',
18915
+ placementId: spot.placementId,
18916
+ spotId: spot.spotId,
18917
+ });
18918
+ break;
18919
+ case RMN_SPOT_EVENT.ADD_TO_WISHLIST:
18920
+ await this.fireAndPublishSpotEvent({
18921
+ spotEvent: RMN_SPOT_EVENT.ADD_TO_WISHLIST,
18922
+ eventUrl: (_h = (_g = spot.events.find((event) => event.event === RMN_SPOT_EVENT.ADD_TO_WISHLIST)) === null || _g === void 0 ? void 0 : _g.url) !== null && _h !== void 0 ? _h : '',
18923
+ placementId: spot.placementId,
18924
+ spotId: spot.spotId,
18925
+ });
18926
+ break;
18927
+ case RMN_SPOT_EVENT.BUY_NOW:
18928
+ await this.fireAndPublishSpotEvent({
18929
+ spotEvent: RMN_SPOT_EVENT.BUY_NOW,
18930
+ eventUrl: (_k = (_j = spot.events.find((event) => event.event === RMN_SPOT_EVENT.BUY_NOW)) === null || _j === void 0 ? void 0 : _j.url) !== null && _k !== void 0 ? _k : '',
18931
+ placementId: spot.placementId,
18932
+ spotId: spot.spotId,
18933
+ });
18934
+ break;
18935
+ }
18936
+ }
17996
18937
  }
17997
- this.subscribers[eventType].push(callback);
17998
- // Return an unsubscribe function
17999
- return () => {
18000
- this.subscribers[eventType] = this.subscribers[eventType].filter((cb) => cb !== callback);
18001
- };
18002
18938
  }
18003
- /**
18004
- * Publish an event
18005
- * @param eventType - The type of event to publish
18006
- * @param data - The data to be passed to the event subscribers
18007
- *
18008
- * @Example:
18009
- * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
18010
- */
18011
- publish(eventType, data) {
18012
- if (!this.subscribers[eventType]) {
18939
+ async fireAndPublishSpotEvent({ spotEvent, eventUrl, placementId, spotId, }) {
18940
+ await fireEvent({
18941
+ event: spotEvent,
18942
+ eventUrl,
18943
+ });
18944
+ if (!this.pubSubService)
18013
18945
  return;
18946
+ this.pubSubService.publish(RMN_EVENT.SPOT_EVENT, {
18947
+ eventType: spotEvent,
18948
+ placementId,
18949
+ spotId,
18950
+ });
18951
+ }
18952
+ detectAnalyticsTool() {
18953
+ let analyticsTool = AnalyticsTool.Other;
18954
+ // Check for Google Analytics
18955
+ if (typeof window.ga !== 'undefined') {
18956
+ analyticsTool = AnalyticsTool.GoogleAnalytics;
18014
18957
  }
18015
- this.subscribers[eventType].forEach((callback) => callback(data));
18958
+ // Check for Google Analytics 4
18959
+ if (typeof window.gtag !== 'undefined') {
18960
+ analyticsTool = AnalyticsTool.GoogleAnalytics;
18961
+ }
18962
+ // Check for Google Tag Manager
18963
+ if (typeof window.google_tag_manager !== 'undefined') {
18964
+ analyticsTool = AnalyticsTool.GoogleAnalytics;
18965
+ }
18966
+ // @TODO: Add support for other analytics tools
18967
+ // Check for Heap Analytics
18968
+ // Check for Mixpanel
18969
+ // Check for Woopra
18970
+ // Check for Segment
18971
+ // Check for Amplitude
18972
+ return analyticsTool;
18016
18973
  }
18017
18974
  }
18018
- /**
18019
- * Usage Example:
18020
- *
18021
- * interface IEventMap {
18022
- * userLogin: { username: string; timestamp: number };
18023
- * pageView: { url: string; timestamp: number };
18024
- * }
18025
- *
18026
- * const pubSub = new PubSub<IEventMap>();
18027
- *
18028
- * // Subscribe to events
18029
- * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
18030
- * console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
18031
- * });
18032
- *
18033
- * pubSub.subscribe('pageView', (data) => {
18034
- * console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
18035
- * });
18036
- *
18037
- * // Publish events
18038
- * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
18039
- * pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
18040
- *
18041
- * // Unsubscribe from an event
18042
- * unsubscribeLogin();
18043
- */
18044
18975
 
18045
18976
  class EventService {
18046
18977
  constructor() {
18047
- this.pubSub = PubSub.getInstance();
18048
- this.localStorage = LocalStorage.getInstance();
18978
+ this.pubSubService = PubsubService.getInstance();
18979
+ this.localStorageService = LocalStorageService.getInstance();
18049
18980
  this.activeSpots = new Map();
18050
18981
  this.spotStates = new Map();
18051
18982
  this.intersectionObserver = new IntersectionObserverService();
18983
+ // Start the user monitor, which will track and check user interactions
18984
+ MonitorService.getInstance().start();
18052
18985
  }
18053
18986
  static getInstance() {
18054
18987
  if (!EventService.instance) {
@@ -18057,16 +18990,16 @@ class EventService {
18057
18990
  return EventService.instance;
18058
18991
  }
18059
18992
  subscribe(eventType, callback) {
18060
- return this.pubSub.subscribe(eventType, callback);
18993
+ return this.pubSubService.subscribe(eventType, callback);
18061
18994
  }
18062
18995
  publish(eventType, data) {
18063
- this.pubSub.publish(eventType, data);
18996
+ this.pubSubService.publish(eventType, data);
18064
18997
  }
18065
18998
  registerSpot(params) {
18066
18999
  const { placementId, spot, spotElement } = params;
18067
19000
  this.activeSpots.set(placementId, { spotElement });
18068
19001
  // Fire impression event
18069
- this.fireImpressionEvent(placementId, spot, spotElement);
19002
+ this.fireImpressionEvent(placementId, spot);
18070
19003
  // Handle intersection observer
18071
19004
  this.handleIntersectionObserver(placementId, spot, spotElement);
18072
19005
  // Attach click event listener
@@ -18141,30 +19074,42 @@ class EventService {
18141
19074
  },
18142
19075
  };
18143
19076
  }
18144
- this.spotStates.set(placementId, { ...currentState, ...updates });
19077
+ const merged = this.deepMerge(currentState, updates);
19078
+ this.spotStates.set(placementId, merged);
18145
19079
  if (publish) {
18146
- this.pubSub.publish(RMN_SPOT_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
19080
+ this.pubSubService.publish(RMN_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
18147
19081
  }
18148
19082
  }
18149
- async handleClick({ placementId, spot, spotElement, }) {
19083
+ deepMerge(current, updates) {
19084
+ return {
19085
+ identifier: updates.identifier
19086
+ ? { ...current.identifier, ...updates.identifier }
19087
+ : current.identifier,
19088
+ dom: updates.dom ? { ...current.dom, ...updates.dom } : current.dom,
19089
+ state: updates.state ? { ...current.state, ...updates.state } : current.state,
19090
+ displayConfig: updates.displayConfig
19091
+ ? { ...current.displayConfig, ...updates.displayConfig }
19092
+ : current.displayConfig,
19093
+ };
19094
+ }
19095
+ async handleClick({ placementId, spot }) {
18150
19096
  var _a, _b, _c;
18151
- // Publish click event
18152
- this.pubSub.publish(RMN_SPOT_EVENT.CLICK, {
19097
+ this.pubSubService.publish(RMN_EVENT.SPOT_EVENT, {
19098
+ eventType: RMN_SPOT_EVENT.CLICK,
18153
19099
  placementId,
18154
19100
  spotId: spot.id,
18155
- spotElement,
18156
19101
  });
18157
- // Fire click event
18158
- await this.fireEvent({
19102
+ await fireEvent({
18159
19103
  event: RMN_SPOT_EVENT.CLICK,
18160
19104
  eventUrl: (_b = (_a = spot.events.find((event) => event.event === RMN_SPOT_EVENT.CLICK)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
18161
19105
  });
18162
19106
  // Save spot to local storage for event tracking
18163
- this.localStorage.setSpot(spot.id, {
19107
+ this.localStorageService.setSpot(spot.id, {
19108
+ placementId,
18164
19109
  spotId: spot.id,
18165
19110
  spotType: spot.spot,
18166
19111
  events: spot.events,
18167
- productIds: (_c = spot.productIds) !== null && _c !== void 0 ? _c : [1, 'GROUPING-12345', 'DAN-12345', 131398103],
19112
+ productIds: (_c = spot.productIds) !== null && _c !== void 0 ? _c : [],
18168
19113
  });
18169
19114
  }
18170
19115
  handleIntersectionObserver(placementId, _spot, spotElement) {
@@ -18179,51 +19124,20 @@ class EventService {
18179
19124
  };
18180
19125
  this.intersectionObserver.observe(spotElement, spotIsVisibleCallback);
18181
19126
  }
18182
- fireImpressionEvent(placementId, spot, spotElement) {
18183
- this.pubSub.publish(RMN_SPOT_EVENT.IMPRESSION, {
19127
+ fireImpressionEvent(placementId, spot) {
19128
+ this.pubSubService.publish(RMN_EVENT.SPOT_EVENT, {
19129
+ eventType: RMN_SPOT_EVENT.IMPRESSION,
18184
19130
  placementId,
18185
19131
  spotId: spot.id,
18186
- spotElement,
18187
19132
  });
18188
19133
  (async () => {
18189
19134
  var _a, _b;
18190
- await this.fireEvent({
19135
+ await fireEvent({
18191
19136
  event: RMN_SPOT_EVENT.IMPRESSION,
18192
19137
  eventUrl: (_b = (_a = spot.events.find((event) => event.event === RMN_SPOT_EVENT.IMPRESSION)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
18193
19138
  });
18194
19139
  })();
18195
19140
  }
18196
- /**
18197
- * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
18198
- *
18199
- * @param {IFireEventParams} params - The parameters for firing the event.
18200
- * @param {RMN_SPOT_EVENT} params.event - The event type.
18201
- * @param {string} params.eventUrl - The URL to which the event is sent.
18202
- * @returns {Promise<void>} - A promise that resolves when the event is fired.
18203
- */
18204
- async fireEvent({ event, eventUrl }) {
18205
- const didFireEvent = navigator.sendBeacon(eventUrl);
18206
- if (didFireEvent && event === RMN_SPOT_EVENT.CLICK) {
18207
- window.location.href = this.getRedirectUrlFromPayload(eventUrl);
18208
- }
18209
- }
18210
- /**
18211
- * Extracts and decodes a URL from a base64-encoded query parameter.
18212
- *
18213
- * @param {string} url - The URL containing the base64-encoded query parameter.
18214
- * @returns {string} - The decoded URL or an empty string if decoding fails.
18215
- */
18216
- getRedirectUrlFromPayload(url) {
18217
- var _a, _b;
18218
- const base64String = (_a = new URL(url).searchParams.get('e')) !== null && _a !== void 0 ? _a : '';
18219
- try {
18220
- const data = JSON.parse(atob(base64String));
18221
- return (_b = data.ur) !== null && _b !== void 0 ? _b : '';
18222
- }
18223
- catch (_c) {
18224
- return '';
18225
- }
18226
- }
18227
19141
  }
18228
19142
 
18229
19143
  const SELECTION_API_PATH = '/spots/selection';
@@ -18256,176 +19170,6 @@ class SelectionService extends BaseApi {
18256
19170
  }
18257
19171
  }
18258
19172
 
18259
- const SPOT_EVENTS_EXAMPLE = [
18260
- {
18261
- event: RMN_SPOT_EVENT.CLICK,
18262
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwidXIiOm51bGx9&s=hWz37kbxi_u95EVNn2aoQhc5Aas',
18263
- },
18264
- {
18265
- event: RMN_SPOT_EVENT.IMPRESSION,
18266
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiYmEiOjEsImZxIjowfQ&s=djoysjCimurf-5T11AlNAwwLSS8',
18267
- },
18268
- {
18269
- event: RMN_SPOT_EVENT.PURCHASE,
18270
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjU5fQ&s=AAPAw-3SfZ0JMzjEGFSwt9L-2S4',
18271
- },
18272
- {
18273
- event: RMN_SPOT_EVENT.ADD_TO_CART,
18274
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYwfQ&s=uzQFcjgL7m9XqUG8FvTPVN5YkZY',
18275
- },
18276
- {
18277
- event: RMN_SPOT_EVENT.ADD_TO_WISHLIST,
18278
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYzfQ&s=m3ISU_iIy-OFtXrTKpI6cJAEC0k',
18279
- },
18280
- {
18281
- event: RMN_SPOT_EVENT.BUY_NOW,
18282
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjY5fQ&s=l6MOscQC-q-FkC2Ksd7w6jjySCQ',
18283
- },
18284
- ];
18285
- const RB_SPOTS_SELECTION_EXAMPLE = {
18286
- rbHomepageHeroFullImage: [
18287
- {
18288
- id: '111111_111111',
18289
- spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18290
- variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18291
- width: 1140,
18292
- height: 640,
18293
- header: 'Artisanal Craft Beer Collection',
18294
- description: 'Discover our curated selection of small-batch, flavor-packed craft beers.',
18295
- ctaText: 'Explore the Collection',
18296
- textColor: '#ffffff',
18297
- ctaTextColor: '#ffffff',
18298
- primaryImage: 'https://placehold.co/1140x640/png?text=Craft+Beer+Collection',
18299
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Craft+Beer',
18300
- events: SPOT_EVENTS_EXAMPLE,
18301
- },
18302
- {
18303
- id: '222222_222222',
18304
- spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18305
- variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18306
- width: 1140,
18307
- height: 640,
18308
- header: 'Summer Wine Spectacular',
18309
- description: 'Refresh your palate with our handpicked selection of crisp, summer wines.',
18310
- ctaText: 'Shop Summer Wines',
18311
- textColor: '#000000',
18312
- ctaTextColor: '#ffffff',
18313
- primaryImage: 'https://placehold.co/1140x640/png?text=Summer+Wines',
18314
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Summer+Wines',
18315
- events: SPOT_EVENTS_EXAMPLE,
18316
- },
18317
- ],
18318
- rbHomepageHeroTwoTile: [
18319
- {
18320
- id: '333333_333333',
18321
- spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
18322
- variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
18323
- width: 1140,
18324
- height: 640,
18325
- header: 'Whiskey Wonderland',
18326
- description: 'Embark on a journey through our premium whiskey selection.',
18327
- ctaText: 'Discover Whiskeys',
18328
- textColor: '#ffffff',
18329
- backgroundColor: '#2c1a05',
18330
- ctaTextColor: '#2c1a05',
18331
- primaryImage: 'https://placehold.co/1140x640/png?text=Whiskey+Collection',
18332
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Whiskey',
18333
- events: SPOT_EVENTS_EXAMPLE,
18334
- },
18335
- ],
18336
- rbHomepageHeroThreeTile: [
18337
- {
18338
- id: '444444_444444',
18339
- spot: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
18340
- variant: RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
18341
- width: 1140,
18342
- height: 640,
18343
- header: 'Cocktail Essentials',
18344
- description: 'Stock your bar with premium spirits and mixers for the perfect cocktail.',
18345
- ctaText: 'Build Your Bar',
18346
- textColor: '#ffffff',
18347
- backgroundColor: '#1a3c4d',
18348
- ctaTextColor: '#1a3c4d',
18349
- primaryImage: 'https://placehold.co/1140x640/png?text=Cocktail+Spirits',
18350
- secondaryImage: 'https://placehold.co/1140x640/png?text=Cocktail+Mixers',
18351
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Cocktail+Kit',
18352
- mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Cocktail+Mixers',
18353
- events: SPOT_EVENTS_EXAMPLE,
18354
- },
18355
- ],
18356
- rbLargeCategoryImageTout: [
18357
- {
18358
- id: '555555_555555',
18359
- spot: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
18360
- variant: RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
18361
- width: 468,
18362
- height: 410,
18363
- header: 'Rare & Limited Edition',
18364
- description: 'Discover our collection of hard-to-find and limited release spirits.',
18365
- textColor: '#ffffff',
18366
- ctaTextColor: '#ffffff',
18367
- primaryImage: 'https://placehold.co/468x410/png?text=Rare+Spirits',
18368
- mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Rare+Spirits',
18369
- ctaText: 'Shop Rare Spirits',
18370
- events: SPOT_EVENTS_EXAMPLE,
18371
- },
18372
- ],
18373
- rbSmallDiscoverTout: [
18374
- {
18375
- id: '666666_666666',
18376
- spot: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
18377
- variant: RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
18378
- width: 224,
18379
- height: 378,
18380
- header: 'Château Margaux 2015 Bordeaux',
18381
- textColor: '#ffffff',
18382
- primaryImage: 'https://placehold.co/224x378/png?text=Château+Margaux',
18383
- mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Château+Margaux',
18384
- events: SPOT_EVENTS_EXAMPLE,
18385
- },
18386
- ],
18387
- rbSmallCategoryImageTout: [
18388
- {
18389
- id: '777777_777777',
18390
- spot: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
18391
- variant: RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
18392
- width: 224,
18393
- height: 410,
18394
- header: 'Japanese Sake',
18395
- textColor: '#ffffff',
18396
- primaryImage: 'https://placehold.co/224x410/png?text=Japanese+Sake',
18397
- mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Japanese+Sake',
18398
- events: SPOT_EVENTS_EXAMPLE,
18399
- },
18400
- ],
18401
- rbCollectionBannerWithoutTextBlock: [
18402
- {
18403
- id: '888888_888888',
18404
- spot: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
18405
- variant: RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
18406
- width: 887,
18407
- height: 344,
18408
- primaryImage: 'https://placehold.co/887x344/png?text=Summer+Cocktails',
18409
- mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Summer+Cocktails',
18410
- events: SPOT_EVENTS_EXAMPLE,
18411
- },
18412
- ],
18413
- rbNavigationBanner: [
18414
- {
18415
- id: '999999_999999',
18416
- spot: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
18417
- variant: RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
18418
- width: 440,
18419
- height: 220,
18420
- header: 'Explore Tequilas',
18421
- textColor: '#ffffff',
18422
- primaryImage: 'https://placehold.co/440x220/png?text=Tequila+Collection',
18423
- mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Tequila+Collection',
18424
- events: SPOT_EVENTS_EXAMPLE,
18425
- },
18426
- ],
18427
- };
18428
-
18429
19173
  class LiquidCommerceRmnClient {
18430
19174
  constructor(auth) {
18431
19175
  this.selectionService = SelectionService.getInstance(auth);
@@ -18439,7 +19183,7 @@ class LiquidCommerceRmnClient {
18439
19183
  *
18440
19184
  * @param {ISpotSelectionParams} params - Spots selection parameters.
18441
19185
  *
18442
- * @return {Promise<ISpots | {error : string}>} - The spots response object.
19186
+ * @return {Promise<ISpots | { error : string }>} - The spots response object.
18443
19187
  */
18444
19188
  async spotSelection(params) {
18445
19189
  return this.selectionService.spotSelection(params);
@@ -18453,13 +19197,19 @@ class LiquidCommerceRmnClient {
18453
19197
  */
18454
19198
  async injectSpotElement(params) {
18455
19199
  var _a;
19200
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
19201
+ console.warn('LiquidCommerce Rmn Sdk: Methods which create elements are only available in browser environments.');
19202
+ return;
19203
+ }
18456
19204
  const config = params.config;
18457
19205
  let inject = params.inject;
18458
19206
  if (!inject.length) {
19207
+ // Handle no spots error state
18459
19208
  this.eventService.handleSpotState('all', {
18460
19209
  state: {
18461
19210
  error: 'No spot elements provided for injection.',
18462
19211
  loading: false,
19212
+ mounted: false,
18463
19213
  },
18464
19214
  });
18465
19215
  return;
@@ -18478,9 +19228,12 @@ class LiquidCommerceRmnClient {
18478
19228
  // const response = await this.useSpotSelectionExample(inject);
18479
19229
  // Handle the response
18480
19230
  if (typeof response === 'object' && 'error' in response) {
19231
+ // Handle request error state
18481
19232
  this.eventService.handleSpotState('all', {
18482
19233
  state: {
18483
19234
  error: response.error,
19235
+ mounted: false,
19236
+ loading: false,
18484
19237
  },
18485
19238
  });
18486
19239
  return;
@@ -18489,9 +19242,11 @@ class LiquidCommerceRmnClient {
18489
19242
  const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
18490
19243
  const spots = response[item.placementId];
18491
19244
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
19245
+ // Handle no spots found error state
18492
19246
  this.eventService.handleSpotState(item.placementId, {
18493
19247
  state: {
18494
19248
  error: `No spots found for type "${item.spotType}".`,
19249
+ mounted: false,
18495
19250
  loading: false,
18496
19251
  },
18497
19252
  });
@@ -18500,9 +19255,11 @@ class LiquidCommerceRmnClient {
18500
19255
  const placementId = item.placementId.replace('#', '');
18501
19256
  const placement = document.getElementById(placementId);
18502
19257
  if (!placement) {
19258
+ // Handle placement not found error state
18503
19259
  this.eventService.handleSpotState(item.placementId, {
18504
19260
  state: {
18505
19261
  error: `Placement not found for id "${placementId}".`,
19262
+ mounted: false,
18506
19263
  loading: false,
18507
19264
  },
18508
19265
  });
@@ -18513,16 +19270,18 @@ class LiquidCommerceRmnClient {
18513
19270
  placement.removeAttribute('class');
18514
19271
  Object.assign(placement.style, {
18515
19272
  width: '100%',
18516
- height: 'auto',
19273
+ height: '100%',
18517
19274
  display: 'flex',
18518
19275
  justifyContent: 'center',
18519
19276
  });
19277
+ // Handle single spot
18520
19278
  if (spots.length === 1) {
18521
19279
  const isInjected = this.injectOneSpotElement(item, placement, spots[0], itemConfig);
18522
19280
  if (!isInjected) {
18523
19281
  continue;
18524
19282
  }
18525
19283
  }
19284
+ // Handle multiple spots (carousel)
18526
19285
  if (spots.length > 1) {
18527
19286
  const isInjected = this.injectCarouselSpotElement(placement, spots, itemConfig);
18528
19287
  if (!isInjected) {
@@ -18566,18 +19325,24 @@ class LiquidCommerceRmnClient {
18566
19325
  const carouselSlides = [];
18567
19326
  for (const spotItem of spots) {
18568
19327
  this.eventService.handleSpotState(placement.id, {
19328
+ identifier: {
19329
+ placementId: placement.id,
19330
+ spotType: spotItem.spot,
19331
+ spotId: spotItem.id,
19332
+ },
18569
19333
  displayConfig: {
19334
+ isSingleItem: false,
18570
19335
  isCarousel: true,
18571
19336
  isCarouselItem: true,
18572
- isSingleItem: false,
18573
19337
  },
18574
- }, false);
19338
+ });
18575
19339
  const spot = this.elementService.overrideSpotColors(spotItem, config === null || config === void 0 ? void 0 : config.colors);
18576
19340
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spot, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18577
19341
  if (!content) {
18578
19342
  this.eventService.handleSpotState(placement.id, {
18579
19343
  state: {
18580
19344
  error: `Failed to inject carousel spot item element. Could not create element for type "${spot.spot}".`,
19345
+ mounted: false,
18581
19346
  loading: false,
18582
19347
  },
18583
19348
  });
@@ -18610,6 +19375,7 @@ class LiquidCommerceRmnClient {
18610
19375
  this.eventService.handleSpotState(placement.id, {
18611
19376
  state: {
18612
19377
  error: `Failed to inject spot carousel element. Could not create spot carousel element.`,
19378
+ mounted: false,
18613
19379
  loading: false,
18614
19380
  },
18615
19381
  });
@@ -18619,10 +19385,12 @@ class LiquidCommerceRmnClient {
18619
19385
  this.eventService.handleSpotState(placement.id, {
18620
19386
  dom: {
18621
19387
  spotElement: carouselElement,
19388
+ visibleOnViewport: false,
18622
19389
  },
18623
19390
  state: {
18624
19391
  mounted: true,
18625
19392
  loading: false,
19393
+ error: undefined,
18626
19394
  },
18627
19395
  });
18628
19396
  return true;
@@ -18639,18 +19407,25 @@ class LiquidCommerceRmnClient {
18639
19407
  */
18640
19408
  injectOneSpotElement(injectItem, placement, spot, config) {
18641
19409
  var _a;
18642
- const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
18643
19410
  this.eventService.handleSpotState(injectItem.placementId, {
19411
+ identifier: {
19412
+ placementId: injectItem.placementId,
19413
+ spotType: injectItem.spotType,
19414
+ spotId: spot.id,
19415
+ },
18644
19416
  displayConfig: {
18645
19417
  isSingleItem: true,
19418
+ isCarousel: false,
19419
+ isCarouselItem: false,
18646
19420
  },
18647
- }, false);
18648
- // Create the spot template element
19421
+ });
19422
+ const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
18649
19423
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18650
19424
  if (!content) {
18651
19425
  this.eventService.handleSpotState(injectItem.placementId, {
18652
19426
  state: {
18653
19427
  error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
19428
+ mounted: false,
18654
19429
  loading: false,
18655
19430
  },
18656
19431
  });
@@ -18671,6 +19446,7 @@ class LiquidCommerceRmnClient {
18671
19446
  this.eventService.handleSpotState(injectItem.placementId, {
18672
19447
  state: {
18673
19448
  error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
19449
+ mounted: false,
18674
19450
  loading: false,
18675
19451
  },
18676
19452
  });
@@ -18685,10 +19461,12 @@ class LiquidCommerceRmnClient {
18685
19461
  this.eventService.handleSpotState(injectItem.placementId, {
18686
19462
  dom: {
18687
19463
  spotElement,
19464
+ visibleOnViewport: false,
18688
19465
  },
18689
19466
  state: {
18690
19467
  mounted: true,
18691
19468
  loading: false,
19469
+ error: undefined,
18692
19470
  },
18693
19471
  });
18694
19472
  return true;
@@ -18709,6 +19487,8 @@ class LiquidCommerceRmnClient {
18709
19487
  this.eventService.handleSpotState(item.placementId, {
18710
19488
  state: {
18711
19489
  error: `Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`,
19490
+ mounted: false,
19491
+ loading: false,
18712
19492
  },
18713
19493
  });
18714
19494
  return false;
@@ -18724,6 +19504,8 @@ class LiquidCommerceRmnClient {
18724
19504
  this.eventService.handleSpotState(item.placementId, {
18725
19505
  state: {
18726
19506
  error: `Invalid spot type (${item.spotType}) found. Please provide a valid spot type for each spot element.`,
19507
+ mounted: false,
19508
+ loading: false,
18727
19509
  },
18728
19510
  });
18729
19511
  continue;
@@ -18732,6 +19514,7 @@ class LiquidCommerceRmnClient {
18732
19514
  }
18733
19515
  return newInject;
18734
19516
  }
19517
+ // Initialize spots with loading state and identifiers
18735
19518
  updateSpotsState(inject) {
18736
19519
  for (const item of inject) {
18737
19520
  this.eventService.handleSpotState(item.placementId, {
@@ -18741,6 +19524,8 @@ class LiquidCommerceRmnClient {
18741
19524
  },
18742
19525
  state: {
18743
19526
  loading: true,
19527
+ mounted: false,
19528
+ error: undefined,
18744
19529
  },
18745
19530
  });
18746
19531
  }
@@ -18832,4 +19617,4 @@ function RmnCreateSpotElement(spot, config) {
18832
19617
  });
18833
19618
  }
18834
19619
 
18835
- export { LiquidCommerceRmnClient, RMN_ENV, RMN_FILTER_PROPERTIES, RMN_SPOT_EVENT, RMN_SPOT_TYPE, RmnClient, RmnCreateSpotElement, RmnEventManager };
19620
+ export { LiquidCommerceRmnClient, RMN_ENV, RMN_EVENT, RMN_FILTER_PROPERTIES, RMN_SPOT_EVENT, RMN_SPOT_TYPE, RmnClient, RmnCreateSpotElement, RmnEventManager };