@saasquatch/squatch-js 2.8.3-2 → 2.8.3-3

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.
@@ -1,212 +1,608 @@
1
- var Ee = Object.defineProperty;
2
- var Ce = (o, t, e) => t in o ? Ee(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
3
- var l = (o, t, e) => Ce(o, typeof t != "symbol" ? t + "" : t, e);
4
- let C = null;
5
- function Ae(o) {
6
- const e = o.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
7
- C = new RegExp(`^${e}$`);
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ var _a;
5
+ function getDefaultExportFromCjs(x) {
6
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
8
7
  }
9
- function Ie() {
10
- C = null;
11
- }
12
- function k(o) {
13
- const t = (...e) => {
14
- C && C.test(o) && console.log(`[${o}]`, ...e);
8
+ var browser = { exports: {} };
9
+ var ms;
10
+ var hasRequiredMs;
11
+ function requireMs() {
12
+ if (hasRequiredMs) return ms;
13
+ hasRequiredMs = 1;
14
+ var s = 1e3;
15
+ var m = s * 60;
16
+ var h = m * 60;
17
+ var d = h * 24;
18
+ var w = d * 7;
19
+ var y = d * 365.25;
20
+ ms = function(val, options) {
21
+ options = options || {};
22
+ var type = typeof val;
23
+ if (type === "string" && val.length > 0) {
24
+ return parse(val);
25
+ } else if (type === "number" && isFinite(val)) {
26
+ return options.long ? fmtLong(val) : fmtShort(val);
27
+ }
28
+ throw new Error(
29
+ "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
30
+ );
15
31
  };
16
- return Object.defineProperty(t, "enabled", {
17
- get() {
18
- return !!(C && C.test(o));
32
+ function parse(str) {
33
+ str = String(str);
34
+ if (str.length > 100) {
35
+ return;
36
+ }
37
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
38
+ str
39
+ );
40
+ if (!match) {
41
+ return;
42
+ }
43
+ var n = parseFloat(match[1]);
44
+ var type = (match[2] || "ms").toLowerCase();
45
+ switch (type) {
46
+ case "years":
47
+ case "year":
48
+ case "yrs":
49
+ case "yr":
50
+ case "y":
51
+ return n * y;
52
+ case "weeks":
53
+ case "week":
54
+ case "w":
55
+ return n * w;
56
+ case "days":
57
+ case "day":
58
+ case "d":
59
+ return n * d;
60
+ case "hours":
61
+ case "hour":
62
+ case "hrs":
63
+ case "hr":
64
+ case "h":
65
+ return n * h;
66
+ case "minutes":
67
+ case "minute":
68
+ case "mins":
69
+ case "min":
70
+ case "m":
71
+ return n * m;
72
+ case "seconds":
73
+ case "second":
74
+ case "secs":
75
+ case "sec":
76
+ case "s":
77
+ return n * s;
78
+ case "milliseconds":
79
+ case "millisecond":
80
+ case "msecs":
81
+ case "msec":
82
+ case "ms":
83
+ return n;
84
+ default:
85
+ return void 0;
86
+ }
87
+ }
88
+ function fmtShort(ms2) {
89
+ var msAbs = Math.abs(ms2);
90
+ if (msAbs >= d) {
91
+ return Math.round(ms2 / d) + "d";
92
+ }
93
+ if (msAbs >= h) {
94
+ return Math.round(ms2 / h) + "h";
95
+ }
96
+ if (msAbs >= m) {
97
+ return Math.round(ms2 / m) + "m";
98
+ }
99
+ if (msAbs >= s) {
100
+ return Math.round(ms2 / s) + "s";
101
+ }
102
+ return ms2 + "ms";
103
+ }
104
+ function fmtLong(ms2) {
105
+ var msAbs = Math.abs(ms2);
106
+ if (msAbs >= d) {
107
+ return plural(ms2, msAbs, d, "day");
108
+ }
109
+ if (msAbs >= h) {
110
+ return plural(ms2, msAbs, h, "hour");
111
+ }
112
+ if (msAbs >= m) {
113
+ return plural(ms2, msAbs, m, "minute");
114
+ }
115
+ if (msAbs >= s) {
116
+ return plural(ms2, msAbs, s, "second");
117
+ }
118
+ return ms2 + " ms";
119
+ }
120
+ function plural(ms2, msAbs, n, name) {
121
+ var isPlural = msAbs >= n * 1.5;
122
+ return Math.round(ms2 / n) + " " + name + (isPlural ? "s" : "");
123
+ }
124
+ return ms;
125
+ }
126
+ var common;
127
+ var hasRequiredCommon;
128
+ function requireCommon() {
129
+ if (hasRequiredCommon) return common;
130
+ hasRequiredCommon = 1;
131
+ function setup(env) {
132
+ createDebug.debug = createDebug;
133
+ createDebug.default = createDebug;
134
+ createDebug.coerce = coerce;
135
+ createDebug.disable = disable;
136
+ createDebug.enable = enable;
137
+ createDebug.enabled = enabled;
138
+ createDebug.humanize = requireMs();
139
+ Object.keys(env).forEach(function(key) {
140
+ createDebug[key] = env[key];
141
+ });
142
+ createDebug.instances = [];
143
+ createDebug.names = [];
144
+ createDebug.skips = [];
145
+ createDebug.formatters = {};
146
+ function selectColor(namespace) {
147
+ var hash = 0;
148
+ for (var i = 0; i < namespace.length; i++) {
149
+ hash = (hash << 5) - hash + namespace.charCodeAt(i);
150
+ hash |= 0;
151
+ }
152
+ return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
153
+ }
154
+ createDebug.selectColor = selectColor;
155
+ function createDebug(namespace) {
156
+ var prevTime;
157
+ function debug2() {
158
+ if (!debug2.enabled) {
159
+ return;
160
+ }
161
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
162
+ args[_key] = arguments[_key];
163
+ }
164
+ var self = debug2;
165
+ var curr = Number(/* @__PURE__ */ new Date());
166
+ var ms2 = curr - (prevTime || curr);
167
+ self.diff = ms2;
168
+ self.prev = prevTime;
169
+ self.curr = curr;
170
+ prevTime = curr;
171
+ args[0] = createDebug.coerce(args[0]);
172
+ if (typeof args[0] !== "string") {
173
+ args.unshift("%O");
174
+ }
175
+ var index = 0;
176
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
177
+ if (match === "%%") {
178
+ return match;
179
+ }
180
+ index++;
181
+ var formatter = createDebug.formatters[format];
182
+ if (typeof formatter === "function") {
183
+ var val = args[index];
184
+ match = formatter.call(self, val);
185
+ args.splice(index, 1);
186
+ index--;
187
+ }
188
+ return match;
189
+ });
190
+ createDebug.formatArgs.call(self, args);
191
+ var logFn = self.log || createDebug.log;
192
+ logFn.apply(self, args);
193
+ }
194
+ debug2.namespace = namespace;
195
+ debug2.enabled = createDebug.enabled(namespace);
196
+ debug2.useColors = createDebug.useColors();
197
+ debug2.color = selectColor(namespace);
198
+ debug2.destroy = destroy;
199
+ debug2.extend = extend;
200
+ if (typeof createDebug.init === "function") {
201
+ createDebug.init(debug2);
202
+ }
203
+ createDebug.instances.push(debug2);
204
+ return debug2;
205
+ }
206
+ function destroy() {
207
+ var index = createDebug.instances.indexOf(this);
208
+ if (index !== -1) {
209
+ createDebug.instances.splice(index, 1);
210
+ return true;
211
+ }
212
+ return false;
213
+ }
214
+ function extend(namespace, delimiter) {
215
+ return createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
216
+ }
217
+ function enable(namespaces) {
218
+ createDebug.save(namespaces);
219
+ createDebug.names = [];
220
+ createDebug.skips = [];
221
+ var i;
222
+ var split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/);
223
+ var len = split.length;
224
+ for (i = 0; i < len; i++) {
225
+ if (!split[i]) {
226
+ continue;
227
+ }
228
+ namespaces = split[i].replace(/\*/g, ".*?");
229
+ if (namespaces[0] === "-") {
230
+ createDebug.skips.push(new RegExp("^" + namespaces.substr(1) + "$"));
231
+ } else {
232
+ createDebug.names.push(new RegExp("^" + namespaces + "$"));
233
+ }
234
+ }
235
+ for (i = 0; i < createDebug.instances.length; i++) {
236
+ var instance = createDebug.instances[i];
237
+ instance.enabled = createDebug.enabled(instance.namespace);
238
+ }
239
+ }
240
+ function disable() {
241
+ createDebug.enable("");
242
+ }
243
+ function enabled(name) {
244
+ if (name[name.length - 1] === "*") {
245
+ return true;
246
+ }
247
+ var i;
248
+ var len;
249
+ for (i = 0, len = createDebug.skips.length; i < len; i++) {
250
+ if (createDebug.skips[i].test(name)) {
251
+ return false;
252
+ }
253
+ }
254
+ for (i = 0, len = createDebug.names.length; i < len; i++) {
255
+ if (createDebug.names[i].test(name)) {
256
+ return true;
257
+ }
258
+ }
259
+ return false;
260
+ }
261
+ function coerce(val) {
262
+ if (val instanceof Error) {
263
+ return val.stack || val.message;
264
+ }
265
+ return val;
266
+ }
267
+ createDebug.enable(createDebug.load());
268
+ return createDebug;
269
+ }
270
+ common = setup;
271
+ return common;
272
+ }
273
+ var hasRequiredBrowser;
274
+ function requireBrowser() {
275
+ if (hasRequiredBrowser) return browser.exports;
276
+ hasRequiredBrowser = 1;
277
+ (function(module, exports) {
278
+ function _typeof(obj) {
279
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
280
+ _typeof = function _typeof2(obj2) {
281
+ return typeof obj2;
282
+ };
283
+ } else {
284
+ _typeof = function _typeof2(obj2) {
285
+ return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
286
+ };
287
+ }
288
+ return _typeof(obj);
289
+ }
290
+ exports.log = log;
291
+ exports.formatArgs = formatArgs;
292
+ exports.save = save;
293
+ exports.load = load;
294
+ exports.useColors = useColors;
295
+ exports.storage = localstorage();
296
+ exports.colors = ["#0000CC", "#0000FF", "#0033CC", "#0033FF", "#0066CC", "#0066FF", "#0099CC", "#0099FF", "#00CC00", "#00CC33", "#00CC66", "#00CC99", "#00CCCC", "#00CCFF", "#3300CC", "#3300FF", "#3333CC", "#3333FF", "#3366CC", "#3366FF", "#3399CC", "#3399FF", "#33CC00", "#33CC33", "#33CC66", "#33CC99", "#33CCCC", "#33CCFF", "#6600CC", "#6600FF", "#6633CC", "#6633FF", "#66CC00", "#66CC33", "#9900CC", "#9900FF", "#9933CC", "#9933FF", "#99CC00", "#99CC33", "#CC0000", "#CC0033", "#CC0066", "#CC0099", "#CC00CC", "#CC00FF", "#CC3300", "#CC3333", "#CC3366", "#CC3399", "#CC33CC", "#CC33FF", "#CC6600", "#CC6633", "#CC9900", "#CC9933", "#CCCC00", "#CCCC33", "#FF0000", "#FF0033", "#FF0066", "#FF0099", "#FF00CC", "#FF00FF", "#FF3300", "#FF3333", "#FF3366", "#FF3399", "#FF33CC", "#FF33FF", "#FF6600", "#FF6633", "#FF9900", "#FF9933", "#FFCC00", "#FFCC33"];
297
+ function useColors() {
298
+ if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
299
+ return true;
300
+ }
301
+ if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
302
+ return false;
303
+ }
304
+ return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
305
+ typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
306
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
307
+ typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
308
+ typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
309
+ }
310
+ function formatArgs(args) {
311
+ args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module.exports.humanize(this.diff);
312
+ if (!this.useColors) {
313
+ return;
314
+ }
315
+ var c = "color: " + this.color;
316
+ args.splice(1, 0, c, "color: inherit");
317
+ var index = 0;
318
+ var lastC = 0;
319
+ args[0].replace(/%[a-zA-Z%]/g, function(match) {
320
+ if (match === "%%") {
321
+ return;
322
+ }
323
+ index++;
324
+ if (match === "%c") {
325
+ lastC = index;
326
+ }
327
+ });
328
+ args.splice(lastC, 0, c);
329
+ }
330
+ function log() {
331
+ var _console;
332
+ return (typeof console === "undefined" ? "undefined" : _typeof(console)) === "object" && console.log && (_console = console).log.apply(_console, arguments);
19
333
  }
20
- }), t;
334
+ function save(namespaces) {
335
+ try {
336
+ if (namespaces) {
337
+ exports.storage.setItem("debug", namespaces);
338
+ } else {
339
+ exports.storage.removeItem("debug");
340
+ }
341
+ } catch (error) {
342
+ }
343
+ }
344
+ function load() {
345
+ var r;
346
+ try {
347
+ r = exports.storage.getItem("debug");
348
+ } catch (error) {
349
+ }
350
+ if (!r && typeof process !== "undefined" && "env" in process) {
351
+ r = process.env.DEBUG;
352
+ }
353
+ return r;
354
+ }
355
+ function localstorage() {
356
+ try {
357
+ return localStorage;
358
+ } catch (error) {
359
+ }
360
+ }
361
+ module.exports = requireCommon()(exports);
362
+ var formatters = module.exports.formatters;
363
+ formatters.j = function(v) {
364
+ try {
365
+ return JSON.stringify(v);
366
+ } catch (error) {
367
+ return "[UnexpectedJSONParseError]: " + error.message;
368
+ }
369
+ };
370
+ })(browser, browser.exports);
371
+ return browser.exports;
21
372
  }
373
+ var browserExports = requireBrowser();
374
+ const debug = /* @__PURE__ */ getDefaultExportFromCjs(browserExports);
22
375
  /*! js-cookie v3.0.5 | MIT */
23
- function S(o) {
24
- for (var t = 1; t < arguments.length; t++) {
25
- var e = arguments[t];
26
- for (var n in e)
27
- o[n] = e[n];
376
+ function assign(target) {
377
+ for (var i = 1; i < arguments.length; i++) {
378
+ var source = arguments[i];
379
+ for (var key in source) {
380
+ target[key] = source[key];
381
+ }
28
382
  }
29
- return o;
383
+ return target;
30
384
  }
31
- var _e = {
32
- read: function(o) {
33
- return o[0] === '"' && (o = o.slice(1, -1)), o.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
385
+ var defaultConverter = {
386
+ read: function(value) {
387
+ if (value[0] === '"') {
388
+ value = value.slice(1, -1);
389
+ }
390
+ return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
34
391
  },
35
- write: function(o) {
36
- return encodeURIComponent(o).replace(
392
+ write: function(value) {
393
+ return encodeURIComponent(value).replace(
37
394
  /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
38
395
  decodeURIComponent
39
396
  );
40
397
  }
41
398
  };
42
- function G(o, t) {
43
- function e(i, s, r) {
44
- if (!(typeof document > "u")) {
45
- r = S({}, t, r), typeof r.expires == "number" && (r.expires = new Date(Date.now() + r.expires * 864e5)), r.expires && (r.expires = r.expires.toUTCString()), i = encodeURIComponent(i).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
46
- var a = "";
47
- for (var d in r)
48
- r[d] && (a += "; " + d, r[d] !== !0 && (a += "=" + r[d].split(";")[0]));
49
- return document.cookie = i + "=" + o.write(s, i) + a;
50
- }
51
- }
52
- function n(i) {
53
- if (!(typeof document > "u" || arguments.length && !i)) {
54
- for (var s = document.cookie ? document.cookie.split("; ") : [], r = {}, a = 0; a < s.length; a++) {
55
- var d = s[a].split("="), c = d.slice(1).join("=");
56
- try {
57
- var h = decodeURIComponent(d[0]);
58
- if (r[h] = o.read(c, h), i === h)
59
- break;
60
- } catch {
399
+ function init$1(converter, defaultAttributes) {
400
+ function set(name, value, attributes) {
401
+ if (typeof document === "undefined") {
402
+ return;
403
+ }
404
+ attributes = assign({}, defaultAttributes, attributes);
405
+ if (typeof attributes.expires === "number") {
406
+ attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
407
+ }
408
+ if (attributes.expires) {
409
+ attributes.expires = attributes.expires.toUTCString();
410
+ }
411
+ name = encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
412
+ var stringifiedAttributes = "";
413
+ for (var attributeName in attributes) {
414
+ if (!attributes[attributeName]) {
415
+ continue;
416
+ }
417
+ stringifiedAttributes += "; " + attributeName;
418
+ if (attributes[attributeName] === true) {
419
+ continue;
420
+ }
421
+ stringifiedAttributes += "=" + attributes[attributeName].split(";")[0];
422
+ }
423
+ return document.cookie = name + "=" + converter.write(value, name) + stringifiedAttributes;
424
+ }
425
+ function get(name) {
426
+ if (typeof document === "undefined" || arguments.length && !name) {
427
+ return;
428
+ }
429
+ var cookies = document.cookie ? document.cookie.split("; ") : [];
430
+ var jar = {};
431
+ for (var i = 0; i < cookies.length; i++) {
432
+ var parts = cookies[i].split("=");
433
+ var value = parts.slice(1).join("=");
434
+ try {
435
+ var found = decodeURIComponent(parts[0]);
436
+ jar[found] = converter.read(value, found);
437
+ if (name === found) {
438
+ break;
61
439
  }
440
+ } catch (e) {
62
441
  }
63
- return i ? r[i] : r;
64
442
  }
443
+ return name ? jar[name] : jar;
65
444
  }
66
445
  return Object.create(
67
446
  {
68
- set: e,
69
- get: n,
70
- remove: function(i, s) {
71
- e(
72
- i,
447
+ set,
448
+ get,
449
+ remove: function(name, attributes) {
450
+ set(
451
+ name,
73
452
  "",
74
- S({}, s, {
453
+ assign({}, attributes, {
75
454
  expires: -1
76
455
  })
77
456
  );
78
457
  },
79
- withAttributes: function(i) {
80
- return G(this.converter, S({}, this.attributes, i));
458
+ withAttributes: function(attributes) {
459
+ return init$1(this.converter, assign({}, this.attributes, attributes));
81
460
  },
82
- withConverter: function(i) {
83
- return G(S({}, this.converter, i), this.attributes);
461
+ withConverter: function(converter2) {
462
+ return init$1(assign({}, this.converter, converter2), this.attributes);
84
463
  }
85
464
  },
86
465
  {
87
- attributes: { value: Object.freeze(t) },
88
- converter: { value: Object.freeze(o) }
466
+ attributes: { value: Object.freeze(defaultAttributes) },
467
+ converter: { value: Object.freeze(converter) }
89
468
  }
90
469
  );
91
470
  }
92
- var M = G(_e, { path: "/" });
93
- const A = "https://app.referralsaasquatch.com", V = "https://fast.ssqt.io/npm", R = "squatch", z = "impact";
94
- function q(o) {
95
- if (typeof o != "object") throw new Error("config must be an object");
96
- const t = window.squatchTenant, e = Y(), n = {
97
- tenantAlias: (o == null ? void 0 : o.tenantAlias) || t,
98
- domain: (o == null ? void 0 : o.domain) || (e == null ? void 0 : e.domain),
99
- npmCdn: (o == null ? void 0 : o.npmCdn) || (e == null ? void 0 : e.npmCdn),
100
- debug: (o == null ? void 0 : o.debug) || (e == null ? void 0 : e.debug)
471
+ var api$1 = init$1(defaultConverter, { path: "/" });
472
+ const DEFAULT_DOMAIN = "https://app.referralsaasquatch.com";
473
+ const DEFAULT_NPM_CDN = "https://fast.ssqt.io/npm";
474
+ const DEFAULT_NAMESPACE = "squatch";
475
+ const IMPACT_NAMESPACE = "impact";
476
+ function validateConfig(_raw) {
477
+ if (typeof _raw !== "object") throw new Error("config must be an object");
478
+ const tenant = window.squatchTenant;
479
+ const config = getConfig();
480
+ const raw = {
481
+ tenantAlias: (_raw == null ? void 0 : _raw["tenantAlias"]) || tenant,
482
+ domain: (_raw == null ? void 0 : _raw["domain"]) || (config == null ? void 0 : config.domain),
483
+ npmCdn: (_raw == null ? void 0 : _raw["npmCdn"]) || (config == null ? void 0 : config.npmCdn),
484
+ debug: (_raw == null ? void 0 : _raw["debug"]) || (config == null ? void 0 : config.debug)
101
485
  };
102
- if (typeof n.tenantAlias != "string")
486
+ if (typeof raw.tenantAlias !== "string")
103
487
  throw new Error("tenantAlias not provided");
104
- const i = n.tenantAlias, s = typeof n.domain == "string" && n.domain || A, r = typeof n.debug == "boolean" && n.debug || !1, a = typeof n.npmCdn == "string" && n.npmCdn || V;
488
+ const tenantAlias = raw.tenantAlias;
489
+ const domain = typeof raw.domain === "string" && raw.domain || DEFAULT_DOMAIN;
490
+ const debug2 = typeof raw.debug === "boolean" && raw.debug || false;
491
+ const npmCdn = typeof raw.npmCdn === "string" && raw.npmCdn || DEFAULT_NPM_CDN;
105
492
  return {
106
- tenantAlias: i,
107
- domain: s,
108
- debug: r,
109
- npmCdn: a
493
+ tenantAlias,
494
+ domain,
495
+ debug: debug2,
496
+ npmCdn
110
497
  };
111
498
  }
112
- function I(o) {
113
- return typeof o == "object" && !Array.isArray(o) && o !== null;
499
+ function isObject$1(obj) {
500
+ return typeof obj === "object" && !Array.isArray(obj) && obj !== null;
114
501
  }
115
- function Te(o) {
116
- if (o && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(o))
117
- return o;
502
+ function validateLocale(locale) {
503
+ if (locale && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(locale)) {
504
+ return locale;
505
+ }
118
506
  }
119
- function ce(o) {
120
- if (!I(o)) throw new Error("Widget properties must be an object");
121
- if (!(o != null && o.user)) throw new Error("Required properties missing.");
122
- return o;
507
+ function validateWidgetConfig(raw) {
508
+ if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
509
+ if (!(raw == null ? void 0 : raw["user"])) throw new Error("Required properties missing.");
510
+ return raw;
123
511
  }
124
- function le(o) {
125
- if (!I(o)) throw new Error("Widget properties must be an object");
126
- return o;
512
+ function validatePasswordlessConfig(raw) {
513
+ if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
514
+ return raw;
127
515
  }
128
- function W() {
516
+ function getToken() {
129
517
  return window.impactToken || window.squatchToken;
130
518
  }
131
- function Y() {
519
+ function getConfig() {
132
520
  return window.impactConfig || window.squatchConfig;
133
521
  }
134
- async function $e(o, t, e, n) {
135
- const i = n || W(), s = {
522
+ browserExports.debug("squatch-js:io");
523
+ async function doQuery(url, query, variables, jwt) {
524
+ const token = jwt || getToken();
525
+ const headers = {
136
526
  Accept: "application/json",
137
527
  "Content-Type": "application/json",
138
- ...i ? { Authorization: `Bearer ${i}` } : {},
528
+ ...token ? { Authorization: `Bearer ${token}` } : {},
139
529
  "X-SaaSquatch-Referrer": window ? window.location.href : ""
140
530
  };
141
531
  try {
142
- const r = await fetch(o, {
532
+ const res = await fetch(url, {
143
533
  method: "POST",
144
- body: JSON.stringify({ query: t, variables: e }),
145
- headers: s
534
+ body: JSON.stringify({ query, variables }),
535
+ headers
146
536
  });
147
- if (!r.ok) throw new Error(await r.text());
148
- return await r.json();
149
- } catch (r) {
150
- throw r;
537
+ if (!res.ok) throw new Error(await res.text());
538
+ return await res.json();
539
+ } catch (e) {
540
+ throw e;
151
541
  }
152
542
  }
153
- async function qe(o, t = "") {
154
- const e = {
543
+ async function doGet(url, jwt = "") {
544
+ const headers = {
155
545
  Accept: "application/json",
156
546
  "Content-Type": "application/json"
157
- }, n = t || W();
158
- n && (e["X-SaaSquatch-User-Token"] = n);
547
+ };
548
+ const token = jwt || getToken();
549
+ if (token) headers["X-SaaSquatch-User-Token"] = token;
159
550
  try {
160
- const i = await fetch(o, {
551
+ const res = await fetch(url, {
161
552
  method: "GET",
162
553
  credentials: "include",
163
- headers: e
164
- }), s = await i.text();
165
- if (!i.ok) throw new Error(s);
166
- return s && JSON.parse(s);
167
- } catch (i) {
168
- throw i;
554
+ headers
555
+ });
556
+ const reply = await res.text();
557
+ if (!res.ok) throw new Error(reply);
558
+ return reply ? JSON.parse(reply) : reply;
559
+ } catch (e) {
560
+ throw e;
169
561
  }
170
562
  }
171
- async function X(o, t, e) {
172
- const n = {
563
+ async function doPost(url, data, jwt) {
564
+ const headers = {
173
565
  Accept: "application/json",
174
566
  "Content-Type": "application/json"
175
- }, i = e || W();
176
- i && (n["X-SaaSquatch-User-Token"] = i);
567
+ };
568
+ const token = jwt || getToken();
569
+ if (token) headers["X-SaaSquatch-User-Token"] = token;
177
570
  try {
178
- const s = await fetch(o, {
571
+ const res = await fetch(url, {
179
572
  method: "POST",
180
- body: t,
181
- headers: n
182
- }), r = await s.text();
183
- if (!s.ok) throw new Error(r);
184
- return r && JSON.parse(r);
185
- } catch (s) {
186
- throw s;
573
+ body: data,
574
+ headers
575
+ });
576
+ const reply = await res.text();
577
+ if (!res.ok) throw new Error(reply);
578
+ return reply ? JSON.parse(reply) : reply;
579
+ } catch (e) {
580
+ throw e;
187
581
  }
188
582
  }
189
- async function We(o, t, e) {
190
- const n = {
583
+ async function doPut(url, data, jwt) {
584
+ const headers = {
191
585
  Accept: "application/json",
192
586
  "Content-Type": "application/json",
193
587
  "X-SaaSquatch-Referrer": window ? window.location.href : ""
194
- }, i = e || W();
195
- i && (n["X-SaaSquatch-User-Token"] = i);
588
+ };
589
+ const token = jwt || getToken();
590
+ if (token) headers["X-SaaSquatch-User-Token"] = token;
196
591
  try {
197
- const s = await fetch(o, {
198
- headers: n,
592
+ const res = await fetch(url, {
593
+ headers,
199
594
  method: "PUT",
200
595
  credentials: "include",
201
- body: t
202
- }), r = await s.text();
203
- if (!s.ok) throw new Error(r);
204
- return r && JSON.parse(r);
205
- } catch (s) {
206
- throw s;
596
+ body: data
597
+ });
598
+ const reply = await res.text();
599
+ if (!res.ok) throw new Error(reply);
600
+ return reply ? JSON.parse(reply) : reply;
601
+ } catch (e) {
602
+ throw e;
207
603
  }
208
604
  }
209
- const Se = `
605
+ const RENDER_WIDGET_QUERY = `
210
606
  query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {
211
607
  renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {
212
608
  template
@@ -221,7 +617,7 @@ const Se = `
221
617
  }
222
618
  }
223
619
  `;
224
- class K {
620
+ class WidgetApi {
225
621
  /**
226
622
  * Initialize a new {@link WidgetApi} instance.
227
623
  *
@@ -238,13 +634,16 @@ class K {
238
634
  * import {WidgetApi} from '@saasquatch/squatch-js';
239
635
  * let squatchApi = new WidgetApi({tenantAlias:'test_12b5bo1b25125'});
240
636
  */
241
- constructor(t) {
242
- l(this, "tenantAlias");
243
- l(this, "domain");
244
- l(this, "npmCdn");
245
- l(this, "referralCookie", this.squatchReferralCookie);
246
- const n = q(t);
247
- this.tenantAlias = n.tenantAlias, this.domain = n.domain, this.npmCdn = n.npmCdn;
637
+ constructor(config) {
638
+ __publicField(this, "tenantAlias");
639
+ __publicField(this, "domain");
640
+ __publicField(this, "npmCdn");
641
+ __publicField(this, "referralCookie", this.squatchReferralCookie);
642
+ const raw = config;
643
+ const clean = validateConfig(raw);
644
+ this.tenantAlias = clean.tenantAlias;
645
+ this.domain = clean.domain;
646
+ this.npmCdn = clean.npmCdn;
248
647
  }
249
648
  /**
250
649
  * Creates/upserts user, requests widget template.
@@ -260,19 +659,29 @@ class K {
260
659
  *
261
660
  * @return {Promise} string if true, with the widget template, jsOptions and user details.
262
661
  */
263
- upsertUser(t) {
264
- const n = ce(t), {
265
- widgetType: i,
266
- engagementMedium: s = "POPUP",
267
- jwt: r,
268
- locale: a,
269
- user: d
270
- } = n, c = encodeURIComponent(this.tenantAlias), h = d.accountId ? encodeURIComponent(d.accountId) : null, u = d.id ? encodeURIComponent(d.id) : null, p = Re({
271
- widgetType: i,
272
- engagementMedium: s,
273
- locale: a
274
- }), g = `/api/v1/${c}/widget/account/${h}/user/${u}/upsert${p}`, m = this.domain + g, w = (M || window.Cookies).get("_saasquatch");
275
- return w && (d.cookies = w), We(m, JSON.stringify(d), r);
662
+ upsertUser(params) {
663
+ const raw = params;
664
+ const clean = validateWidgetConfig(raw);
665
+ const {
666
+ widgetType,
667
+ engagementMedium = "POPUP",
668
+ jwt,
669
+ locale,
670
+ user
671
+ } = clean;
672
+ const tenantAlias = encodeURIComponent(this.tenantAlias);
673
+ const accountId = user.accountId ? encodeURIComponent(user.accountId) : null;
674
+ const userId = user.id ? encodeURIComponent(user.id) : null;
675
+ const optionalParams = _buildParams({
676
+ widgetType,
677
+ engagementMedium,
678
+ locale
679
+ });
680
+ const path = `/api/v1/${tenantAlias}/widget/account/${accountId}/user/${userId}/upsert${optionalParams}`;
681
+ const url = this.domain + path;
682
+ const cookies = (api$1 || window.Cookies).get("_saasquatch");
683
+ if (cookies) user["cookies"] = cookies;
684
+ return doPut(url, JSON.stringify(user), jwt);
276
685
  }
277
686
  /**
278
687
  * Requests widget template
@@ -287,25 +696,34 @@ class K {
287
696
  * to validate the data (can be disabled)
288
697
  * @return {Promise} template html if true.
289
698
  */
290
- render(t) {
291
- const n = le(t), { widgetType: i, engagementMedium: s = "POPUP", jwt: r, user: a } = n, d = encodeURIComponent(this.tenantAlias), c = a != null && a.accountId ? encodeURIComponent(a.accountId) : null, h = a != null && a.id ? encodeURIComponent(a.id) : null, u = n.locale ?? Te(navigator.language.replace(/\-/g, "_")), p = `/api/v1/${d}/graphql`, g = this.domain + p;
292
- return new Promise(async (m, w) => {
293
- var b;
699
+ render(params) {
700
+ const raw = params;
701
+ const clean = validatePasswordlessConfig(raw);
702
+ const { widgetType, engagementMedium = "POPUP", jwt, user } = clean;
703
+ console.log({ params });
704
+ const tenantAlias = encodeURIComponent(this.tenantAlias);
705
+ const accountId = (user == null ? void 0 : user.accountId) ? encodeURIComponent(user.accountId) : null;
706
+ const userId = (user == null ? void 0 : user.id) ? encodeURIComponent(user.id) : null;
707
+ const locale = clean.locale ?? validateLocale(navigator.language.replace(/\-/g, "_"));
708
+ const path = `/api/v1/${tenantAlias}/graphql`;
709
+ const url = this.domain + path;
710
+ return new Promise(async (resolve, reject) => {
711
+ var _a2;
294
712
  try {
295
- const f = await $e(
296
- g,
297
- Se,
713
+ const res = await doQuery(
714
+ url,
715
+ RENDER_WIDGET_QUERY,
298
716
  {
299
- user: h && c ? { id: h, accountId: c } : null,
300
- engagementMedium: s,
301
- widgetType: i,
302
- locale: u
717
+ user: userId && accountId ? { id: userId, accountId } : null,
718
+ engagementMedium,
719
+ widgetType,
720
+ locale
303
721
  },
304
- r
722
+ jwt
305
723
  );
306
- m((b = f == null ? void 0 : f.data) == null ? void 0 : b.renderWidget);
307
- } catch (f) {
308
- w(f);
724
+ resolve((_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2.renderWidget);
725
+ } catch (e) {
726
+ reject(e);
309
727
  }
310
728
  });
311
729
  }
@@ -315,48 +733,64 @@ class K {
315
733
  * @return {Promise<ReferralCookie>} code referral code if true.
316
734
  */
317
735
  async squatchReferralCookie() {
318
- const t = encodeURIComponent(this.tenantAlias), e = (M || window.Cookies).get("_saasquatch") || "", n = e ? `?cookies=${encodeURIComponent(e)}` : "", i = `${this.domain}/a/${t}/widgets/squatchcookiejson${n}`, s = await qe(i);
736
+ const tenantAlias = encodeURIComponent(this.tenantAlias);
737
+ const _saasquatch = (api$1 || window.Cookies).get("_saasquatch") || "";
738
+ const cookie = _saasquatch ? `?cookies=${encodeURIComponent(_saasquatch)}` : ``;
739
+ const url = `${this.domain}/a/${tenantAlias}/widgets/squatchcookiejson${cookie}`;
740
+ const response = await doGet(url);
319
741
  return Promise.resolve({
320
- ...s,
321
- encodedCookie: e
742
+ ...response,
743
+ encodedCookie: _saasquatch
322
744
  });
323
745
  }
324
746
  }
325
- function Re({
326
- widgetType: o,
327
- engagementMedium: t,
328
- locale: e
747
+ function _buildParams({
748
+ widgetType,
749
+ engagementMedium,
750
+ locale
329
751
  }) {
330
- const n = new URLSearchParams();
331
- return n.append("engagementMedium", t), o && n.append("widgetType", o), e && n.append("locale", e), `?${n.toString()}`;
752
+ const queryParams = new URLSearchParams();
753
+ queryParams.append("engagementMedium", engagementMedium);
754
+ if (widgetType) queryParams.append("widgetType", widgetType);
755
+ if (locale) queryParams.append("locale", locale);
756
+ return `?${queryParams.toString()}`;
332
757
  }
333
758
  /*!
334
759
  * domready (c) Dustin Diaz 2014 - License MIT
335
760
  *
336
761
  */
337
- function Q(o, t) {
338
- let e = [], n, i = o, s = i.documentElement.doScroll, r = "DOMContentLoaded", a = (s ? /^loaded|^c/ : /^loaded|^i|^c/).test(i.readyState);
339
- return a || i.addEventListener(
340
- r,
341
- n = () => {
342
- for (i.removeEventListener(r, n), a = !0; n = e.shift(); ) n();
343
- }
344
- ), a ? setTimeout(t, 0) : e.push(t);
762
+ function domready(targetDoc, fn) {
763
+ let fns = [];
764
+ let listener;
765
+ let doc = targetDoc;
766
+ let hack = doc.documentElement.doScroll;
767
+ let domContentLoaded = "DOMContentLoaded";
768
+ let loaded = (hack ? /^loaded|^c/ : /^loaded|^i|^c/).test(doc.readyState);
769
+ if (!loaded)
770
+ doc.addEventListener(
771
+ domContentLoaded,
772
+ listener = () => {
773
+ doc.removeEventListener(domContentLoaded, listener);
774
+ loaded = true;
775
+ while (listener = fns.shift()) listener();
776
+ }
777
+ );
778
+ return loaded ? setTimeout(fn, 0) : fns.push(fn);
345
779
  }
346
- function L({
347
- value: o,
348
- unit: t
780
+ function formatWidth({
781
+ value,
782
+ unit
349
783
  }) {
350
- switch (t) {
784
+ switch (unit) {
351
785
  case "px":
352
- return `${o}px`;
786
+ return `${value}px`;
353
787
  case "%":
354
- return `${o}%`;
788
+ return `${value}%`;
355
789
  default:
356
- return `${o}px`;
790
+ return `${value}px`;
357
791
  }
358
792
  }
359
- class he {
793
+ class AnalyticsApi {
360
794
  /**
361
795
  * Initialize a new {@link AnalyticsApi} instance.
362
796
  *
@@ -364,733 +798,600 @@ class he {
364
798
  * @param {string} [config.domain='https://app.referralsaasquatch.com'] The server domain.
365
799
  *
366
800
  */
367
- constructor(t) {
368
- l(this, "domain");
369
- var i;
370
- const n = Ue(t);
371
- this.domain = (n == null ? void 0 : n.domain) || ((i = Y()) == null ? void 0 : i.domain) || A;
801
+ constructor(config) {
802
+ __publicField(this, "domain");
803
+ var _a2;
804
+ const raw = config;
805
+ const clean = _validateAnalyticsConfig(raw);
806
+ this.domain = (clean == null ? void 0 : clean["domain"]) || ((_a2 = getConfig()) == null ? void 0 : _a2.domain) || DEFAULT_DOMAIN;
807
+ }
808
+ pushAnalyticsLoadEvent(params) {
809
+ if (!params.externalUserId || !params.externalAccountId) return;
810
+ const tenantAlias = encodeURIComponent(params.tenantAlias);
811
+ const accountId = encodeURIComponent(params.externalAccountId);
812
+ const userId = encodeURIComponent(params.externalUserId);
813
+ const engagementMedium = encodeURIComponent(params.engagementMedium);
814
+ const programId = params.programId ? `&programId=${encodeURIComponent(params.programId)}` : ``;
815
+ const path = `/a/${tenantAlias}/widgets/analytics/loaded?externalAccountId=${accountId}&externalUserId=${userId}&engagementMedium=${engagementMedium}${programId}`;
816
+ const url = this.domain + path;
817
+ return doPost(url, JSON.stringify({}));
818
+ }
819
+ pushAnalyticsShareClickedEvent(params) {
820
+ const tenantAlias = encodeURIComponent(params.tenantAlias);
821
+ const accountId = encodeURIComponent(params.externalAccountId);
822
+ const userId = encodeURIComponent(params.externalUserId);
823
+ const engagementMedium = encodeURIComponent(params.engagementMedium);
824
+ const shareMedium = encodeURIComponent(params.shareMedium);
825
+ const path = `/a/${tenantAlias}/widgets/analytics/shared?externalAccountId=${accountId}&externalUserId=${userId}&engagementMedium=${engagementMedium}&shareMedium=${shareMedium}`;
826
+ const url = this.domain + path;
827
+ return doPost(url, JSON.stringify({}));
828
+ }
829
+ }
830
+ function _validateAnalyticsConfig(raw) {
831
+ if (!isObject$1(raw)) throw new Error("'options' should be an object");
832
+ return raw;
833
+ }
834
+ const _log$8 = browserExports.debug("squatch-js:widget");
835
+ class Widget {
836
+ constructor(params) {
837
+ __publicField(this, "type");
838
+ __publicField(this, "content");
839
+ __publicField(this, "analyticsApi");
840
+ __publicField(this, "widgetApi");
841
+ __publicField(this, "context");
842
+ __publicField(this, "npmCdn");
843
+ __publicField(this, "container");
844
+ __publicField(this, "loadEventListener", null);
845
+ var _a2;
846
+ _log$8("widget initializing ...");
847
+ this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
848
+ this.type = params.type;
849
+ this.widgetApi = params.api;
850
+ this.npmCdn = params.npmCdn;
851
+ this.analyticsApi = new AnalyticsApi({ domain: params.domain });
852
+ this.context = params.context;
853
+ this.container = ((_a2 = params.context) == null ? void 0 : _a2.container) || params.container;
854
+ }
855
+ _findElement() {
856
+ let element;
857
+ if (typeof this.container === "string") {
858
+ element = document.querySelector(this.container);
859
+ _log$8("loading widget with selector", element);
860
+ } else if (this.container instanceof HTMLElement) {
861
+ element = this.container;
862
+ _log$8("loading widget with container", element);
863
+ } else if (this.container) {
864
+ element = null;
865
+ _log$8("container must be an HTMLElement or string", this.container);
866
+ } else {
867
+ element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed") || document.querySelector("#impactembed") || document.querySelector(".impactembed");
868
+ _log$8("loading widget with default selector", element);
869
+ }
870
+ if (!(element instanceof HTMLElement))
871
+ throw new Error(
872
+ `element with selector '${this.container || "#squatchembed, .squatchembed, #impactembed, or .impactembed"}' not found.'`
873
+ );
874
+ return element;
875
+ }
876
+ _createFrame(options) {
877
+ const frame = document.createElement("iframe");
878
+ frame["squatchJsApi"] = this;
879
+ frame.id = "squatchFrame";
880
+ frame.width = "100%";
881
+ frame.src = "about:blank";
882
+ frame.scrolling = "no";
883
+ frame.setAttribute(
884
+ "style",
885
+ "border: 0; background-color: none; width: 1px; min-width: 100%;"
886
+ );
887
+ if (options == null ? void 0 : options.minWidth) frame.style.minWidth = options.minWidth;
888
+ if (options == null ? void 0 : options.maxWidth) frame.style.maxWidth = options.maxWidth;
889
+ if ((options == null ? void 0 : options.maxWidth) || (options == null ? void 0 : options.minWidth)) {
890
+ frame.style.width = "100%";
891
+ }
892
+ if (options == null ? void 0 : options.initialHeight) {
893
+ frame.height = options.initialHeight;
894
+ }
895
+ return frame;
896
+ }
897
+ _findFrame() {
898
+ const element = this.container ? this._findElement() : document.body;
899
+ const parent = element.shadowRoot || element;
900
+ return parent.querySelector(
901
+ "iframe#squatchFrame"
902
+ );
903
+ }
904
+ _detachLoadEventListener(frameDoc) {
905
+ if (this.loadEventListener) {
906
+ frameDoc.removeEventListener(
907
+ "sq:user-registration",
908
+ this.loadEventListener
909
+ );
910
+ this.loadEventListener = null;
911
+ }
912
+ }
913
+ _attachLoadEventListener(frameDoc, sqh) {
914
+ if (this.loadEventListener === null) {
915
+ this.loadEventListener = (e) => {
916
+ this._loadEvent({
917
+ ...sqh,
918
+ userId: e.detail.userId,
919
+ accountId: e.detail.accountId
920
+ });
921
+ };
922
+ frameDoc.addEventListener("sq:user-registration", this.loadEventListener);
923
+ }
924
+ }
925
+ _loadEvent(sqh) {
926
+ var _a2;
927
+ if (!sqh) return;
928
+ if (!isObject$1(sqh)) {
929
+ throw new Error("Widget Load event identity property is not an object");
930
+ }
931
+ let params;
932
+ if ("programId" in sqh) {
933
+ if (!sqh.tenantAlias || !sqh.accountId || !sqh.userId || !sqh.engagementMedium)
934
+ throw new Error("Widget Load event missing required properties");
935
+ params = {
936
+ tenantAlias: sqh.tenantAlias,
937
+ externalAccountId: sqh.accountId,
938
+ externalUserId: sqh.userId,
939
+ engagementMedium: sqh.engagementMedium,
940
+ programId: sqh.programId
941
+ };
942
+ } else {
943
+ const { analytics, mode } = sqh;
944
+ params = {
945
+ tenantAlias: analytics.attributes.tenant,
946
+ externalAccountId: analytics.attributes.accountId,
947
+ externalUserId: analytics.attributes.userId,
948
+ engagementMedium: mode.widgetMode
949
+ };
950
+ }
951
+ (_a2 = this.analyticsApi.pushAnalyticsLoadEvent(params)) == null ? void 0 : _a2.then((response) => {
952
+ _log$8(`${params.engagementMedium} loaded event recorded.`);
953
+ }).catch((ex) => {
954
+ _log$8(`ERROR: pushAnalyticsLoadEvent() ${ex}`);
955
+ });
956
+ }
957
+ _shareEvent(sqh, medium) {
958
+ if (sqh) {
959
+ this.analyticsApi.pushAnalyticsShareClickedEvent({
960
+ tenantAlias: sqh.analytics.attributes.tenant,
961
+ externalAccountId: sqh.analytics.attributes.accountId,
962
+ externalUserId: sqh.analytics.attributes.userId,
963
+ engagementMedium: sqh.mode.widgetMode,
964
+ shareMedium: medium
965
+ }).then((response) => {
966
+ _log$8(
967
+ `${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`
968
+ );
969
+ }).catch((ex) => {
970
+ _log$8(`ERROR: pushAnalyticsShareClickedEvent() ${ex}`);
971
+ });
972
+ }
973
+ }
974
+ _error(rs, mode = "modal", style = "") {
975
+ const errorTemplate = `<!DOCTYPE html>
976
+ <!--[if IE 7]><html class="ie7 oldie" lang="en"><![endif]-->
977
+ <!--[if IE 8]><html class="ie8 oldie" lang="en"><![endif]-->
978
+ <!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
979
+ <head>
980
+ <link rel="stylesheet" media="all" href="https://fast.ssqt.io/assets/css/widget/errorpage.css">
981
+ <style>
982
+ ${style}
983
+ </style>
984
+ </head>
985
+ <body>
986
+
987
+ <div class="squatch-container ${mode}" style="width:100%">
988
+ <div class="errorheader">
989
+ <button type="button" class="close" onclick="window.frameElement.squatchJsApi.close();">&times;</button>
990
+ <p class="errortitle">Error</p>
991
+ </div>
992
+ <div class="errorbody">
993
+ <div class="sadface"><img src="https://fast.ssqt.io/assets/images/face.png"></div>
994
+ <h4>Our referral program is temporarily unavailable.</h4><br>
995
+ <p>Please reload the page or check back later.</p>
996
+ <p>If the persists please contact our support team.</p>
997
+ <br>
998
+ <br>
999
+ <div class="right-align errtxt">
1000
+ Error Code: ${rs}
1001
+ </div>
1002
+ </div>
1003
+ </div>
1004
+ </body>
1005
+ </html>`;
1006
+ return errorTemplate;
1007
+ }
1008
+ async _findInnerContainer(frame) {
1009
+ const { contentWindow } = frame;
1010
+ if (!contentWindow)
1011
+ throw new Error("Squatch.js frame inner frame is empty");
1012
+ const frameDoc = contentWindow.document;
1013
+ function search() {
1014
+ const containers = frameDoc.getElementsByTagName("sqh-global-container");
1015
+ const legacyContainers = frameDoc.getElementsByClassName("squatch-container");
1016
+ const fallback = containers.length > 0 ? containers[0] : legacyContainers.length > 0 ? legacyContainers[0] : null;
1017
+ return fallback;
1018
+ }
1019
+ let found = null;
1020
+ for (let i = 0; i < 5; i++) {
1021
+ found = search();
1022
+ if (found) break;
1023
+ await delay(100);
1024
+ }
1025
+ if (!found) {
1026
+ return frameDoc.body;
1027
+ }
1028
+ return found;
372
1029
  }
373
- pushAnalyticsLoadEvent(t) {
374
- if (!t.externalUserId || !t.externalAccountId) return;
375
- const e = encodeURIComponent(t.tenantAlias), n = encodeURIComponent(t.externalAccountId), i = encodeURIComponent(t.externalUserId), s = encodeURIComponent(t.engagementMedium), r = t.programId ? `&programId=${encodeURIComponent(t.programId)}` : "", a = `/a/${e}/widgets/analytics/loaded?externalAccountId=${n}&externalUserId=${i}&engagementMedium=${s}${r}`, d = this.domain + a;
376
- return X(d, JSON.stringify({}));
1030
+ /**
1031
+ * Reloads the current widget, makes updated request to API and renders result.
1032
+ * Primarily for Classic widgets with registration
1033
+ * @param param0 Form field values
1034
+ * @param jwt JWT for API authentication
1035
+ */
1036
+ reload({ email, firstName, lastName }, jwt) {
1037
+ const frame = this._findFrame();
1038
+ if (!frame) throw new Error("Could not find widget iframe");
1039
+ const frameWindow = frame.contentWindow;
1040
+ const engagementMedium = this.context.engagementMedium || "POPUP";
1041
+ if (!frameWindow) {
1042
+ throw new Error("Frame needs a content window");
1043
+ }
1044
+ let response;
1045
+ if (this.context.type === "upsert") {
1046
+ if (!this.context.user) throw new Error("Can't reload without user ids");
1047
+ let userObj = {
1048
+ email: email || null,
1049
+ firstName: firstName || null,
1050
+ lastName: lastName || null,
1051
+ id: this.context.user.id,
1052
+ accountId: this.context.user.accountId
1053
+ };
1054
+ response = this.widgetApi.upsertUser({
1055
+ user: userObj,
1056
+ engagementMedium,
1057
+ widgetType: this.type,
1058
+ jwt
1059
+ });
1060
+ } else if (this.context.type === "passwordless") {
1061
+ response = this.widgetApi.render({
1062
+ user: void 0,
1063
+ engagementMedium,
1064
+ widgetType: this.type,
1065
+ jwt: void 0
1066
+ });
1067
+ } else {
1068
+ throw new Error("can't reload an error widget");
1069
+ }
1070
+ response.then(({ template }) => {
1071
+ if (template) {
1072
+ this.content = template;
1073
+ this.__deprecated__register(
1074
+ frame,
1075
+ { email, engagementMedium },
1076
+ () => {
1077
+ this.load();
1078
+ engagementMedium === "POPUP" && this.open();
1079
+ }
1080
+ );
1081
+ }
1082
+ }).catch(({ message }) => {
1083
+ _log$8(`${message}`);
1084
+ });
377
1085
  }
378
- pushAnalyticsShareClickedEvent(t) {
379
- const e = encodeURIComponent(t.tenantAlias), n = encodeURIComponent(t.externalAccountId), i = encodeURIComponent(t.externalUserId), s = encodeURIComponent(t.engagementMedium), r = encodeURIComponent(t.shareMedium), a = `/a/${e}/widgets/analytics/shared?externalAccountId=${n}&externalUserId=${i}&engagementMedium=${s}&shareMedium=${r}`, d = this.domain + a;
380
- return X(d, JSON.stringify({}));
1086
+ __deprecated__register(frame, params, onClick) {
1087
+ const frameWindow = frame.contentWindow;
1088
+ const frameDoc = frameWindow.document;
1089
+ const showStatsBtn = frameDoc.createElement("button");
1090
+ const registerForm = frameDoc.getElementsByClassName("squatch-register")[0];
1091
+ if (registerForm) {
1092
+ showStatsBtn.className = "btn btn-primary";
1093
+ showStatsBtn.id = "show-stats-btn";
1094
+ showStatsBtn.textContent = this.type === "REFERRER_WIDGET" ? "Show Stats" : "Show Reward";
1095
+ const widgetStyle = params.engagementMedium === "POPUP" ? "margin-top: 10px; max-width: 130px; width: 100%;" : "margin-top: 10px;";
1096
+ showStatsBtn.setAttribute("style", widgetStyle);
1097
+ showStatsBtn.onclick = onClick;
1098
+ registerForm.style.paddingTop = "30px";
1099
+ registerForm.innerHTML = `<p><strong>${params.email}</strong><br>Has been successfully registered</p>`;
1100
+ registerForm.appendChild(showStatsBtn);
1101
+ }
381
1102
  }
382
1103
  }
383
- function Ue(o) {
384
- if (!I(o)) throw new Error("'options' should be an object");
385
- return o;
1104
+ function delay(duration) {
1105
+ return new Promise((resolve) => {
1106
+ setTimeout(resolve, duration);
1107
+ });
386
1108
  }
387
- const ue = ({
388
- type: o = "verified-access",
389
- height: t = "500px"
390
- }) => {
391
- const e = "#e0e0e0";
392
- return `
393
- <style>
394
- * {
395
- box-sizing: border-box;
396
- padding: 0;
397
- margin: 0;
1109
+ const _log$7 = browserExports.debug("squatch-js:EMBEDwidget");
1110
+ class EmbedWidget extends Widget {
1111
+ constructor(params, container) {
1112
+ super(params);
1113
+ __publicField(this, "show", this.open);
1114
+ __publicField(this, "hide", this.close);
1115
+ if (container) {
1116
+ this.container = container;
1117
+ }
1118
+ }
1119
+ async load() {
1120
+ var _a2, _b, _c, _d, _e, _f, _g;
1121
+ const brandingConfig = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1122
+ const initialHeight = brandingConfig == null ? void 0 : brandingConfig.loadingHeight;
1123
+ const sizes = (_c = brandingConfig == null ? void 0 : brandingConfig.widgetSize) == null ? void 0 : _c.embeddedWidgets;
1124
+ const maxWidth = (sizes == null ? void 0 : sizes.maxWidth) ? formatWidth(sizes.maxWidth) : "";
1125
+ const minWidth = (sizes == null ? void 0 : sizes.minWidth) ? formatWidth(sizes.minWidth) : "";
1126
+ const frame = this._createFrame({
1127
+ minWidth,
1128
+ maxWidth,
1129
+ initialHeight
1130
+ });
1131
+ const element = this._findElement();
1132
+ if ((_d = this.context) == null ? void 0 : _d.container) {
1133
+ element.style.visibility = "hidden";
1134
+ element.style.height = "0";
1135
+ element.style["overflow-y"] = "hidden";
1136
+ }
1137
+ if (this.container) {
1138
+ if (element.shadowRoot) {
1139
+ if (((_e = element.shadowRoot.lastChild) == null ? void 0 : _e.nodeName) === "IFRAME") {
1140
+ element.shadowRoot.replaceChild(frame, element.shadowRoot.lastChild);
1141
+ } else {
1142
+ element.shadowRoot.appendChild(frame);
398
1143
  }
399
-
400
- .widget-container {
401
- background: white;
402
- width: 100%;
403
- padding: 40px;
404
- box-sizing: border-box;
405
- overflow: hidden;
406
- }
407
-
408
- @keyframes shimmer {
409
- 0% { background-position: -100% 0; }
410
- 100% { background-position: 100% 0; }
1144
+ } else if (element.firstChild) {
1145
+ element.replaceChild(frame, element.firstChild);
1146
+ } else {
1147
+ element.appendChild(frame);
411
1148
  }
1149
+ } else if (!element.firstChild || element.firstChild.nodeName === "#text") {
1150
+ element.appendChild(frame);
1151
+ }
1152
+ const { contentWindow } = frame;
1153
+ if (!contentWindow) {
1154
+ throw new Error("Frame needs a content window");
1155
+ }
1156
+ const frameDoc = contentWindow.document;
1157
+ frameDoc.open();
1158
+ const domain = this.widgetApi.domain;
1159
+ frameDoc.write(`
1160
+ ${((_f = brandingConfig == null ? void 0 : brandingConfig.main) == null ? void 0 : _f.brandFont) ? `
1161
+ <link rel="preconnect" href="https://fast${domain === "https://staging.referralsaasquatch.com" && "-staging"}.ssqt.io">
1162
+ <link rel="preconnect" href="https://fonts.gstatic.com">
1163
+ <link rel="preconnect" href="https://fonts.googleapis.com">
1164
+ <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent(
1165
+ (_g = brandingConfig == null ? void 0 : brandingConfig.main) == null ? void 0 : _g.brandFont
1166
+ )}" as="style">` : ""}
1167
+ <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>
1168
+ <style data-styles>
1169
+ html { visibility:hidden;}
1170
+ </style>
1171
+ ${this.content}
412
1172
 
413
- .skeleton {
414
- background: ${e};
415
- background: linear-gradient(
416
- 90deg,
417
- ${e} 25%,
418
- #f5f5f5 50%,
419
- ${e} 75%
420
- );
421
- background-size: 200% 100%;
422
- animation: shimmer 1.5s infinite linear;
423
- border-radius: 6px;
424
- margin-bottom: 12px;
1173
+ `);
1174
+ frameDoc.close();
1175
+ domready(frameDoc, async () => {
1176
+ const _sqh = contentWindow.squatch || contentWindow.widgetIdent;
1177
+ frame.height = initialHeight || frameDoc.body.scrollHeight;
1178
+ console.log({ height: frameDoc.body.scrollHeight });
1179
+ const ro = new contentWindow["ResizeObserver"]((entries) => {
1180
+ for (const entry of entries) {
1181
+ const { height } = entry.contentRect;
1182
+ frame.height = height;
1183
+ }
1184
+ });
1185
+ const container = await this._findInnerContainer(frame);
1186
+ ro.observe(container);
1187
+ if (this._shouldFireLoadEvent()) {
1188
+ this._loadEvent(_sqh);
1189
+ _log$7("loaded");
1190
+ } else if (frameDoc) {
1191
+ this._attachLoadEventListener(frameDoc, _sqh);
425
1192
  }
426
-
427
- /* Typography Skeletons */
428
- .sk-title-lg { height: 36px; width: 80%; margin-bottom: 16px; }
429
- .sk-title-md { height: 28px; width: 30%; margin-bottom: 20px; margin-top: 40px; }
430
- .sk-text { height: 16px; width: 90%; margin-bottom: 8px; }
431
- .sk-text-short { width: 40%; }
432
- .sk-label { height: 14px; width: 25%; margin-bottom: 10px; }
433
-
434
- /* Layouts */
435
- .hero-section {
436
- display: flex;
437
- gap: 40px;
438
- margin-bottom: 40px;
439
- padding-bottom: 40px;
440
- flex-direction: row;
441
- height: 100%;
442
- /* Removed border-bottom */
443
- }
444
-
445
- .hero-content {
446
- flex: 1;
447
- display: flex;
448
- flex-direction: column;
449
- justify-content: center;
450
- }
451
-
452
- .hero-image {
453
- flex: 1;
454
- height: 300px;
455
- border-radius: 12px;
456
- }
457
-
458
- /* -- Specific Instant Access Overrides -- */
459
- .instant-access-layout {
460
- margin-bottom: 0;
461
- padding-bottom: 0;
462
- align-items: center;
463
- }
464
- .ia-image {
465
- height: 400px;
466
- }
467
- .ia-center {
468
- margin-left: auto;
469
- margin-right: auto;
470
- }
471
- .ia-content {
472
- align-items: center;
473
- text-align: center;
474
- }
475
- .sk-btn-action {
476
- height: 45px;
477
- width: 140px;
478
- border-radius: 6px;
479
- margin: 24px auto;
480
- }
481
- .input-group {
482
- display: flex;
483
- gap: 10px;
484
- width: 100%;
485
- max-width: 400px;
486
- }
487
- .sk-btn-copy {
488
- height: 50px;
489
- width: 120px;
490
- border-radius: 8px;
491
- }
492
- /* ------------------------------------- */
493
-
494
- .share-section { margin-bottom: 40px; }
495
- .sk-input { height: 50px; width: 100%; border-radius: 8px; margin-bottom: 16px; }
496
-
497
- .social-buttons { display: flex; gap: 12px; }
498
- .sk-btn-social { flex: 1; height: 50px; border-radius: 8px; }
499
-
500
- .stats-section {
501
- display: flex;
502
- gap: 24px;
503
- margin-bottom: 40px;
504
- padding: 30px 0;
505
- /* Removed border-top and border-bottom */
506
- }
507
- .stat-card { flex: 1; display: flex; flex-direction: column; align-items: center; }
508
- .stat-divider { padding-left: 24px; }
509
- .sk-stat-num { height: 48px; width: 120px; margin-bottom: 8px; }
510
- .sk-stat-label { height: 18px; width: 80px; }
511
-
512
- /* Table Styles */
513
- .table-header { display: flex; gap: 16px; margin-bottom: 16px; }
514
- .sk-th { height: 16px; }
515
- .table-row {
516
- display: flex;
517
- align-items: center;
518
- gap: 16px;
519
- padding: 16px 0;
520
- /* Removed border-bottom */
521
- }
522
-
523
- .col-user { flex: 2; }
524
- .col-status { flex: 1; }
525
- .col-reward { flex: 2; }
526
- .col-date { flex: 1; }
527
-
528
- .sk-badge { height: 28px; width: 90px; border-radius: 14px; }
529
- .sk-reward-block { height: 36px; width: 100%; border-radius: 6px; }
530
-
531
- .pagination { display: flex; justify-content: flex-end; gap: 8px; margin-top: 24px; }
532
- .sk-btn-page { height: 36px; width: 64px; border-radius: 6px; margin-bottom: 0; }
533
-
534
- @media (max-width: 768px) {
535
- body { padding: 20px; }
536
- .widget-container { padding: 24px; }
537
-
538
- .hero-section { flex-direction: column-reverse; gap: 24px; }
539
- .instant-access-layout { flex-direction: column; }
540
-
541
- .hero-image { height: 220px; width: 100%; }
542
- .sk-title-lg { width: 100%; }
543
-
544
- .col-date { display: none; }
545
- }
546
- </style>
547
-
548
- <div class="widget-container">
549
- ${o === "verified-access" ? `
550
- <div class="hero-section">
551
- <div class="hero-content">
552
- <div class="skeleton sk-title-lg"></div>
553
- <div class="skeleton sk-text"></div>
554
- <div class="skeleton sk-text sk-text-short"></div>
555
- </div>
556
- <div class="skeleton hero-image"></div>
557
- </div>
558
-
559
- <div class="share-section">
560
- <div class="skeleton sk-label"></div>
561
- <div class="skeleton sk-input"></div>
562
- <div class="social-buttons">
563
- <div class="skeleton sk-btn-social"></div>
564
- <div class="skeleton sk-btn-social"></div>
565
- <div class="skeleton sk-btn-social"></div>
566
- <div class="skeleton sk-btn-social"></div>
567
- </div>
568
- </div>
569
-
570
- <div class="skeleton sk-title-md" style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"></div>
571
- <div class="skeleton sk-text" style="width: 60%; margin-left: auto; margin-right: auto"></div>
572
-
573
- <div class="stats-section">
574
- <div class="stat-card">
575
- <div class="skeleton sk-stat-num"></div>
576
- <div class="skeleton sk-stat-label"></div>
577
- </div>
578
- <div class="stat-card stat-divider">
579
- <div class="skeleton sk-stat-num"></div>
580
- <div class="skeleton sk-stat-label"></div>
581
- </div>
582
- </div>
583
-
584
- <div class="skeleton sk-title-md"></div>
585
-
586
- <div class="table-header">
587
- <div class="skeleton sk-th col-user"></div>
588
- <div class="skeleton sk-th col-status"></div>
589
- <div class="skeleton sk-th col-reward"></div>
590
- <div class="skeleton sk-th col-date"></div>
591
- </div>
592
-
593
- <div class="table-row">
594
- <div class="col-user"><div class="skeleton sk-text" style="width: 70%; margin: 0"></div></div>
595
- <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>
596
- <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>
597
- <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>
598
- </div>
599
-
600
- <div class="table-row">
601
- <div class="col-user"><div class="skeleton sk-text" style="width: 60%; margin: 0"></div></div>
602
- <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>
603
- <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>
604
- <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>
605
- </div>
606
-
607
- <div class="table-row">
608
- <div class="col-user"><div class="skeleton sk-text" style="width: 75%; margin: 0"></div></div>
609
- <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>
610
- <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>
611
- <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>
612
- </div>
613
-
614
- <div class="pagination">
615
- <div class="skeleton sk-btn-page"></div>
616
- <div class="skeleton sk-btn-page"></div>
617
- </div>
618
- ` : `
619
- <div class="hero-section instant-access-layout">
620
- <div class="skeleton hero-image ia-image"></div>
621
-
622
- <div class="hero-content ia-content">
623
- <div class="skeleton sk-title-lg ia-center"></div>
624
- <div class="skeleton sk-text ia-center"></div>
625
-
626
- <div class="skeleton sk-btn-action"></div>
627
-
628
- <div class="skeleton sk-label"></div>
629
- <div class="input-group">
630
- <div class="skeleton sk-input"></div>
631
- <div class="skeleton sk-btn-copy"></div>
632
- </div>
633
-
634
- <div class="skeleton sk-text-short ia-center" style="margin-top: 20px; width: 30%"></div>
635
- <div class="skeleton sk-text-short ia-center" style="width: 20%"></div>
636
- </div>
637
- </div>
638
- `}
639
- </div>
640
- `;
641
- }, Pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
642
- __proto__: null,
643
- getSkeleton: ue
644
- }, Symbol.toStringTag, { value: "Module" })), y = k("squatch-js:widget");
645
- class pe {
646
- constructor(t) {
647
- l(this, "type");
648
- l(this, "content");
649
- l(this, "analyticsApi");
650
- l(this, "widgetApi");
651
- l(this, "context");
652
- l(this, "npmCdn");
653
- l(this, "container");
654
- l(this, "loadEventListener", null);
655
- var e;
656
- y("widget initializing ..."), this.content = t.content === "error" ? this._error(t.rsCode) : t.content, this.type = t.type, this.widgetApi = t.api, this.npmCdn = t.npmCdn, this.analyticsApi = new he({ domain: t.domain }), this.context = t.context, this.container = ((e = t.context) == null ? void 0 : e.container) || t.container;
657
- }
658
- _findElement() {
659
- let t;
660
- if (typeof this.container == "string" ? (t = document.querySelector(this.container), y("loading widget with selector", t)) : this.container instanceof HTMLElement ? (t = this.container, y("loading widget with container", t)) : this.container ? (t = null, y("container must be an HTMLElement or string", this.container)) : (t = document.querySelector("#squatchembed") || document.querySelector(".squatchembed") || document.querySelector("#impactembed") || document.querySelector(".impactembed"), y("loading widget with default selector", t)), !(t instanceof HTMLElement))
661
- throw new Error(
662
- `element with selector '${this.container || "#squatchembed, .squatchembed, #impactembed, or .impactembed"}' not found.'`
663
- );
664
- return t;
665
- }
666
- _createFrame(t) {
667
- const e = document.createElement("iframe");
668
- return e.squatchJsApi = this, e.id = "squatchFrame", e.width = "100%", e.src = "about:blank", e.scrolling = "no", e.setAttribute(
669
- "style",
670
- "border: 0; background-color: none; width: 1px; min-width: 100%; display: block;"
671
- ), t != null && t.minWidth && (e.style.minWidth = t.minWidth), t != null && t.maxWidth && (e.style.maxWidth = t.maxWidth), (t != null && t.maxWidth || t != null && t.minWidth) && (e.style.width = "100%"), t != null && t.initialHeight && (e.height = String(t.initialHeight)), e;
672
- }
673
- _findFrame() {
674
- const t = this.container ? this._findElement() : document.body;
675
- return (t.shadowRoot || t).querySelector(
676
- "iframe#squatchFrame"
677
- );
678
- }
679
- _detachLoadEventListener(t) {
680
- this.loadEventListener && (t.removeEventListener(
681
- "sq:user-registration",
682
- this.loadEventListener
683
- ), this.loadEventListener = null);
684
- }
685
- _attachLoadEventListener(t, e) {
686
- this.loadEventListener === null && (this.loadEventListener = (n) => {
687
- this._loadEvent({
688
- ...e,
689
- userId: n.detail.userId,
690
- accountId: n.detail.accountId
691
- });
692
- }, t.addEventListener("sq:user-registration", this.loadEventListener));
693
- }
694
- _loadEvent(t) {
695
- var n;
696
- if (!t) return;
697
- if (!I(t))
698
- throw new Error("Widget Load event identity property is not an object");
699
- let e;
700
- if ("programId" in t) {
701
- if (!t.tenantAlias || !t.accountId || !t.userId || !t.engagementMedium)
702
- throw new Error("Widget Load event missing required properties");
703
- e = {
704
- tenantAlias: t.tenantAlias,
705
- externalAccountId: t.accountId,
706
- externalUserId: t.userId,
707
- engagementMedium: t.engagementMedium,
708
- programId: t.programId
709
- };
710
- } else {
711
- const { analytics: i, mode: s } = t;
712
- e = {
713
- tenantAlias: i.attributes.tenant,
714
- externalAccountId: i.attributes.accountId,
715
- externalUserId: i.attributes.userId,
716
- engagementMedium: s.widgetMode
717
- };
718
- }
719
- (n = this.analyticsApi.pushAnalyticsLoadEvent(e)) == null || n.then((i) => {
720
- y(`${e.engagementMedium} loaded event recorded.`);
721
- }).catch((i) => {
722
- y(`ERROR: pushAnalyticsLoadEvent() ${i}`);
723
- });
724
- }
725
- _shareEvent(t, e) {
726
- t && this.analyticsApi.pushAnalyticsShareClickedEvent({
727
- tenantAlias: t.analytics.attributes.tenant,
728
- externalAccountId: t.analytics.attributes.accountId,
729
- externalUserId: t.analytics.attributes.userId,
730
- engagementMedium: t.mode.widgetMode,
731
- shareMedium: e
732
- }).then((n) => {
733
- y(
734
- `${t.mode.widgetMode} share ${e} event recorded. ${n}`
735
- );
736
- }).catch((n) => {
737
- y(`ERROR: pushAnalyticsShareClickedEvent() ${n}`);
738
- });
739
- }
740
- _error(t, e = "modal", n = "") {
741
- return `<!DOCTYPE html>
742
- <!--[if IE 7]><html class="ie7 oldie" lang="en"><![endif]-->
743
- <!--[if IE 8]><html class="ie8 oldie" lang="en"><![endif]-->
744
- <!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
745
- <head>
746
- <link rel="stylesheet" media="all" href="https://fast.ssqt.io/assets/css/widget/errorpage.css">
747
- <style>
748
- ${n}
749
- </style>
750
- </head>
751
- <body>
752
-
753
- <div class="squatch-container ${e}" style="width:100%">
754
- <div class="errorheader">
755
- <button type="button" class="close" onclick="window.frameElement.squatchJsApi.close();">&times;</button>
756
- <p class="errortitle">Error</p>
757
- </div>
758
- <div class="errorbody">
759
- <div class="sadface"><img src="https://fast.ssqt.io/assets/images/face.png"></div>
760
- <h4>Our referral program is temporarily unavailable.</h4><br>
761
- <p>Please reload the page or check back later.</p>
762
- <p>If the persists please contact our support team.</p>
763
- <br>
764
- <br>
765
- <div class="right-align errtxt">
766
- Error Code: ${t}
767
- </div>
768
- </div>
769
- </div>
770
- </body>
771
- </html>`;
772
- }
773
- async _findInnerContainer(t) {
774
- const { contentWindow: e } = t;
775
- if (!e)
776
- throw new Error("Squatch.js frame inner frame is empty");
777
- const n = e.document;
778
- function i() {
779
- const r = n.getElementsByTagName("sqh-global-container"), a = n.getElementsByClassName("squatch-container");
780
- return r.length > 0 ? r[0] : a.length > 0 ? a[0] : null;
781
- }
782
- let s = null;
783
- for (let r = 0; r < 5 && (s = i(), !s); r++)
784
- await Me(100);
785
- return s || n.body;
786
- }
787
- /**
788
- * Returns HTML for an in-iframe skeleton preload overlay that is removed
789
- * once all Stencil component chunks have loaded and been hydrated.
790
- *
791
- * Uses a MutationObserver to detect when components receive the `hydrated`
792
- * class, debouncing removal so the skeleton stays visible until all chunks
793
- * have finished loading. Includes a timeout fallback.
794
- *
795
- * Only generates content for mint-components widgets; returns empty string otherwise.
796
- */
797
- _getSkeletonPreloadHTML(t, e) {
798
- if (!t) return "";
799
- const n = this.context.type === "passwordless" ? "instant-access" : "verified-access", i = ue({
800
- type: n,
801
- height: "100%"
802
- });
803
- return `
804
- <div id="sq-preload" style="visibility: visible; position: absolute; top: 0; left: 0; width: 100%; z-index: 9999; background: ${e || "white"};">
805
- ${i}
806
- </div>
807
- <script>(${Le.toString()})()<\/script>
808
- `;
809
- }
810
- /**
811
- * Reloads the current widget, makes updated request to API and renders result.
812
- * Primarily for Classic widgets with registration
813
- * @param param0 Form field values
814
- * @param jwt JWT for API authentication
815
- */
816
- reload({ email: t, firstName: e, lastName: n }, i) {
817
- const s = this._findFrame();
818
- if (!s) throw new Error("Could not find widget iframe");
819
- const r = s.contentWindow, a = this.context.engagementMedium || "POPUP";
820
- if (!r)
821
- throw new Error("Frame needs a content window");
822
- let d;
823
- if (this.context.type === "upsert") {
824
- if (!this.context.user) throw new Error("Can't reload without user ids");
825
- let c = {
826
- email: t || null,
827
- firstName: e || null,
828
- lastName: n || null,
829
- id: this.context.user.id,
830
- accountId: this.context.user.accountId
831
- };
832
- d = this.widgetApi.upsertUser({
833
- user: c,
834
- engagementMedium: a,
835
- widgetType: this.type,
836
- jwt: i
837
- });
838
- } else if (this.context.type === "passwordless")
839
- d = this.widgetApi.render({
840
- user: void 0,
841
- engagementMedium: a,
842
- widgetType: this.type,
843
- jwt: void 0
844
- });
845
- else
846
- throw new Error("can't reload an error widget");
847
- d.then(({ template: c }) => {
848
- c && (this.content = c, this.__deprecated__register(
849
- s,
850
- { email: t, engagementMedium: a },
851
- () => {
852
- this.load(), a === "POPUP" && this.open();
853
- }
854
- ));
855
- }).catch(({ message: c }) => {
856
- y(`${c}`);
857
- });
858
- }
859
- __deprecated__register(t, e, n) {
860
- const s = t.contentWindow.document, r = s.createElement("button"), a = s.getElementsByClassName("squatch-register")[0];
861
- if (a) {
862
- r.className = "btn btn-primary", r.id = "show-stats-btn", r.textContent = this.type === "REFERRER_WIDGET" ? "Show Stats" : "Show Reward";
863
- const d = e.engagementMedium === "POPUP" ? "margin-top: 10px; max-width: 130px; width: 100%;" : "margin-top: 10px;";
864
- r.setAttribute("style", d), r.onclick = n, a.style.paddingTop = "30px", a.innerHTML = `<p><strong>${e.email}</strong><br>Has been successfully registered</p>`, a.appendChild(r);
865
- }
866
- }
867
- }
868
- function Me(o) {
869
- return new Promise((t) => {
870
- setTimeout(t, o);
871
- });
872
- }
873
- function Le() {
874
- var o = setTimeout(t, 1e4);
875
- function t() {
876
- var n = document.getElementById("sq-preload");
877
- n && n.remove(), clearTimeout(o);
878
- }
879
- function e() {
880
- var n = /* @__PURE__ */ new Set();
881
- if (document.querySelectorAll("*").forEach(function(i) {
882
- i.tagName.includes("-") && n.add(i.tagName.toLowerCase());
883
- }), !n.size) return t();
884
- Promise.all(
885
- Array.from(n).map(function(i) {
886
- return customElements.whenDefined(i);
887
- })
888
- ).then(function() {
889
- requestAnimationFrame(function() {
890
- requestAnimationFrame(t);
891
- });
892
- });
893
- }
894
- document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : setTimeout(e, 0);
895
- }
896
- const E = k("squatch-js:EMBEDwidget");
897
- class O extends pe {
898
- constructor(e, n) {
899
- super(e);
900
- l(this, "show", this.open);
901
- l(this, "hide", this.close);
902
- n && (this.container = n);
903
- }
904
- async load() {
905
- var m, w, b, f, _, ee, te, ne, ie;
906
- const e = (w = (m = this.context.widgetConfig) == null ? void 0 : m.values) == null ? void 0 : w.brandingConfig, n = (b = this.content) == null ? void 0 : b.includes("mint-components"), i = (e == null ? void 0 : e.loadingHeight) || 500, s = (f = e == null ? void 0 : e.widgetSize) == null ? void 0 : f.embeddedWidgets, r = s != null && s.maxWidth ? L(s.maxWidth) : "", a = s != null && s.minWidth ? L(s.minWidth) : "", d = this._createFrame({
907
- minWidth: a,
908
- maxWidth: r,
909
- initialHeight: i
910
- }), c = this._findElement();
911
- (_ = this.context) != null && _.container && (c.style.visibility = "hidden", c.style.height = "0", c.style["overflow-y"] = "hidden"), this.container ? c.shadowRoot ? ((ee = c.shadowRoot.lastChild) == null ? void 0 : ee.nodeName) === "IFRAME" ? c.shadowRoot.replaceChild(d, c.shadowRoot.lastChild) : c.shadowRoot.appendChild(d) : c.firstChild ? c.replaceChild(d, c.firstChild) : c.appendChild(d) : (!c.firstChild || c.firstChild.nodeName === "#text") && c.appendChild(d);
912
- const { contentWindow: h } = d;
913
- if (!h)
914
- throw new Error("Frame needs a content window");
915
- const u = h.document;
916
- u.open();
917
- const g = this.widgetApi.domain === "https://staging.referralsaasquatch.com" ? "-staging" : "";
918
- u.write(`
919
- ${(te = e == null ? void 0 : e.main) != null && te.brandFont ? `
920
- <link rel="preconnect" href="https://fast${g}.ssqt.io">
921
- <link rel="preconnect" href="https://fonts.gstatic.com">
922
- <link rel="preconnect" href="https://fonts.googleapis.com">
923
- <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent(
924
- (ne = e == null ? void 0 : e.main) == null ? void 0 : ne.brandFont
925
- )}" as="style">` : ""}
926
- <link rel="dns-prefetch" href="https://res.cloudinary.com">
927
- <link rel="preconnect" href="https://res.cloudinary.com" crossorigin>
928
- ${n ? `
929
- <style data-styles>
930
- html { visibility: hidden; }
931
- </style>` : ""}
932
- ${this._getSkeletonPreloadHTML(n, (ie = e == null ? void 0 : e.color) == null ? void 0 : ie.backgroundColor)}
933
- ${this.content}
934
- <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>
935
- `), u.close(), Q(u, async () => {
936
- const oe = h.squatch || h.widgetIdent;
937
- d.height = i;
938
- const ye = new h.ResizeObserver((ke) => {
939
- for (const be of ke) {
940
- const { height: xe } = be.contentRect;
941
- d.height = xe;
942
- }
943
- }), ve = await this._findInnerContainer(d);
944
- ye.observe(ve), this._shouldFireLoadEvent() ? (this._loadEvent(oe), E("loaded")) : u && this._attachLoadEventListener(u, oe);
945
1193
  });
946
1194
  }
947
1195
  /**
948
1196
  * Un-hide if element is available and refresh data
949
1197
  */
950
1198
  open() {
951
- const e = this._findFrame();
952
- if (!e) return E("no target element to open");
953
- if (!e.contentWindow) return E("Frame needs a content window");
954
- const n = this._findElement();
955
- n.style.visibility = "unset", n.style.height = "auto", n.style["overflow-y"] = "auto", e.contentWindow.document.dispatchEvent(new CustomEvent("sq:refresh"));
956
- const i = e.contentWindow.squatch || e.contentWindow.widgetIdent;
957
- if (this.context.user)
958
- this._loadEvent(i), E("loaded");
959
- else {
960
- if (!e.contentDocument) return;
961
- this._attachLoadEventListener(e.contentDocument, i);
1199
+ const frame = this._findFrame();
1200
+ if (!frame) return _log$7("no target element to open");
1201
+ if (!frame.contentWindow) return _log$7("Frame needs a content window");
1202
+ const element = this._findElement();
1203
+ element.style.visibility = "unset";
1204
+ element.style.height = "auto";
1205
+ element.style["overflow-y"] = "auto";
1206
+ frame.contentWindow.document.dispatchEvent(new CustomEvent("sq:refresh"));
1207
+ const _sqh = frame.contentWindow.squatch || frame.contentWindow.widgetIdent;
1208
+ if (this.context.user) {
1209
+ this._loadEvent(_sqh);
1210
+ _log$7("loaded");
1211
+ } else {
1212
+ if (!frame.contentDocument) return;
1213
+ this._attachLoadEventListener(frame.contentDocument, _sqh);
962
1214
  }
963
1215
  }
964
1216
  close() {
965
- const e = this._findFrame();
966
- if (!e) return E("no target element to close");
967
- e.contentDocument && this._detachLoadEventListener(e.contentDocument);
968
- const n = this._findElement();
969
- n.style.visibility = "hidden", n.style.height = "0", n.style["overflow-y"] = "hidden", E("Embed widget closed");
970
- }
971
- _error(e, n = "embed", i = "") {
972
- return super._error(e, n, i);
1217
+ const frame = this._findFrame();
1218
+ if (!frame) return _log$7("no target element to close");
1219
+ if (frame.contentDocument)
1220
+ this._detachLoadEventListener(frame.contentDocument);
1221
+ const element = this._findElement();
1222
+ element.style.visibility = "hidden";
1223
+ element.style.height = "0";
1224
+ element.style["overflow-y"] = "hidden";
1225
+ _log$7("Embed widget closed");
1226
+ }
1227
+ _error(rs, mode = "embed", style = "") {
1228
+ return super._error(rs, mode, style);
973
1229
  }
974
1230
  _shouldFireLoadEvent() {
975
- const e = !this.container, n = this.container instanceof HTMLElement && (this.container.tagName.startsWith("SQUATCH-") || this.container.tagName.startsWith("IMPACT-"));
976
- return !!this.context.user && (e || n);
1231
+ const noContainer = !this.container;
1232
+ const isComponent = this.container instanceof HTMLElement && (this.container.tagName.startsWith("SQUATCH-") || this.container.tagName.startsWith("IMPACT-"));
1233
+ const isVerified = !!this.context.user;
1234
+ return isVerified && (noContainer || isComponent);
977
1235
  }
978
1236
  }
979
- const T = k("squatch-js:POPUPwidget");
980
- let U = 0;
981
- class j extends pe {
982
- constructor(e, n = ".squatchpop") {
983
- super(e);
984
- l(this, "trigger");
985
- l(this, "id");
986
- l(this, "show", this.open);
987
- l(this, "hide", this.close);
988
- this.trigger = n, this.container ? this.id = "squatchModal" : (this.id = U === 0 ? "squatchModal" : `squatchModal__${U}`, U = U + 1), document.head.insertAdjacentHTML(
1237
+ const _log$6 = browserExports.debug("squatch-js:POPUPwidget");
1238
+ let popupId = 0;
1239
+ class PopupWidget extends Widget {
1240
+ constructor(params, trigger = ".squatchpop") {
1241
+ super(params);
1242
+ __publicField(this, "trigger");
1243
+ __publicField(this, "id");
1244
+ __publicField(this, "show", this.open);
1245
+ __publicField(this, "hide", this.close);
1246
+ this.trigger = trigger;
1247
+ if (this.container) {
1248
+ this.id = "squatchModal";
1249
+ } else {
1250
+ this.id = popupId === 0 ? `squatchModal` : `squatchModal__${popupId}`;
1251
+ popupId = popupId + 1;
1252
+ }
1253
+ document.head.insertAdjacentHTML(
989
1254
  "beforeend",
990
1255
  `<style>#${this.id}::-webkit-scrollbar { display: none; }</style>`
991
1256
  );
992
1257
  }
993
1258
  _initialiseCTA() {
994
1259
  if (!this.trigger) return;
995
- let e;
1260
+ let triggerElement;
996
1261
  try {
997
- e = document.querySelector(this.trigger) || document.querySelector(".impactpop"), this.trigger && !e && T("No element found with trigger selector", this.trigger);
1262
+ triggerElement = document.querySelector(this.trigger) || document.querySelector(".impactpop");
1263
+ if (this.trigger && !triggerElement)
1264
+ _log$6("No element found with trigger selector", this.trigger);
998
1265
  } catch {
999
- T("Not a valid selector", this.trigger);
1266
+ _log$6("Not a valid selector", this.trigger);
1267
+ }
1268
+ if (triggerElement) {
1269
+ triggerElement.onclick = () => {
1270
+ this.open();
1271
+ };
1000
1272
  }
1001
- e && (e.onclick = () => {
1002
- this.open();
1003
- });
1004
1273
  }
1005
- _createPopupDialog(e) {
1006
- var d;
1007
- const n = document.createElement("dialog"), i = (d = e == null ? void 0 : e.widgetSize) == null ? void 0 : d.popupWidgets, s = i != null && i.minWidth ? L(i.minWidth) : "auto", r = i != null && i.maxWidth ? L(i.maxWidth) : "500px";
1008
- n.id = this.id, n.setAttribute(
1274
+ _createPopupDialog() {
1275
+ var _a2, _b, _c;
1276
+ const dialog = document.createElement("dialog");
1277
+ const brandingConfig = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1278
+ const sizes = (_c = brandingConfig == null ? void 0 : brandingConfig.widgetSize) == null ? void 0 : _c.popupWidgets;
1279
+ const minWidth = (sizes == null ? void 0 : sizes.minWidth) ? formatWidth(sizes.minWidth) : "auto";
1280
+ const maxWidth = (sizes == null ? void 0 : sizes.maxWidth) ? formatWidth(sizes.maxWidth) : "500px";
1281
+ dialog.id = this.id;
1282
+ dialog.setAttribute(
1009
1283
  "style",
1010
- `width: 100%; min-width: ${s}; max-width: ${r}; border: none; padding: 0;`
1284
+ `width: 100%; min-width: ${minWidth}; max-width: ${maxWidth}; border: none; padding: 0;`
1011
1285
  );
1012
- const a = (c) => {
1013
- c.stopPropagation(), c.target === n && n.close();
1286
+ const onClick = (e) => {
1287
+ e.stopPropagation();
1288
+ if (e.target === dialog) dialog.close();
1014
1289
  };
1015
- return n.addEventListener("click", a), n;
1290
+ dialog.addEventListener("click", onClick);
1291
+ return dialog;
1016
1292
  }
1017
1293
  async load() {
1018
- var p, g, m, w, b, f, _;
1019
- const e = (g = (p = this.context.widgetConfig) == null ? void 0 : p.values) == null ? void 0 : g.brandingConfig, n = (e == null ? void 0 : e.loadingHeight) || 500, i = (m = this.content) == null ? void 0 : m.includes("mint-components"), s = this._createFrame();
1020
- s.style.height = n + "px", this._initialiseCTA();
1021
- const r = this.container ? this._findElement() : document.body, a = (r == null ? void 0 : r.shadowRoot) || r, d = this._createPopupDialog(e);
1022
- d.appendChild(s), ((w = a.lastChild) == null ? void 0 : w.nodeName) === "DIALOG" ? a.replaceChild(d, a.lastChild) : a.appendChild(d);
1023
- const { contentWindow: c } = s;
1024
- if (!c)
1294
+ var _a2;
1295
+ const frame = this._createFrame();
1296
+ this._initialiseCTA();
1297
+ const element = this.container ? this._findElement() : document.body;
1298
+ const dialogParent = element.shadowRoot || element;
1299
+ const dialog = this._createPopupDialog();
1300
+ dialog.appendChild(frame);
1301
+ if (((_a2 = dialogParent.lastChild) == null ? void 0 : _a2.nodeName) === "DIALOG") {
1302
+ dialogParent.replaceChild(dialog, dialogParent.lastChild);
1303
+ } else {
1304
+ dialogParent.appendChild(dialog);
1305
+ }
1306
+ const { contentWindow } = frame;
1307
+ if (!contentWindow) {
1025
1308
  throw new Error("Frame needs a content window");
1026
- const h = c.document;
1027
- h.open();
1028
- const u = this.widgetApi.domain;
1029
- h.write(`
1030
- ${(b = e == null ? void 0 : e.main) != null && b.brandFont ? `
1031
- <link rel="preconnect" href="https://fast${u === "https://staging.referralsaasquatch.com" ? "-staging" : ""}.ssqt.io">
1032
- <link rel="preconnect" href="https://fonts.gstatic.com">
1033
- <link rel="preconnect" href="https://fonts.googleapis.com">
1034
- <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent(
1035
- (f = e == null ? void 0 : e.main) == null ? void 0 : f.brandFont
1036
- )}" as="style">` : ""}
1037
- <link rel="dns-prefetch" href="https://res.cloudinary.com">
1038
- <link rel="preconnect" href="https://res.cloudinary.com" crossorigin>
1039
- ${i ? `
1040
- <style data-styles>
1041
- html { visibility: hidden; }
1042
- </style>` : ""}
1043
- ${this._getSkeletonPreloadHTML(i, (_ = e == null ? void 0 : e.color) == null ? void 0 : _.backgroundColor)}
1044
- ${this.content}
1045
- <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>
1046
- `), h.close(), T("Popup template loaded into iframe"), await this._setupResizeHandler(s);
1047
- }
1048
- async _setupResizeHandler(e) {
1049
- const { contentWindow: n } = e;
1050
- if (!n)
1309
+ }
1310
+ const frameDoc = contentWindow.document;
1311
+ frameDoc.open();
1312
+ frameDoc.write(this.content);
1313
+ frameDoc.write(
1314
+ `<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>`
1315
+ );
1316
+ frameDoc.write(`
1317
+ <style>
1318
+ body {
1319
+ height: 600px;
1320
+ border: 2px solid #ccc;
1321
+ background-color: red;
1322
+ margin: 0;
1323
+ padding: 0;
1324
+ box-sizing: border-box;
1325
+ }
1326
+ </style>
1327
+ `);
1328
+ frameDoc.close();
1329
+ _log$6("Popup template loaded into iframe");
1330
+ await this._setupResizeHandler(frame);
1331
+ }
1332
+ async _setupResizeHandler(frame) {
1333
+ const { contentWindow } = frame;
1334
+ if (!contentWindow) {
1051
1335
  throw new Error("Frame needs a content window");
1052
- const i = n.document;
1053
- Q(i, async () => {
1054
- i.body.style.overflowY = "hidden";
1055
- let s = !0;
1056
- new n.ResizeObserver((a) => {
1057
- for (const d of a) {
1058
- const { top: c, bottom: h } = d.contentRect, u = h + c;
1059
- u <= 0 || (s ? (s = !1, e.style.height = "0", e.height = i.body.scrollHeight + "", e.style.height = "") : e.height = u + "", d.target.style = "");
1336
+ }
1337
+ const frameDoc = contentWindow.document;
1338
+ domready(frameDoc, async () => {
1339
+ frameDoc.body.style.overflowY = "hidden";
1340
+ frame.height = `${frameDoc.body.offsetHeight}px`;
1341
+ const ro = new contentWindow["ResizeObserver"]((entries) => {
1342
+ for (const entry of entries) {
1343
+ const { top, bottom } = entry.contentRect;
1344
+ const computedHeight = bottom + top;
1345
+ frame.height = computedHeight + "";
1346
+ entry.target.style = ``;
1060
1347
  }
1061
- }).observe(await this._findInnerContainer(e));
1348
+ });
1349
+ ro.observe(await this._findInnerContainer(frame));
1062
1350
  });
1063
1351
  }
1064
1352
  open() {
1065
- const e = this.container ? this._findElement() : document.body, i = (e.shadowRoot || e).querySelector(`#${this.id}`);
1066
- if (!i) throw new Error("Could not determine container div");
1067
- i.showModal();
1068
- const s = this._findFrame();
1069
- if (!s) throw new Error("Could not find iframe");
1070
- const { contentWindow: r } = s;
1071
- if (!r) throw new Error("Squatch.js has an empty iframe");
1072
- const a = r.document;
1073
- Q(a, () => {
1074
- var c;
1075
- const d = r.squatch || r.widgetIdent;
1076
- (c = s.contentDocument) == null || c.dispatchEvent(new CustomEvent("sq:refresh")), this.context.user ? (this._loadEvent(d), T("Popup opened")) : this._attachLoadEventListener(a, d);
1353
+ const element = this.container ? this._findElement() : document.body;
1354
+ const parent = element.shadowRoot || element;
1355
+ const dialog = parent.querySelector(`#${this.id}`);
1356
+ if (!dialog) throw new Error("Could not determine container div");
1357
+ dialog.showModal();
1358
+ const frame = this._findFrame();
1359
+ if (!frame) throw new Error("Could not find iframe");
1360
+ const { contentWindow } = frame;
1361
+ if (!contentWindow) throw new Error("Squatch.js has an empty iframe");
1362
+ const frameDoc = contentWindow.document;
1363
+ domready(frameDoc, () => {
1364
+ var _a2;
1365
+ const _sqh = contentWindow.squatch || contentWindow.widgetIdent;
1366
+ (_a2 = frame.contentDocument) == null ? void 0 : _a2.dispatchEvent(new CustomEvent("sq:refresh"));
1367
+ if (this.context.user) {
1368
+ this._loadEvent(_sqh);
1369
+ _log$6("Popup opened");
1370
+ } else {
1371
+ this._attachLoadEventListener(frameDoc, _sqh);
1372
+ }
1077
1373
  });
1078
1374
  }
1079
1375
  close() {
1080
- const e = this._findFrame();
1081
- e != null && e.contentDocument && this._detachLoadEventListener(e.contentDocument);
1082
- const n = this.container ? this._findElement() : document.body, s = (n.shadowRoot || n).querySelector(`#${this.id}`);
1083
- if (!s) throw new Error("Could not determine container div");
1084
- s.close(), T("Popup closed");
1085
- }
1086
- _clickedOutside({ target: e }) {
1087
- }
1088
- _error(e, n = "modal", i = "") {
1089
- return super._error(e, n, i || "body { margin: 0; } .modal { box-shadow: none; border: 0; }");
1376
+ const frame = this._findFrame();
1377
+ if (frame == null ? void 0 : frame.contentDocument)
1378
+ this._detachLoadEventListener(frame.contentDocument);
1379
+ const element = this.container ? this._findElement() : document.body;
1380
+ const parent = element.shadowRoot || element;
1381
+ const dialog = parent.querySelector(`#${this.id}`);
1382
+ if (!dialog) throw new Error("Could not determine container div");
1383
+ dialog.close();
1384
+ _log$6("Popup closed");
1385
+ }
1386
+ _clickedOutside({ target }) {
1387
+ }
1388
+ _error(rs, mode = "modal", style = "") {
1389
+ const _style = "body { margin: 0; } .modal { box-shadow: none; border: 0; }";
1390
+ return super._error(rs, mode, style || _style);
1090
1391
  }
1091
1392
  }
1092
- const v = k("squatch-js:widgets");
1093
- class D {
1393
+ const _log$5 = browserExports.debug("squatch-js:widgets");
1394
+ class Widgets {
1094
1395
  /**
1095
1396
  * Initialize a new {@link Widgets} instance.
1096
1397
  *
@@ -1100,473 +1401,830 @@ class D {
1100
1401
  * var widgets = new squatch.Widgets({tenantAlias:'test_12b5bo1b25125'});
1101
1402
  *
1102
1403
  * @example <caption>Browserify/Webpack example</caption>
1103
- * var Widgets = require('@saasquatch/squatch-js').Widgets;
1104
- * var widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1404
+ * var Widgets = require('@saasquatch/squatch-js').Widgets;
1405
+ * var widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1406
+ *
1407
+ * @example <caption>Babel+Browserify/Webpack example</caption>
1408
+ * import {Widgets} from '@saasquatch/squatch-js';
1409
+ * let widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1410
+ */
1411
+ constructor(configin) {
1412
+ /**
1413
+ * Instance of {@link WidgetApi}
1414
+ */
1415
+ __publicField(this, "api");
1416
+ /**
1417
+ * Tenant alias of SaaSquatch tenant
1418
+ */
1419
+ __publicField(this, "tenantAlias");
1420
+ /**
1421
+ * SaaSquatch domain for API requests
1422
+ * @default "https://app.referralsaasquatch.com"
1423
+ */
1424
+ __publicField(this, "domain");
1425
+ /**
1426
+ * Hosted CDN for npm packages
1427
+ * @default "https://fast.ssqt.io/npm"
1428
+ */
1429
+ __publicField(this, "npmCdn");
1430
+ const config = validateConfig(configin);
1431
+ this.tenantAlias = config.tenantAlias;
1432
+ this.domain = config.domain;
1433
+ this.npmCdn = config.npmCdn;
1434
+ this.api = new WidgetApi(config);
1435
+ }
1436
+ /**
1437
+ * This function calls the {@link WidgetApi.upsertUser} method, and it renders
1438
+ * the widget if it is successful. Otherwise it shows the "error" widget.
1439
+ *
1440
+ * @param {Object} config Config details
1441
+ * @param {Object} config.user The user details
1442
+ * @param {string} config.user.id The user id
1443
+ * @param {string} config.user.accountId The user account id
1444
+ * @param {WidgetType} config.widgetType The content of the widget
1445
+ * @param {EngagementMedium} config.engagementMedium How to display the widget
1446
+ * @param {string} config.jwt the JSON Web Token (JWT) that is used to validate the data (can be disabled)
1447
+ * @param {HTMLElement | string | undefined} config.container Element to load the widget into
1448
+ * @param {string | undefined} config.trigger Trigger element for opening the popup widget
1449
+ *
1450
+ * @return {Promise<WidgetResult>} json object if true, with a Widget and user details
1451
+ */
1452
+ async upsertUser(config) {
1453
+ const raw = config;
1454
+ const clean = validateWidgetConfig(raw);
1455
+ try {
1456
+ const response = await this.api.upsertUser(clean);
1457
+ return {
1458
+ widget: this._renderWidget(response, clean, {
1459
+ type: "upsert",
1460
+ user: clean.user,
1461
+ engagementMedium: config.engagementMedium,
1462
+ container: config.container,
1463
+ trigger: config.trigger,
1464
+ widgetConfig: {
1465
+ values: {
1466
+ brandingConfig: response == null ? void 0 : response.brandingConfig
1467
+ }
1468
+ }
1469
+ }),
1470
+ user: response.user
1471
+ };
1472
+ } catch (err) {
1473
+ _log$5(err);
1474
+ if (err.apiErrorCode) {
1475
+ this._renderErrorWidget(err, config.engagementMedium);
1476
+ }
1477
+ throw new Error(err);
1478
+ }
1479
+ }
1480
+ /**
1481
+ * This function calls the {@link WidgetApi.render} method, and it renders
1482
+ * the widget if it is successful. Otherwise it shows the "error" widget.
1483
+ *
1484
+ * @param {Object} config Config details
1485
+ * @param {Object} config.user The user details
1486
+ * @param {string} config.user.id The user id
1487
+ * @param {string} config.user.accountId The user account id
1488
+ * @param {WidgetType} config.widgetType The content of the widget
1489
+ * @param {EngagementMedium} config.engagementMedium How to display the widget
1490
+ * @param {string} config.jwt the JSON Web Token (JWT) that is used
1491
+ * to validate the data (can be disabled)
1492
+ *
1493
+ * @return {Promise<WidgetResult>} json object if true, with a Widget and user details
1494
+ */
1495
+ async render(config) {
1496
+ const raw = config;
1497
+ const clean = validatePasswordlessConfig(raw);
1498
+ try {
1499
+ const response = await this.api.render(clean);
1500
+ return {
1501
+ widget: this._renderWidget(response, clean, {
1502
+ type: "passwordless",
1503
+ engagementMedium: clean.engagementMedium,
1504
+ container: clean.container,
1505
+ trigger: clean.trigger,
1506
+ widgetConfig: {
1507
+ values: {
1508
+ brandingConfig: response == null ? void 0 : response.brandingConfig
1509
+ }
1510
+ }
1511
+ }),
1512
+ user: response.user
1513
+ };
1514
+ } catch (err) {
1515
+ if (err.apiErrorCode) {
1516
+ this._renderErrorWidget(err, clean.engagementMedium);
1517
+ }
1518
+ throw new Error(err);
1519
+ }
1520
+ }
1521
+ /**
1522
+ * Autofills a referral code into an element when someone has been referred.
1523
+ * Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
1524
+ *
1525
+ * @param selector Element class/id selector, or a callback function
1526
+ * @returns
1527
+ */
1528
+ async autofill(selector) {
1529
+ const input = selector;
1530
+ if (typeof input === "function") {
1531
+ try {
1532
+ const response = await this.api.squatchReferralCookie();
1533
+ input(response);
1534
+ } catch (e) {
1535
+ _log$5("Autofill error", e);
1536
+ throw new Error(e);
1537
+ }
1538
+ return;
1539
+ }
1540
+ if (typeof input !== "string")
1541
+ throw new Error("Autofill accepts a string or function");
1542
+ let elems = document.querySelectorAll(input);
1543
+ let elem;
1544
+ if (elems.length > 0) {
1545
+ elem = elems[0];
1546
+ } else {
1547
+ _log$5("Element id/class or function missing");
1548
+ throw new Error("Element id/class or function missing");
1549
+ }
1550
+ try {
1551
+ const response = await this.api.squatchReferralCookie();
1552
+ elem.value = response.codes[0];
1553
+ } catch (e) {
1554
+ throw new Error(e);
1555
+ }
1556
+ }
1557
+ /**
1558
+ * @hidden
1559
+ * @param {Object} response The json object return from the WidgetApi
1560
+ * @param {Object} config Config details
1561
+ * @param {string} config.widgetType The widget type (REFERRER_WIDGET, CONVERSION_WIDGET)
1562
+ * @param {string} config.engagementMedium (POPUP, EMBED)
1563
+ * @returns {Widget} widget (PopupWidget or EmbedWidget)
1564
+ */
1565
+ _renderWidget(response, config, context) {
1566
+ var _a2;
1567
+ _log$5("Rendering Widget...");
1568
+ if (!response) throw new Error("Unable to get a response");
1569
+ let widget2;
1570
+ let displayOnLoad = !!config.displayOnLoad;
1571
+ const opts = response.jsOptions || {};
1572
+ const params = {
1573
+ content: response.template,
1574
+ type: config.widgetType || ((_a2 = opts.widget) == null ? void 0 : _a2.defaultWidgetType),
1575
+ api: this.api,
1576
+ domain: this.domain,
1577
+ npmCdn: this.npmCdn,
1578
+ context
1579
+ };
1580
+ if (opts.widgetUrlMappings) {
1581
+ opts.widgetUrlMappings.forEach((rule) => {
1582
+ var _a3, _b;
1583
+ if (Widgets._matchesUrl(rule.url)) {
1584
+ if (rule.widgetType !== "CONVERSION_WIDGET" || ((_b = (_a3 = response.user) == null ? void 0 : _a3.referredBy) == null ? void 0 : _b.code)) {
1585
+ displayOnLoad = rule.displayOnLoad;
1586
+ _log$5(`Display ${rule.widgetType} on ${rule.url}`);
1587
+ } else {
1588
+ _log$5(
1589
+ `Don't display ${rule.widgetType} when no referral on widget rule match ${rule.url}`
1590
+ );
1591
+ }
1592
+ }
1593
+ });
1594
+ }
1595
+ if (opts.fuelTankAutofillUrls) {
1596
+ _log$5("We found a fuel tank autofill!");
1597
+ opts.fuelTankAutofillUrls.forEach(({ url, formSelector }) => {
1598
+ var _a3, _b, _c;
1599
+ if (Widgets._matchesUrl(url)) {
1600
+ _log$5("Fuel Tank URL matches");
1601
+ if ((_b = (_a3 = response.user) == null ? void 0 : _a3.referredBy) == null ? void 0 : _b.code) {
1602
+ const formAutofill = document.querySelector(formSelector);
1603
+ if (formAutofill) {
1604
+ formAutofill.value = ((_c = response.user.referredBy.referredReward) == null ? void 0 : _c.fuelTankCode) || "";
1605
+ } else {
1606
+ _log$5(
1607
+ new Error(
1608
+ `Element with id/class ${formSelector} was not found.`
1609
+ )
1610
+ );
1611
+ }
1612
+ }
1613
+ }
1614
+ });
1615
+ }
1616
+ if (config.engagementMedium === "EMBED") {
1617
+ widget2 = this._renderEmbedWidget(params);
1618
+ } else {
1619
+ widget2 = this._renderPopupWidget(params);
1620
+ if (displayOnLoad) widget2.open();
1621
+ }
1622
+ return widget2;
1623
+ }
1624
+ _renderPopupWidget(params) {
1625
+ const widget2 = new PopupWidget(params, params.context.trigger);
1626
+ widget2.load();
1627
+ return widget2;
1628
+ }
1629
+ _renderEmbedWidget(params) {
1630
+ const widget2 = new EmbedWidget(params, params.context.container);
1631
+ widget2.load();
1632
+ return widget2;
1633
+ }
1634
+ /**
1635
+ * @hidden
1636
+ * @param {Object} error The json object containing the error details
1637
+ * @param {string} em The engagementMedium
1638
+ * @returns {void}
1639
+ */
1640
+ _renderErrorWidget(props, em = "POPUP") {
1641
+ const { apiErrorCode, rsCode, message } = props;
1642
+ _log$5(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
1643
+ const params = {
1644
+ content: "error",
1645
+ rsCode,
1646
+ api: this.api,
1647
+ domain: this.domain,
1648
+ npmCdn: this.npmCdn,
1649
+ type: "ERROR_WIDGET",
1650
+ context: { type: "error" }
1651
+ };
1652
+ let widget2;
1653
+ if (em === "EMBED") {
1654
+ widget2 = new EmbedWidget(params);
1655
+ widget2.load();
1656
+ } else if (em === "POPUP") {
1657
+ widget2 = new PopupWidget(params);
1658
+ widget2.load();
1659
+ }
1660
+ }
1661
+ /**
1662
+ * @hidden
1663
+ * @param {string} rule A regular expression
1664
+ * @returns {boolean} true if rule matches Url, false otherwise
1665
+ */
1666
+ static _matchesUrl(rule) {
1667
+ return window.location.href.match(new RegExp(rule)) ? true : false;
1668
+ }
1669
+ }
1670
+ class EventsApi {
1671
+ /**
1672
+ * Initialize a new {@link EventsApi} instance.
1673
+ *
1674
+ * @param {ConfigOptions} config Config details
1675
+ *
1676
+ * @example <caption>Browser example</caption>
1677
+ * var squatchApi = new squatch.EventsApi({tenantAlias:'test_12b5bo1b25125'});
1678
+ *
1679
+ * @example <caption>Browserify/Webpack example</caption>
1680
+ * var EventsApi = require('@saasquatch/squatch-js').EventsApi;
1681
+ * var squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1105
1682
  *
1106
1683
  * @example <caption>Babel+Browserify/Webpack example</caption>
1107
- * import {Widgets} from '@saasquatch/squatch-js';
1108
- * let widgets = new Widgets({tenantAlias:'test_12b5bo1b25125'});
1684
+ * import {EventsApi} from '@saasquatch/squatch-js';
1685
+ * let squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1109
1686
  */
1110
- constructor(t) {
1111
- /**
1112
- * Instance of {@link WidgetApi}
1113
- */
1114
- l(this, "api");
1115
- /**
1116
- * Tenant alias of SaaSquatch tenant
1117
- */
1118
- l(this, "tenantAlias");
1119
- /**
1120
- * SaaSquatch domain for API requests
1121
- * @default "https://app.referralsaasquatch.com"
1122
- */
1123
- l(this, "domain");
1124
- /**
1125
- * Hosted CDN for npm packages
1126
- * @default "https://fast.ssqt.io/npm"
1127
- */
1128
- l(this, "npmCdn");
1129
- const e = q(t);
1130
- this.tenantAlias = e.tenantAlias, this.domain = e.domain, this.npmCdn = e.npmCdn, this.api = new K(e);
1687
+ constructor(config) {
1688
+ __publicField(this, "tenantAlias");
1689
+ __publicField(this, "domain");
1690
+ const raw = config;
1691
+ const clean = validateConfig(raw);
1692
+ this.tenantAlias = clean.tenantAlias;
1693
+ this.domain = clean.domain;
1131
1694
  }
1132
1695
  /**
1133
- * This function calls the {@link WidgetApi.upsertUser} method, and it renders
1134
- * the widget if it is successful. Otherwise it shows the "error" widget.
1696
+ * Track an event for a user
1135
1697
  *
1136
- * @param {Object} config Config details
1137
- * @param {Object} config.user The user details
1138
- * @param {string} config.user.id The user id
1139
- * @param {string} config.user.accountId The user account id
1140
- * @param {WidgetType} config.widgetType The content of the widget
1141
- * @param {EngagementMedium} config.engagementMedium How to display the widget
1142
- * @param {string} config.jwt the JSON Web Token (JWT) that is used to validate the data (can be disabled)
1143
- * @param {HTMLElement | string | undefined} config.container Element to load the widget into
1144
- * @param {string | undefined} config.trigger Trigger element for opening the popup widget
1698
+ * @param params Parameters for request
1699
+ * @param options.jwt the JSON Web Token (JWT) that is used to authenticate the user
1145
1700
  *
1146
- * @return {Promise<WidgetResult>} json object if true, with a Widget and user details
1701
+ * @return An ID to confirm the event has been accepted for asynchronous processing
1147
1702
  */
1148
- async upsertUser(t) {
1149
- const n = ce(t);
1150
- try {
1151
- const i = await this.api.upsertUser(n);
1152
- return {
1153
- widget: this._renderWidget(i, n, {
1154
- type: "upsert",
1155
- user: n.user,
1156
- engagementMedium: t.engagementMedium,
1157
- container: t.container,
1158
- trigger: t.trigger,
1159
- widgetConfig: {
1160
- values: {
1161
- brandingConfig: i == null ? void 0 : i.brandingConfig
1162
- }
1163
- }
1164
- }),
1165
- user: i.user
1166
- };
1167
- } catch (i) {
1168
- throw v(i), i.apiErrorCode && this._renderErrorWidget(i, t.engagementMedium), new Error(i);
1703
+ track(params, options) {
1704
+ const raw = params;
1705
+ const rawOpts = options;
1706
+ const body = _validateEvent(raw);
1707
+ const { jwt } = _validateTrackOptions(rawOpts);
1708
+ const ta = encodeURIComponent(this.tenantAlias);
1709
+ const userId = encodeURIComponent(body.userId);
1710
+ const accountId = encodeURIComponent(body.accountId);
1711
+ const path = `/api/v1/${ta}/open/account/${accountId}/user/${userId}/events`;
1712
+ const url = this.domain + path;
1713
+ return doPost(url, JSON.stringify(body), jwt);
1714
+ }
1715
+ }
1716
+ function _validateEvent(raw) {
1717
+ if (!isObject$1(raw)) throw new Error("tracking parameter must be an object");
1718
+ if (!(raw == null ? void 0 : raw["accountId"])) throw new Error("accountId field is required");
1719
+ if (!(raw == null ? void 0 : raw["events"])) throw new Error("events field is required");
1720
+ if (!(raw == null ? void 0 : raw["userId"])) throw new Error("userId field is required");
1721
+ const clean = raw;
1722
+ if (!Array.isArray(clean.events))
1723
+ throw new Error("'events' should be an array");
1724
+ return clean;
1725
+ }
1726
+ function _validateTrackOptions(raw) {
1727
+ if (!isObject$1(raw)) throw new Error("'options' should be an object");
1728
+ return raw;
1729
+ }
1730
+ function asyncLoad() {
1731
+ var _a2;
1732
+ const namespace = window[IMPACT_NAMESPACE] ? IMPACT_NAMESPACE : DEFAULT_NAMESPACE;
1733
+ const cached = ((_a2 = window["_" + namespace]) == null ? void 0 : _a2.ready) || [];
1734
+ const declarativeCache = window.impactOnReady || window.squatchOnReady;
1735
+ const readyFns = [...cached, declarativeCache].filter((a) => !!a);
1736
+ setTimeout(() => {
1737
+ if (!window[DEFAULT_NAMESPACE]) return;
1738
+ window[IMPACT_NAMESPACE] = window[DEFAULT_NAMESPACE];
1739
+ readyFns.forEach((cb) => cb());
1740
+ window[DEFAULT_NAMESPACE]._auto();
1741
+ window["_" + namespace] = void 0;
1742
+ delete window["_" + namespace];
1743
+ }, 0);
1744
+ }
1745
+ const _log$4 = browserExports.debug("squatch-js");
1746
+ const isObject = (item) => typeof item === "object" && !Array.isArray(item);
1747
+ const deepMerge = (target, source) => {
1748
+ const isDeep = (prop) => isObject(source[prop]) && target.hasOwnProperty(prop) && isObject(target[prop]);
1749
+ const replaced = Object.getOwnPropertyNames(source).map((prop) => ({
1750
+ [prop]: isDeep(prop) ? deepMerge(target[prop], source[prop]) : source[prop]
1751
+ })).reduce((a, b) => ({ ...a, ...b }), {});
1752
+ return {
1753
+ ...target,
1754
+ ...replaced
1755
+ };
1756
+ };
1757
+ function b64decode(input) {
1758
+ const binary = atob(input.replace(/_/g, "/").replace(/-/g, "+"));
1759
+ const bytes = new Uint8Array(binary.length);
1760
+ for (let i = 0; i < binary.length; i++) {
1761
+ bytes[i] = binary.charCodeAt(i);
1762
+ }
1763
+ return new TextDecoder("utf8").decode(bytes);
1764
+ }
1765
+ function b64encode(input) {
1766
+ const encodedInput = new TextEncoder().encode(input);
1767
+ const binary = Array.from(
1768
+ encodedInput,
1769
+ (byte) => String.fromCodePoint(byte)
1770
+ ).join("");
1771
+ return btoa(binary).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1772
+ }
1773
+ function getTopDomain() {
1774
+ var i, h, weird_cookie = "weird_get_top_level_domain=cookie", hostname = document.location.hostname.split(".");
1775
+ for (i = hostname.length - 1; i >= 0; i--) {
1776
+ h = hostname.slice(i).join(".");
1777
+ document.cookie = weird_cookie + ";domain=." + h + ";";
1778
+ if (document.cookie.indexOf(weird_cookie) > -1) {
1779
+ document.cookie = weird_cookie.split("=")[0] + "=;domain=." + h + ";expires=Thu, 01 Jan 1970 00:00:01 GMT;";
1780
+ return h;
1169
1781
  }
1170
1782
  }
1171
- /**
1172
- * This function calls the {@link WidgetApi.render} method, and it renders
1173
- * the widget if it is successful. Otherwise it shows the "error" widget.
1174
- *
1175
- * @param {Object} config Config details
1176
- * @param {Object} config.user The user details
1177
- * @param {string} config.user.id The user id
1178
- * @param {string} config.user.accountId The user account id
1179
- * @param {WidgetType} config.widgetType The content of the widget
1180
- * @param {EngagementMedium} config.engagementMedium How to display the widget
1181
- * @param {string} config.jwt the JSON Web Token (JWT) that is used
1182
- * to validate the data (can be disabled)
1183
- *
1184
- * @return {Promise<WidgetResult>} json object if true, with a Widget and user details
1185
- */
1186
- async render(t) {
1187
- const n = le(t);
1783
+ }
1784
+ function _pushCookie() {
1785
+ const queryString = window.location.search;
1786
+ const urlParams = new URLSearchParams(queryString);
1787
+ const refParam = urlParams.get("_saasquatch") || "";
1788
+ if (refParam) {
1789
+ let paramsJSON = "", existingCookie = "", reEncodedCookie = "";
1188
1790
  try {
1189
- const i = await this.api.render(n);
1190
- return {
1191
- widget: this._renderWidget(i, n, {
1192
- type: "passwordless",
1193
- engagementMedium: n.engagementMedium,
1194
- container: n.container,
1195
- trigger: n.trigger,
1196
- widgetConfig: i == null ? void 0 : i.widgetConfig
1197
- }),
1198
- user: i.user
1199
- };
1200
- } catch (i) {
1201
- throw i.apiErrorCode && this._renderErrorWidget(i, n.engagementMedium), new Error(i);
1791
+ paramsJSON = JSON.parse(b64decode(refParam));
1792
+ } catch (error) {
1793
+ _log$4("Unable to decode params", error);
1794
+ return;
1795
+ }
1796
+ try {
1797
+ existingCookie = JSON.parse(b64decode(api$1.get("_saasquatch")));
1798
+ _log$4("existing cookie", existingCookie);
1799
+ } catch (error) {
1800
+ _log$4("Unable to retrieve cookie", error);
1801
+ }
1802
+ try {
1803
+ const domain = getTopDomain();
1804
+ _log$4("domain retrieved:", domain);
1805
+ if (existingCookie) {
1806
+ const newCookie = deepMerge(existingCookie, paramsJSON);
1807
+ reEncodedCookie = b64encode(JSON.stringify(newCookie));
1808
+ _log$4("cookie to store:", newCookie);
1809
+ } else {
1810
+ reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
1811
+ _log$4("cookie to store:", paramsJSON);
1812
+ }
1813
+ api$1.set("_saasquatch", reEncodedCookie, {
1814
+ expires: 365,
1815
+ secure: false,
1816
+ sameSite: "Lax",
1817
+ domain,
1818
+ path: "/"
1819
+ });
1820
+ } catch (error) {
1821
+ _log$4("Unable to set cookie", error);
1202
1822
  }
1203
1823
  }
1204
- /**
1205
- * Autofills a referral code into an element when someone has been referred.
1206
- * Uses {@link WidgetApi.squatchReferralCookie} behind the scenes.
1207
- *
1208
- * @param selector Element class/id selector, or a callback function
1209
- * @returns
1210
- */
1211
- async autofill(t) {
1212
- const e = t;
1213
- if (typeof e == "function") {
1214
- try {
1215
- const s = await this.api.squatchReferralCookie();
1216
- e(s);
1217
- } catch (s) {
1218
- throw v("Autofill error", s), new Error(s);
1824
+ }
1825
+ const _log$3 = browserExports.debug("squatch-js");
1826
+ function _getAutoConfig() {
1827
+ var _a2;
1828
+ const queryString = window.location.search;
1829
+ const urlParams = new URLSearchParams(queryString);
1830
+ const refParam = urlParams.get("_saasquatchExtra") || "";
1831
+ if (!refParam) {
1832
+ _log$3("No _saasquatchExtra param");
1833
+ return;
1834
+ }
1835
+ const config = validateConfig({
1836
+ tenantAlias: "UNKNOWN"
1837
+ });
1838
+ if (!config.domain) {
1839
+ _log$3("domain must be provided in config to use _saasquatchExtra");
1840
+ return;
1841
+ }
1842
+ let raw;
1843
+ try {
1844
+ raw = JSON.parse(b64decode(refParam));
1845
+ } catch (e) {
1846
+ _log$3("Unable to decode _saasquatchExtra config");
1847
+ return;
1848
+ }
1849
+ function normalizeDomain(domain) {
1850
+ return domain.replace(/^https?:\/\//, "");
1851
+ }
1852
+ const normalizedDomain = normalizeDomain(config.domain);
1853
+ const tenantAlias = Object.keys((raw == null ? void 0 : raw[normalizedDomain]) || {})[0];
1854
+ const widgetConfig = (_a2 = raw == null ? void 0 : raw[normalizedDomain]) == null ? void 0 : _a2[tenantAlias];
1855
+ if (!widgetConfig) {
1856
+ _log$3("_saasquatchExtra did not have an expected structure");
1857
+ return void 0;
1858
+ }
1859
+ const { autoPopupWidgetType, ...rest } = widgetConfig;
1860
+ return {
1861
+ widgetConfig: {
1862
+ widgetType: autoPopupWidgetType,
1863
+ displayOnLoad: true,
1864
+ ...rest
1865
+ },
1866
+ squatchConfig: {
1867
+ ...config,
1868
+ tenantAlias
1869
+ }
1870
+ };
1871
+ }
1872
+ const getSkeleton = ({
1873
+ type = "verified-access",
1874
+ height = "500px",
1875
+ skeletonBackgroundColor = "#e0e0e0",
1876
+ skeletonShimmerColor = "#f5f5f5"
1877
+ }) => {
1878
+ const referrerHTML = `
1879
+ <div class="hero-section">
1880
+ <div class="hero-content">
1881
+ <div class="skeleton sk-title-lg"></div>
1882
+ <div class="skeleton sk-text"></div>
1883
+ <div class="skeleton sk-text sk-text-short"></div>
1884
+ </div>
1885
+ <div class="skeleton hero-image"></div>
1886
+ </div>
1887
+
1888
+ <div class="share-section">
1889
+ <div class="skeleton sk-label"></div>
1890
+ <div class="skeleton sk-input"></div>
1891
+ <div class="social-buttons">
1892
+ <div class="skeleton sk-btn-social"></div>
1893
+ <div class="skeleton sk-btn-social"></div>
1894
+ <div class="skeleton sk-btn-social"></div>
1895
+ <div class="skeleton sk-btn-social"></div>
1896
+ </div>
1897
+ </div>
1898
+
1899
+ <div class="skeleton sk-title-md" style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"></div>
1900
+ <div class="skeleton sk-text" style="width: 60%; margin-left: auto; margin-right: auto"></div>
1901
+
1902
+ <div class="stats-section">
1903
+ <div class="stat-card">
1904
+ <div class="skeleton sk-stat-num"></div>
1905
+ <div class="skeleton sk-stat-label"></div>
1906
+ </div>
1907
+ <div class="stat-card stat-divider">
1908
+ <div class="skeleton sk-stat-num"></div>
1909
+ <div class="skeleton sk-stat-label"></div>
1910
+ </div>
1911
+ </div>
1912
+
1913
+ <div class="skeleton sk-title-md"></div>
1914
+
1915
+ <div class="table-header">
1916
+ <div class="skeleton sk-th col-user"></div>
1917
+ <div class="skeleton sk-th col-status"></div>
1918
+ <div class="skeleton sk-th col-reward"></div>
1919
+ <div class="skeleton sk-th col-date"></div>
1920
+ </div>
1921
+
1922
+ <div class="table-row">
1923
+ <div class="col-user"><div class="skeleton sk-text" style="width: 70%; margin: 0"></div></div>
1924
+ <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>
1925
+ <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>
1926
+ <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>
1927
+ </div>
1928
+
1929
+ <div class="table-row">
1930
+ <div class="col-user"><div class="skeleton sk-text" style="width: 60%; margin: 0"></div></div>
1931
+ <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>
1932
+ <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>
1933
+ <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>
1934
+ </div>
1935
+
1936
+ <div class="table-row">
1937
+ <div class="col-user"><div class="skeleton sk-text" style="width: 75%; margin: 0"></div></div>
1938
+ <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>
1939
+ <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>
1940
+ <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>
1941
+ </div>
1942
+
1943
+ <div class="pagination">
1944
+ <div class="skeleton sk-btn-page"></div>
1945
+ <div class="skeleton sk-btn-page"></div>
1946
+ </div>
1947
+ `;
1948
+ const instantAccessHTML = `
1949
+ <div class="hero-section instant-access-layout">
1950
+ <div class="skeleton hero-image ia-image"></div>
1951
+
1952
+ <div class="hero-content ia-content">
1953
+ <div class="skeleton sk-title-lg ia-center"></div>
1954
+ <div class="skeleton sk-text ia-center"></div>
1955
+
1956
+ <div class="skeleton sk-btn-action"></div>
1957
+
1958
+ <div class="skeleton sk-label"></div>
1959
+ <div class="input-group">
1960
+ <div class="skeleton sk-input"></div>
1961
+ <div class="skeleton sk-btn-copy"></div>
1962
+ </div>
1963
+
1964
+ <div class="skeleton sk-text-short ia-center" style="margin-top: 20px; width: 30%"></div>
1965
+ <div class="skeleton sk-text-short ia-center" style="width: 20%"></div>
1966
+ </div>
1967
+ </div>
1968
+ `;
1969
+ return `
1970
+ <style>
1971
+ * {
1972
+ box-sizing: border-box;
1973
+ padding: 0;
1974
+ margin: 0;
1975
+ }
1976
+
1977
+ .widget-container {
1978
+ background: white;
1979
+ width: 100%;
1980
+ padding: 40px;
1981
+ box-sizing: border-box;
1982
+ overflow: hidden;
1983
+ }
1984
+
1985
+ @keyframes shimmer {
1986
+ 0% { background-position: -100% 0; }
1987
+ 100% { background-position: 100% 0; }
1988
+ }
1989
+
1990
+ .skeleton {
1991
+ background: ${skeletonBackgroundColor};
1992
+ background: linear-gradient(
1993
+ 90deg,
1994
+ ${skeletonBackgroundColor} 25%,
1995
+ ${skeletonShimmerColor} 50%,
1996
+ ${skeletonBackgroundColor} 75%
1997
+ );
1998
+ background-size: 200% 100%;
1999
+ animation: shimmer 1.5s infinite linear;
2000
+ border-radius: 6px;
2001
+ margin-bottom: 12px;
2002
+ }
2003
+
2004
+ /* Typography Skeletons */
2005
+ .sk-title-lg { height: 36px; width: 80%; margin-bottom: 16px; }
2006
+ .sk-title-md { height: 28px; width: 30%; margin-bottom: 20px; margin-top: 40px; }
2007
+ .sk-text { height: 16px; width: 90%; margin-bottom: 8px; }
2008
+ .sk-text-short { width: 40%; }
2009
+ .sk-label { height: 14px; width: 25%; margin-bottom: 10px; }
2010
+
2011
+ /* Layouts */
2012
+ .hero-section {
2013
+ display: flex;
2014
+ gap: 40px;
2015
+ margin-bottom: 40px;
2016
+ padding-bottom: 40px;
2017
+ flex-direction: row;
2018
+ height: 100%;
2019
+ /* Removed border-bottom */
1219
2020
  }
1220
- return;
1221
- }
1222
- if (typeof e != "string")
1223
- throw new Error("Autofill accepts a string or function");
1224
- let n = document.querySelectorAll(e), i;
1225
- if (n.length > 0)
1226
- i = n[0];
1227
- else
1228
- throw v("Element id/class or function missing"), new Error("Element id/class or function missing");
1229
- try {
1230
- const s = await this.api.squatchReferralCookie();
1231
- i.value = s.codes[0];
1232
- } catch (s) {
1233
- throw new Error(s);
1234
- }
1235
- }
1236
- /**
1237
- * @hidden
1238
- * @param {Object} response The json object return from the WidgetApi
1239
- * @param {Object} config Config details
1240
- * @param {string} config.widgetType The widget type (REFERRER_WIDGET, CONVERSION_WIDGET)
1241
- * @param {string} config.engagementMedium (POPUP, EMBED)
1242
- * @returns {Widget} widget (PopupWidget or EmbedWidget)
1243
- */
1244
- _renderWidget(t, e, n) {
1245
- var d;
1246
- if (v("Rendering Widget..."), !t) throw new Error("Unable to get a response");
1247
- let i, s = !!e.displayOnLoad;
1248
- const r = t.jsOptions || {}, a = {
1249
- content: t.template,
1250
- type: e.widgetType || ((d = r.widget) == null ? void 0 : d.defaultWidgetType),
1251
- api: this.api,
1252
- domain: this.domain,
1253
- npmCdn: this.npmCdn,
1254
- context: n
1255
- };
1256
- return r.widgetUrlMappings && r.widgetUrlMappings.forEach((c) => {
1257
- var h, u;
1258
- D._matchesUrl(c.url) && (c.widgetType !== "CONVERSION_WIDGET" || (u = (h = t.user) == null ? void 0 : h.referredBy) != null && u.code ? (s = c.displayOnLoad, v(`Display ${c.widgetType} on ${c.url}`)) : v(
1259
- `Don't display ${c.widgetType} when no referral on widget rule match ${c.url}`
1260
- ));
1261
- }), r.fuelTankAutofillUrls && (v("We found a fuel tank autofill!"), r.fuelTankAutofillUrls.forEach(({ url: c, formSelector: h }) => {
1262
- var u, p, g;
1263
- if (D._matchesUrl(c) && (v("Fuel Tank URL matches"), (p = (u = t.user) == null ? void 0 : u.referredBy) != null && p.code)) {
1264
- const m = document.querySelector(h);
1265
- m ? m.value = ((g = t.user.referredBy.referredReward) == null ? void 0 : g.fuelTankCode) || "" : v(
1266
- new Error(
1267
- `Element with id/class ${h} was not found.`
1268
- )
1269
- );
2021
+
2022
+ .hero-content {
2023
+ flex: 1;
2024
+ display: flex;
2025
+ flex-direction: column;
2026
+ justify-content: center;
1270
2027
  }
1271
- })), e.engagementMedium === "EMBED" ? i = this._renderEmbedWidget(a) : (i = this._renderPopupWidget(a), s && i.open()), i;
1272
- }
1273
- _renderPopupWidget(t) {
1274
- const e = new j(t, t.context.trigger);
1275
- return e.load(), e;
1276
- }
1277
- _renderEmbedWidget(t) {
1278
- const e = new O(t, t.context.container);
1279
- return e.load(), e;
1280
- }
1281
- /**
1282
- * @hidden
1283
- * @param {Object} error The json object containing the error details
1284
- * @param {string} em The engagementMedium
1285
- * @returns {void}
1286
- */
1287
- _renderErrorWidget(t, e = "POPUP") {
1288
- const { apiErrorCode: n, rsCode: i, message: s } = t;
1289
- v(new Error(`${n} (${i}) ${s}`));
1290
- const r = {
1291
- content: "error",
1292
- rsCode: i,
1293
- api: this.api,
1294
- domain: this.domain,
1295
- npmCdn: this.npmCdn,
1296
- type: "ERROR_WIDGET",
1297
- context: { type: "error" }
1298
- };
1299
- let a;
1300
- e === "EMBED" ? (a = new O(r), a.load()) : e === "POPUP" && (a = new j(r), a.load());
1301
- }
1302
- /**
1303
- * @hidden
1304
- * @param {string} rule A regular expression
1305
- * @returns {boolean} true if rule matches Url, false otherwise
1306
- */
1307
- static _matchesUrl(t) {
1308
- return !!window.location.href.match(new RegExp(t));
1309
- }
1310
- }
1311
- class Oe {
1312
- /**
1313
- * Initialize a new {@link EventsApi} instance.
1314
- *
1315
- * @param {ConfigOptions} config Config details
1316
- *
1317
- * @example <caption>Browser example</caption>
1318
- * var squatchApi = new squatch.EventsApi({tenantAlias:'test_12b5bo1b25125'});
1319
- *
1320
- * @example <caption>Browserify/Webpack example</caption>
1321
- * var EventsApi = require('@saasquatch/squatch-js').EventsApi;
1322
- * var squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1323
- *
1324
- * @example <caption>Babel+Browserify/Webpack example</caption>
1325
- * import {EventsApi} from '@saasquatch/squatch-js';
1326
- * let squatchApi = new EventsApi({tenantAlias:'test_12b5bo1b25125'});
1327
- */
1328
- constructor(t) {
1329
- l(this, "tenantAlias");
1330
- l(this, "domain");
1331
- const n = q(t);
1332
- this.tenantAlias = n.tenantAlias, this.domain = n.domain;
1333
- }
1334
- /**
1335
- * Track an event for a user
1336
- *
1337
- * @param params Parameters for request
1338
- * @param options.jwt the JSON Web Token (JWT) that is used to authenticate the user
1339
- *
1340
- * @return An ID to confirm the event has been accepted for asynchronous processing
1341
- */
1342
- track(t, e) {
1343
- const n = t, i = e, s = je(n), { jwt: r } = De(i), a = encodeURIComponent(this.tenantAlias), d = encodeURIComponent(s.userId), c = encodeURIComponent(s.accountId), h = `/api/v1/${a}/open/account/${c}/user/${d}/events`, u = this.domain + h;
1344
- return X(u, JSON.stringify(s), r);
1345
- }
1346
- }
1347
- function je(o) {
1348
- if (!I(o)) throw new Error("tracking parameter must be an object");
1349
- if (!(o != null && o.accountId)) throw new Error("accountId field is required");
1350
- if (!(o != null && o.events)) throw new Error("events field is required");
1351
- if (!(o != null && o.userId)) throw new Error("userId field is required");
1352
- const t = o;
1353
- if (!Array.isArray(t.events))
1354
- throw new Error("'events' should be an array");
1355
- return t;
1356
- }
1357
- function De(o) {
1358
- if (!I(o)) throw new Error("'options' should be an object");
1359
- return o;
1360
- }
1361
- function Ne() {
1362
- var i;
1363
- const o = window[z] ? z : R, t = ((i = window["_" + o]) == null ? void 0 : i.ready) || [], e = window.impactOnReady || window.squatchOnReady, n = [...t, e].filter((s) => !!s);
1364
- setTimeout(() => {
1365
- window[R] && (window[z] = window[R], n.forEach((s) => s()), window[R]._auto(), window["_" + o] = void 0, delete window["_" + o]);
1366
- }, 0);
1367
- }
1368
- const x = k("squatch-js"), se = (o) => typeof o == "object" && !Array.isArray(o), me = (o, t) => {
1369
- const e = (i) => se(t[i]) && o.hasOwnProperty(i) && se(o[i]), n = Object.getOwnPropertyNames(t).map((i) => ({
1370
- [i]: e(i) ? me(o[i], t[i]) : t[i]
1371
- })).reduce((i, s) => ({ ...i, ...s }), {});
1372
- return {
1373
- ...o,
1374
- ...n
1375
- };
2028
+
2029
+ .hero-image {
2030
+ flex: 1;
2031
+ height: 300px;
2032
+ border-radius: 12px;
2033
+ }
2034
+
2035
+ /* -- Specific Instant Access Overrides -- */
2036
+ .instant-access-layout {
2037
+ margin-bottom: 0;
2038
+ padding-bottom: 0;
2039
+ align-items: center;
2040
+ }
2041
+ .ia-image {
2042
+ height: 400px;
2043
+ }
2044
+ .ia-center {
2045
+ margin-left: auto;
2046
+ margin-right: auto;
2047
+ }
2048
+ .ia-content {
2049
+ align-items: center;
2050
+ text-align: center;
2051
+ }
2052
+ .sk-btn-action {
2053
+ height: 45px;
2054
+ width: 140px;
2055
+ border-radius: 6px;
2056
+ margin: 24px auto;
2057
+ }
2058
+ .input-group {
2059
+ display: flex;
2060
+ gap: 10px;
2061
+ width: 100%;
2062
+ max-width: 400px;
2063
+ }
2064
+ .sk-btn-copy {
2065
+ height: 50px;
2066
+ width: 120px;
2067
+ border-radius: 8px;
2068
+ }
2069
+ /* ------------------------------------- */
2070
+
2071
+ .share-section { margin-bottom: 40px; }
2072
+ .sk-input { height: 50px; width: 100%; border-radius: 8px; margin-bottom: 16px; }
2073
+
2074
+ .social-buttons { display: flex; gap: 12px; }
2075
+ .sk-btn-social { flex: 1; height: 50px; border-radius: 8px; }
2076
+
2077
+ .stats-section {
2078
+ display: flex;
2079
+ gap: 24px;
2080
+ margin-bottom: 40px;
2081
+ padding: 30px 0;
2082
+ /* Removed border-top and border-bottom */
2083
+ }
2084
+ .stat-card { flex: 1; display: flex; flex-direction: column; align-items: center; }
2085
+ .stat-divider { padding-left: 24px; }
2086
+ .sk-stat-num { height: 48px; width: 120px; margin-bottom: 8px; }
2087
+ .sk-stat-label { height: 18px; width: 80px; }
2088
+
2089
+ /* Table Styles */
2090
+ .table-header { display: flex; gap: 16px; margin-bottom: 16px; }
2091
+ .sk-th { height: 16px; }
2092
+ .table-row {
2093
+ display: flex;
2094
+ align-items: center;
2095
+ gap: 16px;
2096
+ padding: 16px 0;
2097
+ /* Removed border-bottom */
2098
+ }
2099
+
2100
+ .col-user { flex: 2; }
2101
+ .col-status { flex: 1; }
2102
+ .col-reward { flex: 2; }
2103
+ .col-date { flex: 1; }
2104
+
2105
+ .sk-badge { height: 28px; width: 90px; border-radius: 14px; }
2106
+ .sk-reward-block { height: 36px; width: 100%; border-radius: 6px; }
2107
+
2108
+ .pagination { display: flex; justify-content: flex-end; gap: 8px; margin-top: 24px; }
2109
+ .sk-btn-page { height: 36px; width: 64px; border-radius: 6px; margin-bottom: 0; }
2110
+
2111
+ @media (max-width: 768px) {
2112
+ body { padding: 20px; }
2113
+ .widget-container { padding: 24px; }
2114
+
2115
+ .hero-section { flex-direction: column-reverse; gap: 24px; }
2116
+ .instant-access-layout { flex-direction: column; }
2117
+
2118
+ .hero-image { height: 220px; width: 100%; }
2119
+ .sk-title-lg { width: 100%; }
2120
+
2121
+ .col-date { display: none; }
2122
+ }
2123
+ </style>
2124
+
2125
+ <div class="widget-container">
2126
+ ${type === "verified-access" ? referrerHTML : instantAccessHTML}
2127
+ </div>
2128
+ `;
1376
2129
  };
1377
- function N(o) {
1378
- const t = atob(o.replace(/_/g, "/").replace(/-/g, "+")), e = new Uint8Array(t.length);
1379
- for (let n = 0; n < t.length; n++)
1380
- e[n] = t.charCodeAt(n);
1381
- return new TextDecoder("utf8").decode(e);
1382
- }
1383
- function re(o) {
1384
- const t = new TextEncoder().encode(o), e = Array.from(
1385
- t,
1386
- (n) => String.fromCodePoint(n)
1387
- ).join("");
1388
- return btoa(e).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1389
- }
1390
- function Fe() {
1391
- var o, t, e = "weird_get_top_level_domain=cookie", n = document.location.hostname.split(".");
1392
- for (o = n.length - 1; o >= 0; o--)
1393
- if (t = n.slice(o).join("."), document.cookie = e + ";domain=." + t + ";", document.cookie.indexOf(e) > -1)
1394
- return document.cookie = e.split("=")[0] + "=;domain=." + t + ";expires=Thu, 01 Jan 1970 00:00:01 GMT;", t;
1395
- }
1396
- function He() {
1397
- const o = window.location.search, e = new URLSearchParams(o).get("_saasquatch") || "";
1398
- if (e) {
1399
- let n = "", i = "", s = "";
1400
- try {
1401
- n = JSON.parse(N(e));
1402
- } catch (r) {
1403
- x("Unable to decode params", r);
1404
- return;
1405
- }
1406
- try {
1407
- i = JSON.parse(N(M.get("_saasquatch"))), x("existing cookie", i);
1408
- } catch (r) {
1409
- x("Unable to retrieve cookie", r);
1410
- }
1411
- try {
1412
- const r = Fe();
1413
- if (x("domain retrieved:", r), i) {
1414
- const a = me(i, n);
1415
- s = re(JSON.stringify(a)), x("cookie to store:", a);
1416
- } else
1417
- s = re(JSON.stringify(n)), x("cookie to store:", n);
1418
- M.set("_saasquatch", s, {
1419
- expires: 365,
1420
- secure: !1,
1421
- sameSite: "Lax",
1422
- domain: r,
1423
- path: "/"
1424
- });
1425
- } catch (r) {
1426
- x("Unable to set cookie", r);
1427
- }
1428
- }
1429
- }
1430
- const P = k("squatch-js");
1431
- function Be() {
1432
- var u;
1433
- const o = window.location.search, e = new URLSearchParams(o).get("_saasquatchExtra") || "";
1434
- if (!e) {
1435
- P("No _saasquatchExtra param");
1436
- return;
1437
- }
1438
- const n = q({
1439
- tenantAlias: "UNKNOWN"
1440
- });
1441
- if (!n.domain) {
1442
- P("domain must be provided in config to use _saasquatchExtra");
1443
- return;
1444
- }
1445
- let i;
2130
+ const _log$2 = browserExports.debug("squatch-js:decodeUserJwt");
2131
+ function decodeUserJwt(tokenStr) {
2132
+ var _a2;
1446
2133
  try {
1447
- i = JSON.parse(N(e));
1448
- } catch {
1449
- P("Unable to decode _saasquatchExtra config");
1450
- return;
1451
- }
1452
- function s(p) {
1453
- return p.replace(/^https?:\/\//, "");
1454
- }
1455
- const r = s(n.domain), a = Object.keys((i == null ? void 0 : i[r]) || {})[0], d = (u = i == null ? void 0 : i[r]) == null ? void 0 : u[a];
1456
- if (!d) {
1457
- P("_saasquatchExtra did not have an expected structure");
1458
- return;
1459
- }
1460
- const { autoPopupWidgetType: c, ...h } = d;
1461
- return {
1462
- widgetConfig: {
1463
- widgetType: c,
1464
- displayOnLoad: !0,
1465
- ...h
1466
- },
1467
- squatchConfig: {
1468
- ...n,
1469
- tenantAlias: a
1470
- }
1471
- };
1472
- }
1473
- const Je = k("squatch-js:decodeUserJwt");
1474
- function ze(o) {
1475
- var t;
1476
- try {
1477
- const e = o.split(".")[1];
1478
- if (e === void 0) return null;
1479
- const n = N(e);
1480
- return (t = JSON.parse(n)) == null ? void 0 : t.user;
2134
+ const base64Url = tokenStr.split(".")[1];
2135
+ if (base64Url === void 0) return null;
2136
+ const jsonStr = b64decode(base64Url);
2137
+ return (_a2 = JSON.parse(jsonStr)) == null ? void 0 : _a2.user;
1481
2138
  } catch (e) {
1482
- return Je(e), null;
2139
+ _log$2(e);
2140
+ return null;
1483
2141
  }
1484
2142
  }
1485
- const ae = k("squatch-js:DeclarativeWidget");
1486
- class ge extends HTMLElement {
2143
+ const _log$1 = debug("squatch-js:DeclarativeWidget");
2144
+ class DeclarativeWidget extends HTMLElement {
1487
2145
  constructor() {
1488
2146
  super();
1489
2147
  /**
1490
2148
  * Configuration overrides
1491
2149
  * @default window.squatchConfig
1492
2150
  */
1493
- l(this, "config");
2151
+ __publicField(this, "config");
1494
2152
  /**
1495
2153
  * Signed JWT containing user information
1496
2154
  * @default window.squatchToken
1497
2155
  */
1498
- l(this, "token");
2156
+ __publicField(this, "token");
1499
2157
  /**
1500
2158
  * Tenant alias of SaaSquatch tenant
1501
2159
  * @default window.squatchTenant
1502
2160
  */
1503
- l(this, "tenant");
2161
+ __publicField(this, "tenant");
1504
2162
  /**
1505
2163
  * widgetType of widget to load
1506
2164
  */
1507
- l(this, "widgetType");
2165
+ __publicField(this, "widgetType");
1508
2166
  /**
1509
2167
  * Locale to render the widget in
1510
2168
  */
1511
- l(this, "locale");
2169
+ __publicField(this, "locale");
1512
2170
  /**
1513
2171
  * Instance of {@link WidgetApi}
1514
2172
  */
1515
- l(this, "widgetApi");
2173
+ __publicField(this, "widgetApi");
1516
2174
  /**
1517
2175
  * Instance of {@link AnalyticsApi}
1518
2176
  */
1519
- l(this, "analyticsApi");
2177
+ __publicField(this, "analyticsApi");
1520
2178
  /**
1521
2179
  * Instance of {@link EmbedWidget} or {@link PopupWidget}
1522
2180
  */
1523
- l(this, "widgetInstance");
2181
+ __publicField(this, "widgetInstance");
1524
2182
  /**
1525
2183
  * Determines whether to render the widget as an embedding widget or popup widget
1526
2184
  */
1527
- l(this, "type");
2185
+ __publicField(this, "type");
1528
2186
  /**
1529
2187
  * Container element to contain the widget iframe
1530
2188
  * @default this
1531
2189
  */
1532
- l(this, "container");
1533
- l(this, "element");
2190
+ __publicField(this, "container");
2191
+ __publicField(this, "element");
1534
2192
  /**
1535
2193
  * Flag for if the component has been loaded or not
1536
2194
  * @hidden
1537
2195
  */
1538
- l(this, "loaded");
1539
- l(this, "_setWidget", (e, n) => {
1540
- var s;
1541
- const i = {
2196
+ __publicField(this, "loaded");
2197
+ __publicField(this, "_setWidget", (res, config) => {
2198
+ var _a2;
2199
+ const params = {
1542
2200
  api: this.widgetApi,
1543
- content: e.template,
2201
+ content: res.template,
1544
2202
  context: {
1545
- type: n.type,
1546
- user: n.user,
2203
+ type: config.type,
2204
+ user: config.user,
1547
2205
  container: this.container || void 0,
1548
2206
  engagementMedium: this.type,
1549
- widgetConfig: e.widgetConfig
2207
+ widgetConfig: res.widgetConfig
1550
2208
  },
1551
2209
  type: this.widgetType,
1552
- domain: ((s = this.config) == null ? void 0 : s.domain) || A,
1553
- npmCdn: V,
2210
+ domain: ((_a2 = this.config) == null ? void 0 : _a2.domain) || DEFAULT_DOMAIN,
2211
+ npmCdn: DEFAULT_NPM_CDN,
1554
2212
  container: this
1555
2213
  };
1556
- if (this.type === "EMBED")
1557
- return new O(i);
1558
- {
1559
- const r = this.firstChild ? null : void 0;
1560
- return new j(i, r);
2214
+ if (this.type === "EMBED") {
2215
+ return new EmbedWidget(params);
2216
+ } else {
2217
+ const useFirstChildTrigger = this.firstChild ? null : void 0;
2218
+ return new PopupWidget(params, useFirstChildTrigger);
1561
2219
  }
1562
2220
  });
1563
2221
  /**
1564
2222
  * Builds a Widget instance for the default error widget
1565
2223
  * @returns Instance of either {@link EmbedWidget} or {@link PopupWidget} depending on `this.type`
1566
2224
  */
1567
- l(this, "setErrorWidget", (e) => {
1568
- var i;
1569
- const n = {
2225
+ __publicField(this, "setErrorWidget", (e) => {
2226
+ var _a2;
2227
+ const params = {
1570
2228
  api: this.widgetApi,
1571
2229
  content: "error",
1572
2230
  context: {
@@ -1574,58 +2232,76 @@ class ge extends HTMLElement {
1574
2232
  container: this.container || void 0
1575
2233
  },
1576
2234
  type: "ERROR_WIDGET",
1577
- domain: ((i = this.config) == null ? void 0 : i.domain) || A,
1578
- npmCdn: V,
2235
+ domain: ((_a2 = this.config) == null ? void 0 : _a2.domain) || DEFAULT_DOMAIN,
2236
+ npmCdn: DEFAULT_NPM_CDN,
1579
2237
  container: this
1580
2238
  };
1581
- if (this.type === "EMBED")
1582
- return new O(n);
1583
- {
1584
- const s = this.firstChild ? null : void 0;
1585
- return new j(n, s);
2239
+ if (this.type === "EMBED") {
2240
+ return new EmbedWidget(params);
2241
+ } else {
2242
+ const useFirstChildTrigger = this.firstChild ? null : void 0;
2243
+ return new PopupWidget(params, useFirstChildTrigger);
1586
2244
  }
1587
2245
  });
1588
- l(this, "reload", this.renderWidget);
1589
- l(this, "show", this.open);
1590
- l(this, "hide", this.close);
2246
+ __publicField(this, "reload", this.renderWidget);
2247
+ __publicField(this, "show", this.open);
2248
+ __publicField(this, "hide", this.close);
1591
2249
  this.attachShadow({
1592
2250
  mode: "open"
1593
- }).innerHTML = "<style>:host { display: block; }</style><slot></slot>", this.config = Y(), this.token = W(), this.tenant = window.squatchTenant, this.container = this;
1594
- }
1595
- _setupApis(e) {
1596
- var n, i;
2251
+ }).innerHTML = `<style>:host { display: block; }</style><slot></slot>`;
2252
+ this.config = getConfig();
2253
+ this.token = getToken();
2254
+ this.tenant = window.squatchTenant;
2255
+ this.container = this;
2256
+ }
2257
+ _setupApis(config) {
2258
+ var _a2, _b;
1597
2259
  if (!this.tenant) throw new Error("tenantAlias not provided");
1598
- this.widgetApi = new K({
1599
- tenantAlias: (e == null ? void 0 : e.tenantAlias) || this.tenant,
1600
- domain: (e == null ? void 0 : e.domain) || ((n = this.config) == null ? void 0 : n.domain) || A
1601
- }), this.analyticsApi = new he({
1602
- domain: (e == null ? void 0 : e.domain) || ((i = this.config) == null ? void 0 : i.domain) || A
2260
+ this.widgetApi = new WidgetApi({
2261
+ tenantAlias: (config == null ? void 0 : config.tenantAlias) || this.tenant,
2262
+ domain: (config == null ? void 0 : config.domain) || ((_a2 = this.config) == null ? void 0 : _a2.domain) || DEFAULT_DOMAIN
2263
+ });
2264
+ this.analyticsApi = new AnalyticsApi({
2265
+ domain: (config == null ? void 0 : config.domain) || ((_b = this.config) == null ? void 0 : _b.domain) || DEFAULT_DOMAIN
1603
2266
  });
1604
2267
  }
1605
- getWidgetType(e) {
1606
- return e && (e.includes("websiteReferralWidget") || e.includes("friendWidget")) ? "instant-access" : "verified-access";
2268
+ getWidgetType(widgetType) {
2269
+ if (widgetType && (widgetType.includes("websiteReferralWidget") || widgetType.includes("friendWidget"))) {
2270
+ return "instant-access";
2271
+ }
2272
+ return "verified-access";
1607
2273
  }
1608
2274
  async renderPasswordlessVariant() {
1609
- return this._setupApis(), ae("Rendering as an Instant Access widget"), await this.widgetApi.render({
2275
+ this._setupApis();
2276
+ _log$1("Rendering as an Instant Access widget");
2277
+ return await this.widgetApi.render({
1610
2278
  engagementMedium: this.type,
1611
2279
  widgetType: this.widgetType,
1612
2280
  locale: this.locale
1613
- }).then((e) => this._setWidget(e, { type: "passwordless" })).catch(this.setErrorWidget);
2281
+ }).then((res) => this._setWidget(res, { type: "passwordless" })).catch(this.setErrorWidget);
1614
2282
  }
1615
2283
  async renderUserUpsertVariant() {
1616
2284
  this._setupApis();
1617
- const e = ze(this.token);
1618
- return e ? (ae("Rendering as a Verified widget"), await this.widgetApi.upsertUser({
1619
- user: e,
2285
+ const userObj = decodeUserJwt(this.token);
2286
+ if (!userObj) {
2287
+ return this.setErrorWidget(Error("No user object in token."));
2288
+ }
2289
+ _log$1("Rendering as a Verified widget");
2290
+ await this.widgetApi.upsertUser({
2291
+ user: userObj,
1620
2292
  locale: this.locale,
1621
2293
  engagementMedium: this.type,
1622
2294
  widgetType: this.widgetType,
1623
2295
  jwt: this.token
1624
- }), await this.widgetApi.render({
2296
+ });
2297
+ const widgetInstance = await this.widgetApi.render({
1625
2298
  locale: this.locale,
1626
2299
  engagementMedium: this.type,
1627
2300
  widgetType: this.widgetType
1628
- }).then((i) => this._setWidget(i, { type: "upsert", user: e })).catch(this.setErrorWidget)) : this.setErrorWidget(Error("No user object in token."));
2301
+ }).then((res) => {
2302
+ return this._setWidget(res, { type: "upsert", user: userObj });
2303
+ }).catch(this.setErrorWidget);
2304
+ return widgetInstance;
1629
2305
  }
1630
2306
  /**
1631
2307
  * Fetches widget content from SaaSquatch and builds a Widget instance to support rendering the widget in the DOM
@@ -1633,15 +2309,26 @@ class ge extends HTMLElement {
1633
2309
  * @throws Throws an Error if `widgetType` is undefined
1634
2310
  */
1635
2311
  async getWidgetInstance() {
1636
- let e;
1637
- if (this.widgetType = this.getAttribute("widget") || void 0, this.locale = this.getAttribute("locale") || this.locale, !this.widgetType) throw new Error("No widget has been specified");
1638
- return this.token ? e = await this.renderUserUpsertVariant() : e = await this.renderPasswordlessVariant(), this.widgetInstance = e, this.widgetInstance && this.dispatchEvent(new CustomEvent("sq:widget-loaded")), e;
2312
+ let widgetInstance;
2313
+ this.widgetType = this.getAttribute("widget") || void 0;
2314
+ this.locale = this.getAttribute("locale") || this.locale;
2315
+ if (!this.widgetType) throw new Error("No widget has been specified");
2316
+ if (!this.token) {
2317
+ widgetInstance = await this.renderPasswordlessVariant();
2318
+ } else {
2319
+ widgetInstance = await this.renderUserUpsertVariant();
2320
+ }
2321
+ this.widgetInstance = widgetInstance;
2322
+ if (this.widgetInstance)
2323
+ this.dispatchEvent(new CustomEvent("sq:widget-loaded"));
2324
+ return widgetInstance;
1639
2325
  }
1640
2326
  /**
1641
2327
  * Calls {@link getWidgetInstance} to build the Widget instance and loads the widget iframe into the DOM
1642
2328
  */
1643
2329
  async renderWidget() {
1644
- await this.getWidgetInstance(), await this.widgetInstance.load();
2330
+ await this.getWidgetInstance();
2331
+ await this.widgetInstance.load();
1645
2332
  }
1646
2333
  /**
1647
2334
  * Calls `open` method of `widgetInstance`
@@ -1659,123 +2346,197 @@ class ge extends HTMLElement {
1659
2346
  if (!this.widgetInstance) throw new Error("Widget has not loaded yet");
1660
2347
  this.widgetInstance.close();
1661
2348
  }
2349
+ }
2350
+ class DeclarativeEmbedWidget extends DeclarativeWidget {
2351
+ constructor() {
2352
+ super();
2353
+ this.type = "EMBED";
2354
+ this.loaded = false;
2355
+ }
1662
2356
  static get observedAttributes() {
1663
2357
  return ["widget", "locale"];
1664
2358
  }
1665
- attributeChangedCallback(e, n, i) {
1666
- if (!(n === i || !this.loaded))
1667
- switch (e) {
1668
- case "locale":
1669
- case "widget":
1670
- this.connectedCallback();
1671
- break;
1672
- }
2359
+ attributeChangedCallback(attr, oldVal, newVal) {
2360
+ if (oldVal === newVal || !this.loaded) return;
2361
+ switch (attr) {
2362
+ case "locale":
2363
+ case "widget":
2364
+ this.connectedCallback();
2365
+ break;
2366
+ }
1673
2367
  }
1674
2368
  async connectedCallback() {
1675
- this.loaded = !0, this.container = this.getAttribute("container"), this.widgetType = this.getAttribute("widget") || void 0;
1676
- const e = this.getWidgetType(this.widgetType), { getSkeleton: n } = await Promise.resolve().then(() => Pe), i = n({
2369
+ this.loaded = true;
2370
+ this.container = this.getAttribute("container");
2371
+ this.widgetType = this.getAttribute("widget") || void 0;
2372
+ console.log("widget type", this.widgetType);
2373
+ const skeletonWidgetType = this.getWidgetType(this.widgetType);
2374
+ const skeletonHTML = getSkeleton({
1677
2375
  height: "100%",
1678
- type: e
1679
- }), s = document.createElement("div");
1680
- s.id = "loading-skeleton", s.innerHTML = i;
1681
- const r = this.shadowRoot || this.attachShadow({ mode: "open" });
1682
- if (this.type === "POPUP") {
1683
- const d = r.getElementById("#squatchModal");
1684
- d && (d.innerHTML = "", d.appendChild(s));
1685
- } else
1686
- r.innerHTML = "", r.appendChild(s);
2376
+ type: skeletonWidgetType
2377
+ });
2378
+ const skeletonContainer = document.createElement("div");
2379
+ skeletonContainer.id = "loading-skeleton";
2380
+ skeletonContainer.innerHTML = skeletonHTML;
2381
+ const root = this.shadowRoot || this.attachShadow({ mode: "open" });
2382
+ root.innerHTML = "";
2383
+ root.appendChild(skeletonContainer);
1687
2384
  await this.renderWidget();
1688
- const a = r.getElementById("loading-skeleton");
1689
- a && a.remove(), this.getAttribute("open") !== null && this.open();
2385
+ const loadingElement = root.getElementById("loading-skeleton");
2386
+ if (loadingElement) {
2387
+ loadingElement.remove();
2388
+ }
2389
+ if (this.getAttribute("open") !== null) this.open();
1690
2390
  }
1691
2391
  }
1692
- class fe extends ge {
2392
+ class DeclarativePopupWidget extends DeclarativeWidget {
1693
2393
  constructor() {
1694
- super(), this.type = "EMBED", this.loaded = !1;
2394
+ super();
2395
+ this.type = "POPUP";
2396
+ this.loaded = false;
2397
+ this.addEventListener("click", (e) => {
2398
+ e.stopPropagation();
2399
+ this.open();
2400
+ });
1695
2401
  }
1696
- }
1697
- class we extends ge {
1698
- constructor() {
1699
- super(), this.type = "POPUP", this.loaded = !1, this.addEventListener("click", (t) => {
1700
- t.stopPropagation(), this.open();
2402
+ static get observedAttributes() {
2403
+ return ["widget", "locale"];
2404
+ }
2405
+ attributeChangedCallback(attr, oldVal, newVal) {
2406
+ if (oldVal === newVal || !this.loaded) return;
2407
+ switch (attr) {
2408
+ case "locale":
2409
+ case "widget":
2410
+ this.connectedCallback();
2411
+ break;
2412
+ }
2413
+ }
2414
+ async connectedCallback() {
2415
+ this.loaded = true;
2416
+ this.container = this.getAttribute("container");
2417
+ this.widgetType = this.getAttribute("widget") || void 0;
2418
+ const skeletonWidgetType = this.getWidgetType(this.widgetType);
2419
+ const skeletonHTML = getSkeleton({
2420
+ height: "100%",
2421
+ type: skeletonWidgetType
1701
2422
  });
2423
+ const skeletonContainer = document.createElement("div");
2424
+ skeletonContainer.id = "loading-skeleton";
2425
+ skeletonContainer.innerHTML = skeletonHTML;
2426
+ const root = this.shadowRoot || this.attachShadow({ mode: "open" });
2427
+ const container = root.getElementById("#squatchModal");
2428
+ console.log("Container is ", container);
2429
+ if (container) {
2430
+ container.innerHTML = "";
2431
+ container.appendChild(skeletonContainer);
2432
+ }
2433
+ await this.renderWidget();
2434
+ const loadingElement = root.getElementById("loading-skeleton");
2435
+ if (loadingElement) {
2436
+ loadingElement.remove();
2437
+ }
2438
+ if (this.getAttribute("open") !== null) this.open();
1702
2439
  }
1703
2440
  }
1704
- class Ge extends fe {
2441
+ class SquatchEmbed extends DeclarativeEmbedWidget {
1705
2442
  }
1706
- class Ve extends we {
2443
+ class SquatchPopup extends DeclarativePopupWidget {
1707
2444
  }
1708
- class Xe extends fe {
2445
+ class ImpactEmbed extends DeclarativeEmbedWidget {
1709
2446
  }
1710
- class Qe extends we {
2447
+ class ImpactPopup extends DeclarativePopupWidget {
1711
2448
  }
1712
- window.customElements.get("squatch-embed") || window.customElements.define("squatch-embed", Ge);
1713
- window.customElements.get("impact-embed") || window.customElements.define("impact-embed", Xe);
1714
- window.customElements.get("squatch-popup") || window.customElements.define("squatch-popup", Ve);
1715
- window.customElements.get("impact-popup") || window.customElements.define("impact-popup", Qe);
1716
- function Ze() {
2449
+ if (!window.customElements.get("squatch-embed"))
2450
+ window.customElements.define("squatch-embed", SquatchEmbed);
2451
+ if (!window.customElements.get("impact-embed"))
2452
+ window.customElements.define("impact-embed", ImpactEmbed);
2453
+ if (!window.customElements.get("squatch-popup"))
2454
+ window.customElements.define("squatch-popup", SquatchPopup);
2455
+ if (!window.customElements.get("impact-popup"))
2456
+ window.customElements.define("impact-popup", ImpactPopup);
2457
+ function help() {
1717
2458
  console.log(
1718
- "Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes."
2459
+ `Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.`
1719
2460
  );
1720
2461
  }
1721
- const $ = k("squatch-js");
1722
- let F = null, H = null, B = null;
1723
- function et() {
1724
- return F || J({}), F;
2462
+ const _log = browserExports.debug("squatch-js");
2463
+ let _api = null;
2464
+ let _widgets = null;
2465
+ let _events = null;
2466
+ function api() {
2467
+ if (!_api) init({});
2468
+ return _api;
1725
2469
  }
1726
- function Z() {
1727
- return H || J({}), H;
2470
+ function widgets() {
2471
+ if (!_widgets) init({});
2472
+ return _widgets;
1728
2473
  }
1729
- function tt() {
1730
- return B || J({}), B;
2474
+ function events() {
2475
+ if (!_events) init({});
2476
+ return _events;
1731
2477
  }
1732
- function nt(o) {
1733
- var t;
1734
- return (t = Z()) == null ? void 0 : t.render(o);
2478
+ function widget(widgetConfig) {
2479
+ var _a2;
2480
+ return (_a2 = widgets()) == null ? void 0 : _a2.render(widgetConfig);
1735
2481
  }
1736
- function it() {
1737
- var t;
1738
- const o = Be();
1739
- if (o) {
1740
- const { squatchConfig: e, widgetConfig: n } = o;
1741
- return J(e), (t = Z()) == null ? void 0 : t.render(n);
2482
+ function _auto() {
2483
+ var _a2;
2484
+ const configs = _getAutoConfig();
2485
+ if (configs) {
2486
+ const { squatchConfig, widgetConfig } = configs;
2487
+ init(squatchConfig);
2488
+ return (_a2 = widgets()) == null ? void 0 : _a2.render(widgetConfig);
1742
2489
  }
1743
2490
  }
1744
- function J(o) {
1745
- const e = q(o);
1746
- e.tenantAlias.match("^test") || e.debug ? Ae("squatch-js*") : Ie(), $("initializing ..."), F = new K(e), H = new D(e), B = new Oe(e), $("Widget API instance", F), $("Widgets instance", H), $("Events API instance", B);
2491
+ function init(configIn) {
2492
+ const raw = configIn;
2493
+ const config = validateConfig(raw);
2494
+ if (config.tenantAlias.match("^test") || config.debug) {
2495
+ browserExports.debug.enable("squatch-js*");
2496
+ } else {
2497
+ browserExports.debug.disable();
2498
+ }
2499
+ _log("initializing ...");
2500
+ _api = new WidgetApi(config);
2501
+ _widgets = new Widgets(config);
2502
+ _events = new EventsApi(config);
2503
+ _log("Widget API instance", _api);
2504
+ _log("Widgets instance", _widgets);
2505
+ _log("Events API instance", _events);
1747
2506
  }
1748
- function ot(o) {
1749
- o();
2507
+ function ready(fn) {
2508
+ fn();
1750
2509
  }
1751
- function st(o) {
1752
- Z().autofill(o);
2510
+ function autofill(selector) {
2511
+ widgets().autofill(selector);
1753
2512
  }
1754
- function Ye() {
1755
- He();
2513
+ function pushCookie() {
2514
+ _pushCookie();
1756
2515
  }
1757
- typeof document < "u" && !window.SaaSquatchDoNotAutoDrop && Ye();
1758
- var de;
1759
- (de = window.squatch) != null && de.init && $(
1760
- "Squatchjs is being loaded more than once. This may lead to multiple load events being sent, duplicated widgets, and inaccurate analytics."
1761
- );
1762
- typeof document < "u" && Ne();
2516
+ if (typeof document !== "undefined" && !window.SaaSquatchDoNotAutoDrop) {
2517
+ pushCookie();
2518
+ }
2519
+ if ((_a = window["squatch"]) == null ? void 0 : _a.init)
2520
+ _log(
2521
+ "Squatchjs is being loaded more than once. This may lead to multiple load events being sent, duplicated widgets, and inaccurate analytics."
2522
+ );
2523
+ if (typeof document !== "undefined") asyncLoad();
1763
2524
  export {
1764
- fe as DeclarativeEmbedWidget,
1765
- we as DeclarativePopupWidget,
1766
- O as EmbedWidget,
1767
- j as PopupWidget,
1768
- K as WidgetApi,
1769
- D as Widgets,
1770
- it as _auto,
1771
- et as api,
1772
- st as autofill,
1773
- tt as events,
1774
- Ze as help,
1775
- J as init,
1776
- Ye as pushCookie,
1777
- ot as ready,
1778
- nt as widget,
1779
- Z as widgets
2525
+ DeclarativeEmbedWidget,
2526
+ DeclarativePopupWidget,
2527
+ EmbedWidget,
2528
+ PopupWidget,
2529
+ WidgetApi,
2530
+ Widgets,
2531
+ _auto,
2532
+ api,
2533
+ autofill,
2534
+ events,
2535
+ help,
2536
+ init,
2537
+ pushCookie,
2538
+ ready,
2539
+ widget,
2540
+ widgets
1780
2541
  };
1781
2542
  //# sourceMappingURL=squatch.esm.js.map