@blotoutio/providers-snapchat-sdk 1.68.1 → 1.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/index.cjs.js +742 -14
  2. package/index.js +742 -14
  3. package/index.mjs +742 -14
  4. package/package.json +1 -1
package/index.js CHANGED
@@ -37,7 +37,725 @@ var ProvidersSnapchatSdk = (function () {
37
37
  'CUSTOM_EVENT_5',
38
38
  ]);
39
39
 
40
- // eslint-disable-next-line @nx/enforce-module-boundaries
40
+ const keyPrefix = `_worker`;
41
+
42
+ const getProductIdFromMapping = (item, productIdMapping) => {
43
+ if (productIdMapping === '1' && item['variantId']) {
44
+ return item['variantId'];
45
+ }
46
+ if (productIdMapping === '2' && item['sku']) {
47
+ return item['sku'];
48
+ }
49
+ return item['id'];
50
+ };
51
+
52
+ const initKey = `${keyPrefix}StoreMultiple`;
53
+ const getData = (destination, persistType, key = initKey) => {
54
+ let data;
55
+ if (persistType === 'session') {
56
+ data = getSession(key);
57
+ }
58
+ else {
59
+ data = getLocal(key);
60
+ }
61
+ return (data === null || data === void 0 ? void 0 : data[destination]) || {};
62
+ };
63
+ const getLocal = (key) => {
64
+ try {
65
+ if (!localStorage) {
66
+ return {};
67
+ }
68
+ const data = localStorage.getItem(key);
69
+ if (!data) {
70
+ return {};
71
+ }
72
+ return JSON.parse(data) || {};
73
+ }
74
+ catch {
75
+ return {};
76
+ }
77
+ };
78
+ const getSession = (key) => {
79
+ try {
80
+ if (!sessionStorage) {
81
+ return {};
82
+ }
83
+ const data = sessionStorage.getItem(key);
84
+ if (!data) {
85
+ return {};
86
+ }
87
+ return JSON.parse(data) || {};
88
+ }
89
+ catch {
90
+ return {};
91
+ }
92
+ };
93
+
94
+ /**
95
+ * Known ad-network click ID query parameters and the human-readable provider
96
+ * label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
97
+ * and by the analytics API to classify paid-media touch sessions.
98
+ *
99
+ * Keep this list in sync with `defaultParams` in queryParams.ts when new
100
+ * click ID providers are added.
101
+ */
102
+ const CLICK_IDS = [
103
+ { param: 'fbclid', label: 'Facebook' }, // Facebook Ads
104
+ { param: 'gclid', label: 'Google' }, // Google Ads (click)
105
+ { param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
106
+ { param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
107
+ { param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
108
+ { param: 'ttclid', label: 'TikTok' }, // TikTok Ads
109
+ { param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
110
+ { param: 'epik', label: 'Pinterest' }, // Pinterest Ads
111
+ { param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
112
+ { param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
113
+ { param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
114
+ { param: 'aleid', label: 'AppLovin' }, // AppLovin
115
+ { param: 'tabclid', label: 'Taboola' }, // Taboola
116
+ { param: 'obclid', label: 'Outbrain' }, // Outbrain
117
+ { param: 'trybe', label: 'Trybe' }, // Trybe
118
+ { param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
119
+ { param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
120
+ { param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
121
+ { param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
122
+ { param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
123
+ { param: '_raclid', label: 'Rumble' }, // Rumble Ads
124
+ { param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
125
+ { param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
126
+ ];
127
+
128
+ const expand = (str) => str.split(',').flatMap((entry) => {
129
+ if (!entry.includes('-')) {
130
+ return entry;
131
+ }
132
+ const result = [];
133
+ const [start, end] = entry.split('-').map(Number);
134
+ for (let i = start; i <= end; i++) {
135
+ result.push(i.toString());
136
+ }
137
+ return result;
138
+ });
139
+ /**
140
+ * Exported from https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes
141
+ *
142
+ * In Dev Tools, select the `tbody` element containing the area codes and run the following code,
143
+ * replacing the emdash character with a simple endash:
144
+ *
145
+ * ```ts
146
+ * [...$0.querySelectorAll('td:first-child')]
147
+ * .filter(cell => cell.firstChild.nodeName != 'A')
148
+ * .map(cell => cell.textContent.trim()).join(',')
149
+ * ```
150
+ */
151
+ const invalidNANPAreaCodes = new Set([
152
+ ...expand('200,211,221,222,230,232,233,235,237-238,241,243,244,245,247,255,257,258-259,261,265,266,271,273,274,275,277,278,280,282,283,285-287,288,290-299'),
153
+ ...expand('300,311,322,324,327,328,333,335,338,342,344,348-349,353,355,356,357-359,362,366,369,370-379,381,382,383-384,387,388,389,390-399'),
154
+ ...expand('400,411,420,421-422,426-427,428,429,433,439,444,446,449,451-454,455,456,457,459,460,461-462,465,466,467,471,476,477,481-483,485-486,487,488,489,490-499'),
155
+ ...expand('511,532,535,536,537,538,542-543,545-547,549-550,552-554,555,556,558,560,565,568,569,576,578,583,589,590-599'),
156
+ ...expand('611,621,624,625,627,632,633,634-635,637-638,642-643,644,648,652-654,655,663,665,666,668,673-676,677,679,685,686,687,688,690-699'),
157
+ ...expand('711,722,723,729,733,735-736,739,741,744,745-746,748,749-751,752,755,756,759,761,764,766,768,776,777,783,788,789,790-799'),
158
+ ...expand('811,821,822,823-824,827,834,836,841-842,846,851,852-853,871,874-875,879,880-887,889,890-899'),
159
+ ...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
160
+ ]);
161
+ const isValidZone1AreaCode = (num) => {
162
+ if (!/^[2-9]\d{2}$/.test(num)) {
163
+ return false;
164
+ }
165
+ return !invalidNANPAreaCodes.has(num);
166
+ };
167
+
168
+ // North America; assume local numbers as NANP
169
+ const ZONE_1 = /^[+]1([2-9][0-8][0-9])[2-9][0-9]{6}$/;
170
+ // Africa
171
+ const ZONE_2 = /^[+]2([07][0-9]{4,13}|(1[12368]|[234][0-9]|5[0-8]|6[0-9]|9[01789])[0-9]{4,12})$/;
172
+ // Europe
173
+ const EU_TWO_DIGIT = `(3[0-469]|4[013-9])[0-9]{4,15}`;
174
+ const EU_THREE_DIGIT = `((3[578]|42)[0-9])[0-9]{4,12}`;
175
+ const ZONE_3_4 = new RegExp(`^[+](${EU_TWO_DIGIT}|${EU_THREE_DIGIT})$`);
176
+ // South America
177
+ const ZONE_5 = /^[+]5([1-8][0-9]{4,13}|[09][0-9][0-9]{4,12})$/;
178
+ // Southeast Asia & Oceania
179
+ const ZONE_6 = /^[+]6([0-6][0-9]{4,13}|(7[02-9]|8[0-35-9]|9[0-2])[0-9]{4,12})$/;
180
+ // Russia & Kazakhstan
181
+ const ZONE_7 = /^[+]7([1-9])[0-9]{4,13}$/;
182
+ // East & South Asia
183
+ const ZONE_8 = /^[+]8([1246][0-9]{4,13}|(0[08]|5[02356]|70|8[0-36])[0-9]{4,12})$/;
184
+ // Middle East, West & Central Asia, South Asia, Eastern Europe
185
+ const ZONE_9 = /^[+]9([0123458][0-9]{4,13}|(6[0-8]|7[0-79]|9[2-8])[0-9]{4,12})$/;
186
+ const checkers = [
187
+ (num) => {
188
+ const match = num.match(ZONE_1);
189
+ if (!match) {
190
+ return false;
191
+ }
192
+ return isValidZone1AreaCode(match[1]);
193
+ },
194
+ (num) => ZONE_2.test(num),
195
+ (num) => ZONE_3_4.test(num),
196
+ (num) => ZONE_5.test(num),
197
+ (num) => ZONE_6.test(num),
198
+ (num) => ZONE_7.test(num),
199
+ (num) => ZONE_8.test(num),
200
+ (num) => ZONE_9.test(num),
201
+ ];
202
+ /**
203
+ * Returns a boolean indicating whether or not a phone number conforms to a
204
+ * plausible E.164 phone number. It does not guarantee validity as each national
205
+ * operator may have various phone number lengths per area code or national
206
+ * scheme. It only validates currently active country codes and length
207
+ * restrictions.
208
+ *
209
+ * > *NOTE:* `E.164` format requires a leading plus sign, so you must set
210
+ * > `keepPlus` to `true` when normalising numbers:
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * const number = isPlausibleE164Number(normalizePhoneNumber(str, true))
215
+ * ```
216
+ */
217
+ const isPlausibleE164Number = (str) => str.startsWith('+') && checkers.some((check) => check(str));
218
+ const INTL_PREFIX = /^00|[+]+/;
219
+ /**
220
+ * Attempts to convert a given phone number string into an E.164 formatted
221
+ * number. In order to check whether the number is plausibly a real number, it
222
+ * must be checked with `isPlausibleE164Number` after normalising.
223
+ */
224
+ const normalizePhoneNumber = (str, keepPlus = false) => {
225
+ if (!str) {
226
+ return '';
227
+ }
228
+ let normalized = str;
229
+ // assume non-international numbers are US numbers
230
+ if (!INTL_PREFIX.test(normalized)) {
231
+ normalized = `+1${normalized}`;
232
+ }
233
+ normalized = normalized.replace(/[^+0-9]/g, '').replace(INTL_PREFIX, '+');
234
+ return keepPlus ? normalized : normalized.slice(1);
235
+ };
236
+
237
+ /**
238
+ * ISO-3166 2-leter country codes and their names
239
+ * @see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
240
+ */
241
+ const isoCountries = new Map([
242
+ ['AD', 'Andorra'],
243
+ ['AE', 'United Arab Emirates'],
244
+ ['AF', 'Afghanistan'],
245
+ ['AG', 'Antigua and Barbuda'],
246
+ ['AI', 'Anguilla'],
247
+ ['AL', 'Albania'],
248
+ ['AM', 'Armenia'],
249
+ ['AO', 'Angola'],
250
+ ['AQ', 'Antarctica'],
251
+ ['AR', 'Argentina'],
252
+ ['AS', 'American Samoa'],
253
+ ['AT', 'Austria'],
254
+ ['AU', 'Australia'],
255
+ ['AW', 'Aruba'],
256
+ ['AX', 'Åland Islands'],
257
+ ['AZ', 'Azerbaijan'],
258
+ ['BA', 'Bosnia and Herzegovina'],
259
+ ['BB', 'Barbados'],
260
+ ['BD', 'Bangladesh'],
261
+ ['BE', 'Belgium'],
262
+ ['BF', 'Burkina Faso'],
263
+ ['BG', 'Bulgaria'],
264
+ ['BH', 'Bahrain'],
265
+ ['BI', 'Burundi'],
266
+ ['BJ', 'Benin'],
267
+ ['BL', 'Saint Barthélemy'],
268
+ ['BM', 'Bermuda'],
269
+ ['BN', 'Brunei Darussalam'],
270
+ ['BO', 'Bolivia, Plurinational State of'],
271
+ ['BQ', 'Bonaire, Sint Eustatius and Saba'],
272
+ ['BR', 'Brazil'],
273
+ ['BS', 'Bahamas'],
274
+ ['BT', 'Bhutan'],
275
+ ['BV', 'Bouvet Island'],
276
+ ['BW', 'Botswana'],
277
+ ['BY', 'Belarus'],
278
+ ['BZ', 'Belize'],
279
+ ['CA', 'Canada'],
280
+ ['CC', 'Cocos (Keeling) Islands'],
281
+ ['CD', 'Congo, Democratic Republic of the'],
282
+ ['CF', 'Central African Republic'],
283
+ ['CG', 'Congo'],
284
+ ['CH', 'Switzerland'],
285
+ ['CI', "Côte d'Ivoire"],
286
+ ['CK', 'Cook Islands'],
287
+ ['CL', 'Chile'],
288
+ ['CM', 'Cameroon'],
289
+ ['CN', 'China'],
290
+ ['CO', 'Colombia'],
291
+ ['CR', 'Costa Rica'],
292
+ ['CU', 'Cuba'],
293
+ ['CV', 'Cabo Verde'],
294
+ ['CW', 'Curaçao'],
295
+ ['CX', 'Christmas Island'],
296
+ ['CY', 'Cyprus'],
297
+ ['CZ', 'Czechia'],
298
+ ['DE', 'Germany'],
299
+ ['DJ', 'Djibouti'],
300
+ ['DK', 'Denmark'],
301
+ ['DM', 'Dominica'],
302
+ ['DO', 'Dominican Republic'],
303
+ ['DZ', 'Algeria'],
304
+ ['EC', 'Ecuador'],
305
+ ['EE', 'Estonia'],
306
+ ['EG', 'Egypt'],
307
+ ['EH', 'Western Sahara'],
308
+ ['ER', 'Eritrea'],
309
+ ['ES', 'Spain'],
310
+ ['ET', 'Ethiopia'],
311
+ ['EU', 'European Union'],
312
+ ['FI', 'Finland'],
313
+ ['FJ', 'Fiji'],
314
+ ['FK', 'Falkland Islands (Malvinas)'],
315
+ ['FM', 'Micronesia, Federated States of'],
316
+ ['FO', 'Faroe Islands'],
317
+ ['FR', 'France'],
318
+ ['GA', 'Gabon'],
319
+ ['GB', 'Great Britain'],
320
+ ['GD', 'Grenada'],
321
+ ['GE', 'Georgia'],
322
+ ['GF', 'French Guiana'],
323
+ ['GG', 'Guernsey'],
324
+ ['GH', 'Ghana'],
325
+ ['GI', 'Gibraltar'],
326
+ ['GL', 'Greenland'],
327
+ ['GM', 'Gambia'],
328
+ ['GN', 'Guinea'],
329
+ ['GP', 'Guadeloupe'],
330
+ ['GQ', 'Equatorial Guinea'],
331
+ ['GR', 'Greece'],
332
+ ['GS', 'South Georgia and the South Sandwich Islands'],
333
+ ['GT', 'Guatemala'],
334
+ ['GU', 'Guam'],
335
+ ['GW', 'Guinea-Bissau'],
336
+ ['GY', 'Guyana'],
337
+ ['HK', 'Hong Kong'],
338
+ ['HM', 'Heard Island and McDonald Islands'],
339
+ ['HN', 'Honduras'],
340
+ ['HR', 'Croatia'],
341
+ ['HT', 'Haiti'],
342
+ ['HU', 'Hungary'],
343
+ ['ID', 'Indonesia'],
344
+ ['IE', 'Ireland'],
345
+ ['IL', 'Israel'],
346
+ ['IM', 'Isle of Man'],
347
+ ['IN', 'India'],
348
+ ['IO', 'British Indian Ocean Territory'],
349
+ ['IQ', 'Iraq'],
350
+ ['IR', 'Iran, Islamic Republic of'],
351
+ ['IS', 'Iceland'],
352
+ ['IT', 'Italy'],
353
+ ['JE', 'Jersey'],
354
+ ['JM', 'Jamaica'],
355
+ ['JO', 'Jordan'],
356
+ ['JP', 'Japan'],
357
+ ['KE', 'Kenya'],
358
+ ['KG', 'Kyrgyzstan'],
359
+ ['KH', 'Cambodia'],
360
+ ['KI', 'Kiribati'],
361
+ ['KM', 'Comoros'],
362
+ ['KN', 'Saint Kitts and Nevis'],
363
+ ['KP', "Korea, Democratic People's Republic of"],
364
+ ['KR', 'Korea, Republic of'],
365
+ ['KW', 'Kuwait'],
366
+ ['KY', 'Cayman Islands'],
367
+ ['KZ', 'Kazakhstan'],
368
+ ['LA', "Lao People's Democratic Republic"],
369
+ ['LB', 'Lebanon'],
370
+ ['LC', 'Saint Lucia'],
371
+ ['LI', 'Liechtenstein'],
372
+ ['LK', 'Sri Lanka'],
373
+ ['LR', 'Liberia'],
374
+ ['LS', 'Lesotho'],
375
+ ['LT', 'Lithuania'],
376
+ ['LU', 'Luxembourg'],
377
+ ['LV', 'Latvia'],
378
+ ['LY', 'Libya'],
379
+ ['MA', 'Morocco'],
380
+ ['MC', 'Monaco'],
381
+ ['MD', 'Moldova, Republic of'],
382
+ ['ME', 'Montenegro'],
383
+ ['MF', 'Saint Martin (French part)'],
384
+ ['MG', 'Madagascar'],
385
+ ['MH', 'Marshall Islands'],
386
+ ['MK', 'North Macedonia'],
387
+ ['ML', 'Mali'],
388
+ ['MM', 'Myanmar'],
389
+ ['MN', 'Mongolia'],
390
+ ['MO', 'Macao'],
391
+ ['MP', 'Northern Mariana Islands'],
392
+ ['MQ', 'Martinique'],
393
+ ['MR', 'Mauritania'],
394
+ ['MS', 'Montserrat'],
395
+ ['MT', 'Malta'],
396
+ ['MU', 'Mauritius'],
397
+ ['MV', 'Maldives'],
398
+ ['MW', 'Malawi'],
399
+ ['MX', 'Mexico'],
400
+ ['MY', 'Malaysia'],
401
+ ['MZ', 'Mozambique'],
402
+ ['NA', 'Namibia'],
403
+ ['NC', 'New Caledonia'],
404
+ ['NE', 'Niger'],
405
+ ['NF', 'Norfolk Island'],
406
+ ['NG', 'Nigeria'],
407
+ ['NI', 'Nicaragua'],
408
+ ['NL', 'Netherlands, Kingdom of the'],
409
+ ['NO', 'Norway'],
410
+ ['NP', 'Nepal'],
411
+ ['NR', 'Nauru'],
412
+ ['NU', 'Niue'],
413
+ ['NZ', 'New Zealand'],
414
+ ['OM', 'Oman'],
415
+ ['PA', 'Panama'],
416
+ ['PE', 'Peru'],
417
+ ['PF', 'French Polynesia'],
418
+ ['PG', 'Papua New Guinea'],
419
+ ['PH', 'Philippines'],
420
+ ['PK', 'Pakistan'],
421
+ ['PL', 'Poland'],
422
+ ['PM', 'Saint Pierre and Miquelon'],
423
+ ['PN', 'Pitcairn'],
424
+ ['PR', 'Puerto Rico'],
425
+ ['PS', 'Palestine, State of'],
426
+ ['PT', 'Portugal'],
427
+ ['PW', 'Palau'],
428
+ ['PY', 'Paraguay'],
429
+ ['QA', 'Qatar'],
430
+ ['RE', 'Réunion'],
431
+ ['RO', 'Romania'],
432
+ ['RS', 'Serbia'],
433
+ ['RU', 'Russian Federation'],
434
+ ['RW', 'Rwanda'],
435
+ ['SA', 'Saudi Arabia'],
436
+ ['SB', 'Solomon Islands'],
437
+ ['SC', 'Seychelles'],
438
+ ['SD', 'Sudan'],
439
+ ['SE', 'Sweden'],
440
+ ['SG', 'Singapore'],
441
+ ['SH', 'Saint Helena, Ascension and Tristan da Cunha'],
442
+ ['SI', 'Slovenia'],
443
+ ['SJ', 'Svalbard and Jan Mayen'],
444
+ ['SK', 'Slovakia'],
445
+ ['SL', 'Sierra Leone'],
446
+ ['SM', 'San Marino'],
447
+ ['SN', 'Senegal'],
448
+ ['SO', 'Somalia'],
449
+ ['SR', 'Suriname'],
450
+ ['SS', 'South Sudan'],
451
+ ['ST', 'Sao Tome and Principe'],
452
+ ['SV', 'El Salvador'],
453
+ ['SX', 'Sint Maarten (Dutch part)'],
454
+ ['SY', 'Syrian Arab Republic'],
455
+ ['SZ', 'Eswatini'],
456
+ ['TC', 'Turks and Caicos Islands'],
457
+ ['TD', 'Chad'],
458
+ ['TF', 'French Southern Territories'],
459
+ ['TG', 'Togo'],
460
+ ['TH', 'Thailand'],
461
+ ['TJ', 'Tajikistan'],
462
+ ['TK', 'Tokelau'],
463
+ ['TL', 'Timor-Leste'],
464
+ ['TM', 'Turkmenistan'],
465
+ ['TN', 'Tunisia'],
466
+ ['TO', 'Tonga'],
467
+ ['TR', 'Türkiye'],
468
+ ['TT', 'Trinidad and Tobago'],
469
+ ['TV', 'Tuvalu'],
470
+ ['TW', 'Taiwan, Province of China'],
471
+ ['TZ', 'Tanzania, United Republic of'],
472
+ ['UA', 'Ukraine'],
473
+ ['UG', 'Uganda'],
474
+ ['UK', 'United Kingdom of Great Britain and Northern Ireland'],
475
+ ['UM', 'United States Minor Outlying Islands'],
476
+ ['US', 'United States of America'],
477
+ ['UY', 'Uruguay'],
478
+ ['UZ', 'Uzbekistan'],
479
+ ['VA', 'Holy See'],
480
+ ['VC', 'Saint Vincent and the Grenadines'],
481
+ ['VE', 'Venezuela, Bolivarian Republic of'],
482
+ ['VG', 'Virgin Islands (British)'],
483
+ ['VI', 'Virgin Islands (U.S.)'],
484
+ ['VN', 'Viet Nam'],
485
+ ['VU', 'Vanuatu'],
486
+ ['WF', 'Wallis and Futuna'],
487
+ ['WS', 'Samoa'],
488
+ ['YE', 'Yemen'],
489
+ ['YT', 'Mayotte'],
490
+ ['ZA', 'South Africa'],
491
+ ['ZM', 'Zambia'],
492
+ ['ZW', 'Zimbabwe'],
493
+ ]);
494
+ /**
495
+ * ISO-3166 US state ISO codes
496
+ * @see https://en.wikipedia.org/wiki/ISO_3166-2:US
497
+ * */
498
+ const usStates = new Map([
499
+ ['US-AL', 'Alabama'],
500
+ ['US-AK', 'Alaska'],
501
+ ['US-AZ', 'Arizona'],
502
+ ['US-AR', 'Arkansas'],
503
+ ['US-CA', 'California'],
504
+ ['US-CO', 'Colorado'],
505
+ ['US-CT', 'Connecticut'],
506
+ ['US-DE', 'Delaware'],
507
+ ['US-FL', 'Florida'],
508
+ ['US-GA', 'Georgia'],
509
+ ['US-HI', 'Hawaii'],
510
+ ['US-ID', 'Idaho'],
511
+ ['US-IL', 'Illinois'],
512
+ ['US-IN', 'Indiana'],
513
+ ['US-IA', 'Iowa'],
514
+ ['US-KS', 'Kansas'],
515
+ ['US-KY', 'Kentucky'],
516
+ ['US-LA', 'Louisiana'],
517
+ ['US-ME', 'Maine'],
518
+ ['US-MD', 'Maryland'],
519
+ ['US-MA', 'Massachusetts'],
520
+ ['US-MI', 'Michigan'],
521
+ ['US-MN', 'Minnesota'],
522
+ ['US-MS', 'Mississippi'],
523
+ ['US-MO', 'Missouri'],
524
+ ['US-MT', 'Montana'],
525
+ ['US-NE', 'Nebraska'],
526
+ ['US-NV', 'Nevada'],
527
+ ['US-NH', 'New Hampshire'],
528
+ ['US-NJ', 'New Jersey'],
529
+ ['US-NM', 'New Mexico'],
530
+ ['US-NY', 'New York'],
531
+ ['US-NC', 'North Carolina'],
532
+ ['US-ND', 'North Dakota'],
533
+ ['US-OH', 'Ohio'],
534
+ ['US-OK', 'Oklahoma'],
535
+ ['US-OR', 'Oregon'],
536
+ ['US-PA', 'Pennsylvania'],
537
+ ['US-RI', 'Rhode Island'],
538
+ ['US-SC', 'South Carolina'],
539
+ ['US-SD', 'South Dakota'],
540
+ ['US-TN', 'Tennessee'],
541
+ ['US-TX', 'Texas'],
542
+ ['US-UT', 'Utah'],
543
+ ['US-VT', 'Vermont'],
544
+ ['US-VA', 'Virginia'],
545
+ ['US-WA', 'Washington'],
546
+ ['US-WV', 'West Virginia'],
547
+ ['US-WI', 'Wisconsin'],
548
+ ['US-WY', 'Wyoming'],
549
+ ['US-DC', 'District of Columbia'],
550
+ ['US-AS', 'American Samoa'],
551
+ ['US-GU', 'Guam'],
552
+ ['US-MP', 'Northern Mariana Islands'],
553
+ ['US-PR', 'Puerto Rico'],
554
+ ['US-UM', 'United States Minor Outlying Islands'],
555
+ ['US-VI', 'Virgin Islands, U.S.'],
556
+ ]);
557
+ /**
558
+ * ISO 3166-2:CA province and territory codes, keyed `CA-XX` to mirror
559
+ * `usStates`. Used by the consent banner's Canada region to offer province
560
+ * selection (Québec is treated specially by the regional consent config).
561
+ */
562
+ const caProvinces = new Map([
563
+ ['CA-AB', 'Alberta'],
564
+ ['CA-BC', 'British Columbia'],
565
+ ['CA-MB', 'Manitoba'],
566
+ ['CA-NB', 'New Brunswick'],
567
+ ['CA-NL', 'Newfoundland and Labrador'],
568
+ ['CA-NS', 'Nova Scotia'],
569
+ ['CA-NT', 'Northwest Territories'],
570
+ ['CA-NU', 'Nunavut'],
571
+ ['CA-ON', 'Ontario'],
572
+ ['CA-PE', 'Prince Edward Island'],
573
+ ['CA-QC', 'Quebec'],
574
+ ['CA-SK', 'Saskatchewan'],
575
+ ['CA-YT', 'Yukon'],
576
+ ]);
577
+ new Set([
578
+ ...isoCountries.keys(),
579
+ ...usStates.keys(),
580
+ ...caProvinces.keys(),
581
+ ]);
582
+
583
+ /**
584
+ * Exact utm_source normalization (lowercase key → canonical name).
585
+ *
586
+ * Use exact match when the key is short, generic, or must not accidentally
587
+ * absorb variant spellings (e.g. "impact" must not match "impact_radius").
588
+ *
589
+ * Ordering: Paid (search/social → ad networks → affiliates) →
590
+ * Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
591
+ */
592
+ const UTM_SOURCE_EXACT = {
593
+ // ── Paid – Search & Social ────────────────────────────────────────────────
594
+ google: 'Google',
595
+ adwords: 'Google',
596
+ youtube: 'Google',
597
+ yt: 'Google',
598
+ meta: 'Facebook',
599
+ facebook: 'Facebook',
600
+ instagram: 'Facebook',
601
+ ig: 'Facebook',
602
+ igshopping: 'Facebook',
603
+ threads: 'Facebook',
604
+ twitter: 'Twitter',
605
+ snapchat: 'Snapchat',
606
+ pinterest: 'Pinterest',
607
+ bing: 'Bing',
608
+ microsoft: 'Bing',
609
+ tiktok: 'TikTok',
610
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
611
+ rtbhouse: 'RTB House',
612
+ applovin: 'AppLovin',
613
+ ttd: 'The Trade Desk',
614
+ amazondsp: 'Amazon DSP',
615
+ axon: 'Axon',
616
+ duel: 'Duel',
617
+ // ── Paid – Affiliates ────────────────────────────────────────────────────
618
+ awin: 'Awin',
619
+ 'affiliate-cj': 'CJ Affiliate',
620
+ impact: 'Impact',
621
+ rakuten: 'Rakuten',
622
+ superfiliate: 'Superfiliate',
623
+ // ── Organic – AI & Discovery ─────────────────────────────────────────────
624
+ perplexity: 'Perplexity',
625
+ chatgpt: 'ChatGPT',
626
+ 'chatgpt.com': 'ChatGPT',
627
+ openai: 'ChatGPT',
628
+ 'copilot.com': 'Microsoft Copilot',
629
+ copilot: 'Microsoft Copilot',
630
+ applenews: 'Apple News',
631
+ whatsapp: 'WhatsApp',
632
+ podcast: 'Podcast',
633
+ // ── Retention – Email ────────────────────────────────────────────────────
634
+ mailchimp: 'Mailchimp',
635
+ omnisend: 'Omnisend',
636
+ iterable: 'Iterable',
637
+ listrak: 'Listrak',
638
+ sailthru: 'Sailthru',
639
+ // ── Retention – Push ─────────────────────────────────────────────────────
640
+ pushowl: 'PushOwl',
641
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
642
+ narvar: 'Narvar',
643
+ shop_app: 'Shop App',
644
+ salesforce: 'Salesforce',
645
+ yotpo: 'Yotpo',
646
+ };
647
+ /**
648
+ * Partial utm_source normalization (startsWith prefix check, lowercase).
649
+ *
650
+ * Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
651
+ */
652
+ const UTM_SOURCE_PARTIAL = [
653
+ // ── Paid – Social ─────────────────────────────────────────────────────────
654
+ { prefix: 'tiktok', name: 'TikTok' },
655
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
656
+ { prefix: 'criteo', name: 'Criteo' },
657
+ // ── Retention – Email ────────────────────────────────────────────────────
658
+ { prefix: 'klaviyo', name: 'Klaviyo' },
659
+ // ── Retention – SMS ──────────────────────────────────────────────────────
660
+ { prefix: 'attentive', name: 'Attentive' },
661
+ { prefix: 'postscript', name: 'Postscript' },
662
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
663
+ { prefix: 'afterpay', name: 'Afterpay' },
664
+ { prefix: 'klarna', name: 'Klarna' },
665
+ ];
666
+ const ORGANIC_SEARCH_ENGINES = [
667
+ { match: 'google', name: 'Google' },
668
+ { match: 'bing', name: 'Bing' },
669
+ { match: 'yahoo', name: 'Yahoo' },
670
+ { match: 'duckduckgo', name: 'DuckDuckGo' },
671
+ { match: 'baidu', name: 'Baidu' },
672
+ { match: 'yandex', name: 'Yandex' },
673
+ { match: 'brave', name: 'Brave' },
674
+ ];
675
+ const KNOWN_REFERRAL_PLATFORMS = [
676
+ { match: 'facebook', name: 'Facebook' },
677
+ { match: 'instagram', name: 'Facebook' },
678
+ { match: 'twitter', name: 'Twitter' },
679
+ { match: 'x.com', name: 'Twitter' },
680
+ { match: 'tiktok', name: 'TikTok' },
681
+ { match: 'pinterest', name: 'Pinterest' },
682
+ { match: 'linkedin', name: 'LinkedIn' },
683
+ { match: 'youtube', name: 'YouTube' },
684
+ { match: 'chatgpt', name: 'ChatGPT' },
685
+ { match: 'claude', name: 'Claude' },
686
+ { match: 'perplexity', name: 'Perplexity' },
687
+ { match: 'shop.app', name: 'Shop App' },
688
+ { match: 'amazon', name: 'Amazon' },
689
+ { match: 'attentive', name: 'Attentive' },
690
+ ];
691
+ const OFFLINE_TOUCH = 'Blotout_Offline';
692
+ new Set([
693
+ ...CLICK_IDS.map((c) => c.label),
694
+ ...Object.values(UTM_SOURCE_EXACT),
695
+ ...UTM_SOURCE_PARTIAL.map((e) => e.name),
696
+ ...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
697
+ ...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
698
+ 'Referral - Other',
699
+ 'Direct Traffic',
700
+ 'Other',
701
+ OFFLINE_TOUCH,
702
+ ]);
703
+
704
+ const getString = (kv, key) => {
705
+ const value = kv === null || kv === void 0 ? void 0 : kv[key];
706
+ return typeof value === 'string' && value ? value : undefined;
707
+ };
708
+ /**
709
+ * Maps session KV onto the params Snap's tag accepts on `init`. Everything goes
710
+ * across raw: the tag strips the phone to digits and lowercases the rest before
711
+ * hashing it in the browser.
712
+ *
713
+ * `gender` and `dateOfBirth` are deliberately left out. Snap transmits gender
714
+ * unhashed, and it parses `db` as an integer age bounded to 0-130, so a
715
+ * YYYYMMDD date is rejected.
716
+ */
717
+ const buildIdentity = (kv, userId) => {
718
+ const identity = {};
719
+ const email = getString(kv, 'email');
720
+ if (email) {
721
+ identity['user_email'] = email;
722
+ }
723
+ const phone = getString(kv, 'phone');
724
+ if (phone && isPlausibleE164Number(normalizePhoneNumber(phone, true))) {
725
+ // Snap normalizes before hashing, so the raw value goes across. The guard
726
+ // only keeps junk from being sent as a hash that matches nobody.
727
+ identity['user_phone_number'] = phone;
728
+ }
729
+ const firstName = getString(kv, 'firstName');
730
+ if (firstName) {
731
+ identity['firstname'] = firstName;
732
+ }
733
+ const lastName = getString(kv, 'lastName');
734
+ if (lastName) {
735
+ identity['lastname'] = lastName;
736
+ }
737
+ const city = getString(kv, 'city');
738
+ if (city) {
739
+ identity['geo_city'] = city;
740
+ }
741
+ const state = getString(kv, 'state');
742
+ if (state) {
743
+ identity['geo_region'] = state;
744
+ }
745
+ const zip = getString(kv, 'zip');
746
+ if (zip) {
747
+ identity['geo_postal_code'] = zip;
748
+ }
749
+ const country = getString(kv, 'country');
750
+ if (country) {
751
+ identity['geo_country'] = country;
752
+ }
753
+ if (userId) {
754
+ identity['external_id'] = userId;
755
+ }
756
+ return identity;
757
+ };
758
+
41
759
  const snippet = () => {
42
760
  if (!window || !document || window.snaptr) {
43
761
  return;
@@ -58,7 +776,7 @@ var ProvidersSnapchatSdk = (function () {
58
776
  script.parentNode.insertBefore(element, script);
59
777
  }
60
778
  };
61
- const init = ({ manifest }) => {
779
+ const init = ({ manifest, userId, destination }) => {
62
780
  if (!manifest.variables ||
63
781
  !manifest.variables['pixelId'] ||
64
782
  manifest.variables['enableBrowser'] !== '1') {
@@ -68,17 +786,8 @@ var ProvidersSnapchatSdk = (function () {
68
786
  if (!window.snaptr) {
69
787
  return;
70
788
  }
71
- window.snaptr('init', manifest.variables['pixelId']);
72
- };
73
-
74
- const getProductIdFromMapping = (item, productIdMapping) => {
75
- if (productIdMapping === '1' && item['variantId']) {
76
- return item['variantId'];
77
- }
78
- if (productIdMapping === '2' && item['sku']) {
79
- return item['sku'];
80
- }
81
- return item['id'];
789
+ const identity = buildIdentity(getData(destination, 'session')['kv'], userId);
790
+ window.snaptr('init', manifest.variables['pixelId'], identity);
82
791
  };
83
792
 
84
793
  // eslint-disable-next-line @nx/enforce-module-boundaries
@@ -179,7 +888,7 @@ var ProvidersSnapchatSdk = (function () {
179
888
  return name.toUpperCase();
180
889
  };
181
890
  const tag = ({ data, eventName, manifestVariables, eventId, executionContext, }) => {
182
- const result = { sdkVersion: "1.68.1" };
891
+ const result = { sdkVersion: "1.69.0" };
183
892
  if (executionContext.get('pixelFired')) {
184
893
  return result;
185
894
  }
@@ -203,11 +912,30 @@ var ProvidersSnapchatSdk = (function () {
203
912
  return result;
204
913
  };
205
914
 
915
+ const user = ({ userId, manifestVariables, destination }) => {
916
+ if (!window ||
917
+ !window.snaptr ||
918
+ !manifestVariables['pixelId'] ||
919
+ manifestVariables['enableBrowser'] !== '1') {
920
+ return;
921
+ }
922
+ // KV is read rather than `data` because `data` carries only what just
923
+ // changed, and saveKV has already merged it in by the time this runs.
924
+ const identity = buildIdentity(getData(destination, 'session')['kv'], userId);
925
+ if (!Object.keys(identity).length) {
926
+ return;
927
+ }
928
+ // A second init on the same pixel merges the new params over the stored ones
929
+ // and skips the first-init side effects, so nothing re-registers or re-fires.
930
+ window.snaptr('init', manifestVariables['pixelId'], identity);
931
+ };
932
+
206
933
  // eslint-disable-next-line @nx/enforce-module-boundaries
207
934
  const data = {
208
935
  name: packageName,
209
936
  tag,
210
937
  init,
938
+ user,
211
939
  };
212
940
  try {
213
941
  if (window) {