clarity-js 0.6.43 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/clarity.js CHANGED
@@ -84,12 +84,14 @@ var config$1 = {
84
84
  lean: false,
85
85
  track: true,
86
86
  content: true,
87
+ drop: [],
87
88
  mask: [],
88
89
  unmask: [],
89
90
  regions: [],
90
91
  extract: [],
91
92
  cookies: [],
92
- fraud: [],
93
+ fraud: true,
94
+ checksum: [],
93
95
  report: null,
94
96
  upload: null,
95
97
  fallback: null,
@@ -105,22 +107,23 @@ function api(method) {
105
107
  }
106
108
 
107
109
  var startTime = 0;
108
- function start$F() {
110
+ function start$G() {
109
111
  startTime = performance.now();
110
112
  }
111
- function time(ts) {
112
- if (ts === void 0) { ts = null; }
113
- ts = ts ? ts : performance.now();
113
+ function time(event) {
114
+ if (event === void 0) { event = null; }
115
+ var ts = event && event.timeStamp > 0 ? event.timeStamp : performance.now();
114
116
  return Math.max(Math.round(ts - startTime), 0);
115
117
  }
116
- function stop$B() {
118
+ function stop$C() {
117
119
  startTime = 0;
118
120
  }
119
121
 
120
- var version$1 = "0.6.43";
122
+ var version$1 = "0.7.0";
121
123
 
122
124
  // tslint:disable: no-bitwise
123
- function hash (input) {
125
+ function hash (input, precision) {
126
+ if (precision === void 0) { precision = null; }
124
127
  // Code inspired from C# GetHashCode: https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/string.cs
125
128
  var hash = 0;
126
129
  var hashOne = 5381;
@@ -136,21 +139,164 @@ function hash (input) {
136
139
  // Replace the magic number from C# implementation (1566083941) with a smaller prime number (11579)
137
140
  // This ensures we don't hit integer overflow and prevent collisions
138
141
  hash = Math.abs(hashOne + (hashTwo * 11579));
139
- return hash.toString(36);
142
+ return (precision ? hash % Math.pow(2, precision) : hash).toString(36);
143
+ }
144
+
145
+ var catchallRegex = /\S/gi;
146
+ var unicodeRegex = true;
147
+ var digitRegex = null;
148
+ var letterRegex = null;
149
+ var currencyRegex = null;
150
+ function text$1(value, hint, privacy, mangle) {
151
+ if (mangle === void 0) { mangle = false; }
152
+ if (value) {
153
+ switch (privacy) {
154
+ case 0 /* Privacy.None */:
155
+ return value;
156
+ case 1 /* Privacy.Sensitive */:
157
+ switch (hint) {
158
+ case "*T" /* Layout.Constant.TextTag */:
159
+ case "value":
160
+ case "placeholder":
161
+ case "click":
162
+ return redact(value);
163
+ case "input":
164
+ case "change":
165
+ return mangleToken(value);
166
+ }
167
+ return value;
168
+ case 2 /* Privacy.Text */:
169
+ case 3 /* Privacy.TextImage */:
170
+ switch (hint) {
171
+ case "*T" /* Layout.Constant.TextTag */:
172
+ return mangle ? mangleText(value) : mask(value);
173
+ case "src":
174
+ case "srcset":
175
+ case "title":
176
+ case "alt":
177
+ return privacy === 3 /* Privacy.TextImage */ ? "" /* Data.Constant.Empty */ : value;
178
+ case "value":
179
+ case "click":
180
+ case "input":
181
+ case "change":
182
+ return mangleToken(value);
183
+ case "placeholder":
184
+ return mask(value);
185
+ }
186
+ break;
187
+ case 4 /* Privacy.Exclude */:
188
+ switch (hint) {
189
+ case "value":
190
+ case "input":
191
+ case "click":
192
+ case "change":
193
+ return Array(5 /* Data.Setting.WordLength */).join("\u2022" /* Data.Constant.Mask */);
194
+ case "checksum":
195
+ return "" /* Data.Constant.Empty */;
196
+ }
197
+ }
198
+ }
199
+ return value;
200
+ }
201
+ function url$1(input) {
202
+ var drop = config$1.drop;
203
+ if (drop && drop.length > 0 && input && input.indexOf("?") > 0) {
204
+ var _a = input.split("?"), path = _a[0], query = _a[1];
205
+ var swap_1 = "*na*" /* Data.Constant.Dropped */;
206
+ return path + "?" + query.split("&").map(function (p) { return drop.some(function (x) { return p.indexOf("".concat(x, "=")) === 0; }) ? "".concat(p.split("=")[0], "=").concat(swap_1) : p; }).join("&");
207
+ }
208
+ return input;
209
+ }
210
+ function mangleText(value) {
211
+ var trimmed = value.trim();
212
+ if (trimmed.length > 0) {
213
+ var first = trimmed[0];
214
+ var index = value.indexOf(first);
215
+ var prefix = value.substr(0, index);
216
+ var suffix = value.substr(index + trimmed.length);
217
+ return "".concat(prefix).concat(trimmed.length.toString(36)).concat(suffix);
218
+ }
219
+ return value;
220
+ }
221
+ function mask(value) {
222
+ return value.replace(catchallRegex, "\u2022" /* Data.Constant.Mask */);
223
+ }
224
+ function mangleToken(value) {
225
+ var length = ((Math.floor(value.length / 5 /* Data.Setting.WordLength */) + 1) * 5 /* Data.Setting.WordLength */);
226
+ var output = "" /* Layout.Constant.Empty */;
227
+ for (var i = 0; i < length; i++) {
228
+ output += i > 0 && i % 5 /* Data.Setting.WordLength */ === 0 ? " " /* Data.Constant.Space */ : "\u2022" /* Data.Constant.Mask */;
229
+ }
230
+ return output;
231
+ }
232
+ function redact(value) {
233
+ var spaceIndex = -1;
234
+ var gap = 0;
235
+ var hasDigit = false;
236
+ var hasEmail = false;
237
+ var hasWhitespace = false;
238
+ var array = null;
239
+ // Initialize unicode regex, if supported by the browser
240
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
241
+ if (unicodeRegex && digitRegex === null) {
242
+ try {
243
+ digitRegex = new RegExp("\\p{N}", "gu");
244
+ letterRegex = new RegExp("\\p{L}", "gu");
245
+ currencyRegex = new RegExp("\\p{Sc}", "gu");
246
+ }
247
+ catch (_a) {
248
+ unicodeRegex = false;
249
+ }
250
+ }
251
+ for (var i = 0; i < value.length; i++) {
252
+ var c = value.charCodeAt(i);
253
+ hasDigit = hasDigit || (c >= 48 /* Data.Character.Zero */ && c <= 57 /* Data.Character.Nine */); // Check for digits in the current word
254
+ hasEmail = hasEmail || c === 64 /* Data.Character.At */; // Check for @ sign anywhere within the current word
255
+ hasWhitespace = c === 9 /* Data.Character.Tab */ || c === 10 /* Data.Character.NewLine */ || c === 13 /* Data.Character.Return */ || c === 32 /* Data.Character.Blank */;
256
+ // Process each word as an individual token to redact any sensitive information
257
+ if (i === 0 || i === value.length - 1 || hasWhitespace) {
258
+ // Performance optimization: Lazy load string -> array conversion only when required
259
+ if (hasDigit || hasEmail) {
260
+ if (array === null) {
261
+ array = value.split("" /* Data.Constant.Empty */);
262
+ }
263
+ // Work on a token at a time so we don't have to apply regex to a larger string
264
+ var token = value.substring(spaceIndex + 1, hasWhitespace ? i : i + 1);
265
+ // Check if unicode regex is supported, otherwise fallback to calling mask function on this token
266
+ if (unicodeRegex && currencyRegex !== null) {
267
+ // Do not redact information if the token contains a currency symbol
268
+ token = token.match(currencyRegex) ? token : token.replace(letterRegex, "\u25AA" /* Data.Constant.Letter */).replace(digitRegex, "\u25AB" /* Data.Constant.Digit */);
269
+ }
270
+ else {
271
+ token = mask(token);
272
+ }
273
+ // Merge token back into array at the right place
274
+ array.splice(spaceIndex + 1 - gap, token.length, token);
275
+ gap += token.length - 1;
276
+ }
277
+ // Reset digit and email flags after every word boundary, except the beginning of string
278
+ if (hasWhitespace) {
279
+ hasDigit = false;
280
+ hasEmail = false;
281
+ spaceIndex = i;
282
+ }
283
+ }
284
+ }
285
+ return array ? array.join("" /* Data.Constant.Empty */) : value;
140
286
  }
141
287
 
142
- var state$9 = null;
288
+ var state$a = null;
143
289
  var buffer = null;
144
290
  var update$2 = false;
145
- function start$E() {
291
+ function start$F() {
146
292
  update$2 = false;
147
- reset$p();
293
+ reset$q();
148
294
  }
149
- function reset$p() {
295
+ function reset$q() {
150
296
  // Baseline state holds the previous values - if it is updated in the current payload,
151
297
  // reset the state to current value after sending the previous state
152
298
  if (update$2) {
153
- state$9 = { time: time(), event: 4 /* Event.Baseline */, data: {
299
+ state$a = { time: time(), event: 4 /* Event.Baseline */, data: {
154
300
  visible: buffer.visible,
155
301
  docWidth: buffer.docWidth,
156
302
  docHeight: buffer.docHeight,
@@ -213,20 +359,20 @@ function compute$c() {
213
359
  encode$1(4 /* Event.Baseline */);
214
360
  }
215
361
  }
216
- function stop$A() {
217
- reset$p();
362
+ function stop$B() {
363
+ reset$q();
218
364
  }
219
365
 
220
366
  var baseline = /*#__PURE__*/Object.freeze({
221
367
  __proto__: null,
222
- get state () { return state$9; },
223
- start: start$E,
224
- reset: reset$p,
368
+ get state () { return state$a; },
369
+ start: start$F,
370
+ reset: reset$q,
225
371
  track: track$7,
226
372
  activity: activity,
227
373
  visibility: visibility,
228
374
  compute: compute$c,
229
- stop: stop$A
375
+ stop: stop$B
230
376
  });
231
377
 
232
378
  var data$j = null;
@@ -245,12 +391,12 @@ function event(key, value) {
245
391
 
246
392
  var data$i = null;
247
393
  var updates$3 = null;
248
- function start$D() {
394
+ function start$E() {
249
395
  data$i = {};
250
396
  updates$3 = {};
251
397
  count$1(5 /* Metric.InvokeCount */);
252
398
  }
253
- function stop$z() {
399
+ function stop$A() {
254
400
  data$i = {};
255
401
  updates$3 = {};
256
402
  }
@@ -291,7 +437,7 @@ function max(metric, value) {
291
437
  function compute$b() {
292
438
  encode$1(0 /* Event.Metric */);
293
439
  }
294
- function reset$o() {
440
+ function reset$p() {
295
441
  updates$3 = {};
296
442
  }
297
443
 
@@ -306,11 +452,11 @@ var data$h;
306
452
  var last = 0;
307
453
  var interval = 0;
308
454
  var timeout$6 = null;
309
- function start$C() {
455
+ function start$D() {
310
456
  interval = 60000 /* Setting.PingInterval */;
311
457
  last = 0;
312
458
  }
313
- function reset$n() {
459
+ function reset$o() {
314
460
  if (timeout$6) {
315
461
  clearTimeout(timeout$6);
316
462
  }
@@ -328,7 +474,7 @@ function ping() {
328
474
  suspend();
329
475
  }
330
476
  }
331
- function stop$y() {
477
+ function stop$z() {
332
478
  clearTimeout(timeout$6);
333
479
  last = 0;
334
480
  interval = 0;
@@ -337,16 +483,16 @@ function stop$y() {
337
483
  var ping$1 = /*#__PURE__*/Object.freeze({
338
484
  __proto__: null,
339
485
  get data () { return data$h; },
340
- start: start$C,
341
- reset: reset$n,
342
- stop: stop$y
486
+ start: start$D,
487
+ reset: reset$o,
488
+ stop: stop$z
343
489
  });
344
490
 
345
491
  var data$g = null;
346
- function start$B() {
492
+ function start$C() {
347
493
  data$g = {};
348
494
  }
349
- function stop$x() {
495
+ function stop$y() {
350
496
  data$g = {};
351
497
  }
352
498
  function track$6(event, time) {
@@ -369,22 +515,22 @@ function track$6(event, time) {
369
515
  function compute$a() {
370
516
  encode$1(36 /* Event.Summary */);
371
517
  }
372
- function reset$m() {
518
+ function reset$n() {
373
519
  data$g = {};
374
520
  }
375
521
 
376
522
  var summary = /*#__PURE__*/Object.freeze({
377
523
  __proto__: null,
378
524
  get data () { return data$g; },
379
- start: start$B,
380
- stop: stop$x,
525
+ start: start$C,
526
+ stop: stop$y,
381
527
  track: track$6,
382
528
  compute: compute$a,
383
- reset: reset$m
529
+ reset: reset$n
384
530
  });
385
531
 
386
532
  var data$f = null;
387
- function start$A() {
533
+ function start$B() {
388
534
  if (!config$1.lean && config$1.upgrade) {
389
535
  config$1.upgrade("Config" /* Constant.Config */);
390
536
  }
@@ -408,21 +554,21 @@ function upgrade(key) {
408
554
  encode$1(3 /* Event.Upgrade */);
409
555
  }
410
556
  }
411
- function stop$w() {
557
+ function stop$x() {
412
558
  data$f = null;
413
559
  }
414
560
 
415
561
  var upgrade$1 = /*#__PURE__*/Object.freeze({
416
562
  __proto__: null,
417
563
  get data () { return data$f; },
418
- start: start$A,
564
+ start: start$B,
419
565
  upgrade: upgrade,
420
- stop: stop$w
566
+ stop: stop$x
421
567
  });
422
568
 
423
569
  var data$e = null;
424
- function start$z() {
425
- reset$l();
570
+ function start$A() {
571
+ reset$m();
426
572
  }
427
573
  function set(variable, value) {
428
574
  var values = typeof value === "string" /* Constant.String */ ? [value] : value;
@@ -453,22 +599,22 @@ function log$2(variable, value) {
453
599
  function compute$9() {
454
600
  encode$1(34 /* Event.Variable */);
455
601
  }
456
- function reset$l() {
602
+ function reset$m() {
457
603
  data$e = {};
458
604
  }
459
- function stop$v() {
460
- reset$l();
605
+ function stop$w() {
606
+ reset$m();
461
607
  }
462
608
 
463
609
  var variable = /*#__PURE__*/Object.freeze({
464
610
  __proto__: null,
465
611
  get data () { return data$e; },
466
- start: start$z,
612
+ start: start$A,
467
613
  set: set,
468
614
  identify: identify,
469
615
  compute: compute$9,
470
- reset: reset$l,
471
- stop: stop$v
616
+ reset: reset$m,
617
+ stop: stop$w
472
618
  });
473
619
 
474
620
  /******************************************************************************
@@ -583,18 +729,18 @@ function read(stream) {
583
729
  }
584
730
 
585
731
  var modules$1 = [baseline, dimension, variable, limit, summary, metadata$1, envelope$1, upload$1, ping$1, upgrade$1, extract];
586
- function start$y() {
732
+ function start$z() {
587
733
  // Metric needs to be initialized before we can start measuring. so metric is not wrapped in measure
588
- start$D();
734
+ start$E();
589
735
  modules$1.forEach(function (x) { return measure(x.start)(); });
590
736
  }
591
- function stop$u() {
737
+ function stop$v() {
592
738
  // Stop modules in the reverse order of their initialization
593
739
  // The ordering below should respect inter-module dependency.
594
740
  // E.g. if upgrade depends on upload, then upgrade needs to end before upload.
595
741
  // Similarly, if upload depends on metadata, upload needs to end before metadata.
596
742
  modules$1.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
597
- stop$z();
743
+ stop$A();
598
744
  }
599
745
  function compute$8() {
600
746
  compute$9();
@@ -606,130 +752,9 @@ function compute$8() {
606
752
  compute$4();
607
753
  }
608
754
 
609
- var catchallRegex = /\S/gi;
610
- var unicodeRegex = true;
611
- var digitRegex = null;
612
- var letterRegex = null;
613
- var currencyRegex = null;
614
- function scrub (value, hint, privacy, mangle) {
615
- if (mangle === void 0) { mangle = false; }
616
- if (value) {
617
- switch (privacy) {
618
- case 0 /* Privacy.None */:
619
- return value;
620
- case 1 /* Privacy.Sensitive */:
621
- switch (hint) {
622
- case "*T" /* Layout.Constant.TextTag */:
623
- case "value":
624
- case "placeholder":
625
- case "click":
626
- case "input":
627
- return redact(value);
628
- }
629
- return value;
630
- case 2 /* Privacy.Text */:
631
- case 3 /* Privacy.TextImage */:
632
- switch (hint) {
633
- case "*T" /* Layout.Constant.TextTag */:
634
- return mangle ? mangleText(value) : mask(value);
635
- case "src":
636
- case "srcset":
637
- case "title":
638
- case "alt":
639
- return privacy === 3 /* Privacy.TextImage */ ? "" /* Data.Constant.Empty */ : value;
640
- case "value":
641
- case "click":
642
- case "input":
643
- return mangleToken(value);
644
- case "placeholder":
645
- return mask(value);
646
- }
647
- break;
648
- }
649
- }
650
- return value;
651
- }
652
- function mangleText(value) {
653
- var trimmed = value.trim();
654
- if (trimmed.length > 0) {
655
- var first = trimmed[0];
656
- var index = value.indexOf(first);
657
- var prefix = value.substr(0, index);
658
- var suffix = value.substr(index + trimmed.length);
659
- return "".concat(prefix).concat(trimmed.length.toString(36)).concat(suffix);
660
- }
661
- return value;
662
- }
663
- function mask(value) {
664
- return value.replace(catchallRegex, "\u2022" /* Data.Constant.Mask */);
665
- }
666
- function mangleToken(value) {
667
- var length = ((Math.floor(value.length / 5 /* Data.Setting.WordLength */) + 1) * 5 /* Data.Setting.WordLength */);
668
- var output = "" /* Layout.Constant.Empty */;
669
- for (var i = 0; i < length; i++) {
670
- output += i > 0 && i % 5 /* Data.Setting.WordLength */ === 0 ? " " /* Data.Constant.Space */ : "\u2022" /* Data.Constant.Mask */;
671
- }
672
- return output;
673
- }
674
- function redact(value) {
675
- var spaceIndex = -1;
676
- var gap = 0;
677
- var hasDigit = false;
678
- var hasEmail = false;
679
- var hasWhitespace = false;
680
- var array = null;
681
- // Initialize unicode regex, if supported by the browser
682
- // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
683
- if (unicodeRegex && digitRegex === null) {
684
- try {
685
- digitRegex = new RegExp("\\p{N}", "gu");
686
- letterRegex = new RegExp("\\p{L}", "gu");
687
- currencyRegex = new RegExp("\\p{Sc}", "gu");
688
- }
689
- catch (_a) {
690
- unicodeRegex = false;
691
- }
692
- }
693
- for (var i = 0; i < value.length; i++) {
694
- var c = value.charCodeAt(i);
695
- hasDigit = hasDigit || (c >= 48 /* Data.Character.Zero */ && c <= 57 /* Data.Character.Nine */); // Check for digits in the current word
696
- hasEmail = hasEmail || c === 64 /* Data.Character.At */; // Check for @ sign anywhere within the current word
697
- hasWhitespace = c === 9 /* Data.Character.Tab */ || c === 10 /* Data.Character.NewLine */ || c === 13 /* Data.Character.Return */ || c === 32 /* Data.Character.Blank */;
698
- // Process each word as an individual token to redact any sensitive information
699
- if (i === 0 || i === value.length - 1 || hasWhitespace) {
700
- // Performance optimization: Lazy load string -> array conversion only when required
701
- if (hasDigit || hasEmail) {
702
- if (array === null) {
703
- array = value.split("" /* Data.Constant.Empty */);
704
- }
705
- // Work on a token at a time so we don't have to apply regex to a larger string
706
- var token = value.substring(spaceIndex + 1, hasWhitespace ? i : i + 1);
707
- // Check if unicode regex is supported, otherwise fallback to calling mask function on this token
708
- if (unicodeRegex && currencyRegex !== null) {
709
- // Do not redact information if the token contains a currency symbol
710
- token = token.match(currencyRegex) ? token : token.replace(letterRegex, "\u25AA" /* Data.Constant.Letter */).replace(digitRegex, "\u25AB" /* Data.Constant.Digit */);
711
- }
712
- else {
713
- token = mask(token);
714
- }
715
- // Merge token back into array at the right place
716
- array.splice(spaceIndex + 1 - gap, token.length, token);
717
- gap += token.length - 1;
718
- }
719
- // Reset digit and email flags after every word boundary, except the beginning of string
720
- if (hasWhitespace) {
721
- hasDigit = false;
722
- hasEmail = false;
723
- spaceIndex = i;
724
- }
725
- }
726
- }
727
- return array ? array.join("" /* Data.Constant.Empty */) : value;
728
- }
729
-
730
755
  var history$5 = [];
731
756
  var data$d;
732
- function start$x() {
757
+ function start$y() {
733
758
  history$5 = [];
734
759
  max(26 /* Metric.Automation */, navigator.webdriver ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */);
735
760
  try {
@@ -740,12 +765,12 @@ function start$x() {
740
765
  }
741
766
  }
742
767
  function check$4(id, target, input) {
743
- // Compute hash for fraud detection. Hash is computed only if input meets the minimum length criteria
744
- if (id !== null && input && input.length >= 5 /* Setting.WordLength */) {
745
- data$d = { id: id, target: target, hash: hash(input) };
768
+ // Compute hash for fraud detection, if enabled. Hash is computed only if input meets the minimum length criteria
769
+ if (config$1.fraud && id !== null && input && input.length >= 5 /* Setting.WordLength */) {
770
+ data$d = { id: id, target: target, checksum: hash(input, 24 /* Setting.ChecksumPrecision */) };
746
771
  // Only encode this event if we haven't already reported this hash
747
- if (history$5.indexOf(data$d.hash) < 0) {
748
- history$5.push(data$d.hash);
772
+ if (history$5.indexOf(data$d.checksum) < 0) {
773
+ history$5.push(data$d.checksum);
749
774
  encode$2(41 /* Event.Fraud */);
750
775
  }
751
776
  }
@@ -753,7 +778,7 @@ function check$4(id, target, input) {
753
778
 
754
779
  var excludeClassNames = "load,active,fixed,visible,focus,show,collaps,animat" /* Constant.ExcludeClassNames */.split("," /* Constant.Comma */);
755
780
  var selectorMap = {};
756
- function reset$k() {
781
+ function reset$l() {
757
782
  selectorMap = {};
758
783
  }
759
784
  function get$1(input, type) {
@@ -841,7 +866,7 @@ function filter(value) {
841
866
 
842
867
  var selector = /*#__PURE__*/Object.freeze({
843
868
  __proto__: null,
844
- reset: reset$k,
869
+ reset: reset$l,
845
870
  get: get$1
846
871
  });
847
872
 
@@ -868,7 +893,7 @@ function resume$1() {
868
893
  }
869
894
  }
870
895
  }
871
- function reset$j() {
896
+ function reset$k() {
872
897
  tracker = {};
873
898
  queuedTasks = [];
874
899
  activeTask = null;
@@ -929,7 +954,7 @@ function run() {
929
954
  });
930
955
  }
931
956
  }
932
- function state$8(timer) {
957
+ function state$9(timer) {
933
958
  var id = key(timer);
934
959
  if (id in tracker) {
935
960
  var elapsed = performance.now() - tracker[id].start;
@@ -938,7 +963,7 @@ function state$8(timer) {
938
963
  // If this task is no longer being tracked, send stop message to the caller
939
964
  return 2 /* Task.Stop */;
940
965
  }
941
- function start$w(timer) {
966
+ function start$x(timer) {
942
967
  tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* Setting.LongTask */ };
943
968
  }
944
969
  function restart$2(timer) {
@@ -946,12 +971,12 @@ function restart$2(timer) {
946
971
  if (tracker && tracker[id]) {
947
972
  var c = tracker[id].calls;
948
973
  var y = tracker[id].yield;
949
- start$w(timer);
974
+ start$x(timer);
950
975
  tracker[id].calls = c + 1;
951
976
  tracker[id].yield = y;
952
977
  }
953
978
  }
954
- function stop$t(timer) {
979
+ function stop$u(timer) {
955
980
  var end = performance.now();
956
981
  var id = key(timer);
957
982
  var duration = end - tracker[id].start;
@@ -971,7 +996,7 @@ function suspend$1(timer) {
971
996
  case 0:
972
997
  id = key(timer);
973
998
  if (!(id in tracker)) return [3 /*break*/, 2];
974
- stop$t(timer);
999
+ stop$u(timer);
975
1000
  _a = tracker[id];
976
1001
  return [4 /*yield*/, wait()];
977
1002
  case 1:
@@ -1122,7 +1147,7 @@ function encode$4 (type, timer, ts) {
1122
1147
  return [3 /*break*/, 10];
1123
1148
  case 3:
1124
1149
  // Check if we are operating within the context of the current page
1125
- if (state$8(timer) === 2 /* Task.Stop */) {
1150
+ if (state$9(timer) === 2 /* Task.Stop */) {
1126
1151
  return [3 /*break*/, 10];
1127
1152
  }
1128
1153
  values = updates$2();
@@ -1132,7 +1157,7 @@ function encode$4 (type, timer, ts) {
1132
1157
  case 4:
1133
1158
  if (!(_c < values_1.length)) return [3 /*break*/, 8];
1134
1159
  value = values_1[_c];
1135
- state = state$8(timer);
1160
+ state = state$9(timer);
1136
1161
  if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 6];
1137
1162
  return [4 /*yield*/, suspend$1(timer)];
1138
1163
  case 5:
@@ -1176,7 +1201,7 @@ function encode$4 (type, timer, ts) {
1176
1201
  break;
1177
1202
  case "value":
1178
1203
  check$4(value.metadata.fraud, value.id, data[key]);
1179
- tokens.push(scrub(data[key], data.tag, privacy, mangle));
1204
+ tokens.push(text$1(data[key], data.tag, privacy, mangle));
1180
1205
  break;
1181
1206
  }
1182
1207
  }
@@ -1214,15 +1239,15 @@ function str$1(input) {
1214
1239
  return input.toString(36);
1215
1240
  }
1216
1241
  function attribute(key, value, privacy) {
1217
- return "".concat(key, "=").concat(scrub(value, key, privacy));
1242
+ return "".concat(key, "=").concat(text$1(value, key, privacy));
1218
1243
  }
1219
1244
 
1220
1245
  var data$c;
1221
- function reset$i() {
1246
+ function reset$j() {
1222
1247
  data$c = null;
1223
1248
  }
1224
- function start$v() {
1225
- reset$i();
1249
+ function start$w() {
1250
+ reset$j();
1226
1251
  compute$7();
1227
1252
  }
1228
1253
  function compute$7() {
@@ -1249,6 +1274,29 @@ function compute$7() {
1249
1274
  }
1250
1275
  }
1251
1276
  function end() {
1277
+ reset$j();
1278
+ }
1279
+
1280
+ var state$8 = [];
1281
+ function start$v() {
1282
+ reset$i();
1283
+ }
1284
+ function observe$c(root) {
1285
+ bind(root, "change", recompute$8, true);
1286
+ }
1287
+ function recompute$8(evt) {
1288
+ var element = target(evt);
1289
+ if (element) {
1290
+ var value = element.value;
1291
+ var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$1.fraud ? hash(value, 24 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
1292
+ state$8.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
1293
+ schedule$1(encode$3.bind(this, 42 /* Event.Change */));
1294
+ }
1295
+ }
1296
+ function reset$i() {
1297
+ state$8 = [];
1298
+ }
1299
+ function stop$t() {
1252
1300
  reset$i();
1253
1301
  }
1254
1302
 
@@ -1305,7 +1353,7 @@ function handler$3(event, root, evt) {
1305
1353
  // Check for null values before processing this event
1306
1354
  if (x !== null && y !== null) {
1307
1355
  state$7.push({
1308
- time: time(),
1356
+ time: time(evt),
1309
1357
  event: event,
1310
1358
  data: {
1311
1359
  target: t,
@@ -1396,7 +1444,7 @@ function observe$a(root) {
1396
1444
  bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
1397
1445
  }
1398
1446
  function recompute$7(action, evt) {
1399
- state$6.push({ time: time(), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
1447
+ state$6.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
1400
1448
  schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
1401
1449
  }
1402
1450
  function reset$g() {
@@ -1430,9 +1478,9 @@ function recompute$6(evt) {
1430
1478
  if (state$5.length > 0 && (state$5[state$5.length - 1].data.target === data.target)) {
1431
1479
  state$5.pop();
1432
1480
  }
1433
- state$5.push({ time: time(), event: 27 /* Event.Input */, data: data });
1481
+ state$5.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
1434
1482
  clearTimeout(timeout$5);
1435
- timeout$5 = setTimeout(process$6, 500 /* Setting.LookAhead */, 27 /* Event.Input */);
1483
+ timeout$5 = setTimeout(process$6, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
1436
1484
  }
1437
1485
  }
1438
1486
  function process$6(event) {
@@ -1475,14 +1523,14 @@ function mouse(event, root, evt) {
1475
1523
  }
1476
1524
  // Check for null values before processing this event
1477
1525
  if (x !== null && y !== null) {
1478
- handler$2({ time: time(), event: event, data: { target: target(evt), x: x, y: y } });
1526
+ handler$2({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
1479
1527
  }
1480
1528
  }
1481
1529
  function touch(event, root, evt) {
1482
1530
  var frame = iframe(root);
1483
1531
  var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1484
1532
  var touches = evt.changedTouches;
1485
- var t = time();
1533
+ var t = time(evt);
1486
1534
  if (touches) {
1487
1535
  for (var i = 0; i < touches.length; i++) {
1488
1536
  var entry = touches[i];
@@ -1588,7 +1636,7 @@ function recompute$4(event) {
1588
1636
  // And, if for some reason that is not available, fall back to looking up scrollTop on document.documentElement.
1589
1637
  var x = element === de && "pageXOffset" in w ? Math.round(w.pageXOffset) : Math.round(element.scrollLeft);
1590
1638
  var y = element === de && "pageYOffset" in w ? Math.round(w.pageYOffset) : Math.round(element.scrollTop);
1591
- var current = { time: time(), event: 10 /* Event.Scroll */, data: { target: element, x: x, y: y } };
1639
+ var current = { time: time(event), event: 10 /* Event.Scroll */, data: { target: element, x: x, y: y } };
1592
1640
  // We don't send any scroll events if this is the first event and the current position is top (0,0)
1593
1641
  if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
1594
1642
  return;
@@ -1678,7 +1726,7 @@ function observe$5(root) {
1678
1726
  bind(root, "submit", recompute$2, true);
1679
1727
  }
1680
1728
  function recompute$2(evt) {
1681
- state$2.push({ time: time(), event: 39 /* Event.Submit */, data: { target: target(evt) } });
1729
+ state$2.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
1682
1730
  schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
1683
1731
  }
1684
1732
  function reset$a() {
@@ -1694,7 +1742,7 @@ function start$m() {
1694
1742
  }
1695
1743
  function recompute$1(evt) {
1696
1744
  data$9 = { name: evt.type };
1697
- encode$3(26 /* Event.Unload */);
1745
+ encode$3(26 /* Event.Unload */, time(evt));
1698
1746
  stop();
1699
1747
  }
1700
1748
  function reset$9() {
@@ -1709,9 +1757,10 @@ function start$l() {
1709
1757
  bind(document, "visibilitychange", recompute);
1710
1758
  recompute();
1711
1759
  }
1712
- function recompute() {
1760
+ function recompute(evt) {
1761
+ if (evt === void 0) { evt = null; }
1713
1762
  data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
1714
- encode$3(28 /* Event.Visibility */);
1763
+ encode$3(28 /* Event.Visibility */, time(evt));
1715
1764
  }
1716
1765
  function reset$8() {
1717
1766
  data$8 = null;
@@ -1730,6 +1779,7 @@ function start$k() {
1730
1779
  start$l();
1731
1780
  start$p();
1732
1781
  start$o();
1782
+ start$v();
1733
1783
  start$n();
1734
1784
  start$m();
1735
1785
  }
@@ -1743,6 +1793,7 @@ function stop$i() {
1743
1793
  stop$j();
1744
1794
  stop$n();
1745
1795
  stop$m();
1796
+ stop$t();
1746
1797
  stop$l();
1747
1798
  stop$k();
1748
1799
  }
@@ -1756,6 +1807,7 @@ function observe$4(root) {
1756
1807
  observe$8(root);
1757
1808
  observe$9(root);
1758
1809
  observe$6(root);
1810
+ observe$c(root);
1759
1811
  observe$5(root);
1760
1812
  }
1761
1813
  }
@@ -1836,6 +1888,7 @@ function num$1(input, scale) {
1836
1888
  var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror", "data-drupal-form-submit-last"];
1837
1889
  var newlineRegex = /[\r\n]+/g;
1838
1890
  function processNode (node, source) {
1891
+ var _a;
1839
1892
  var child = null;
1840
1893
  // Do not track this change if we are attempting to remove a node before discovering it
1841
1894
  if (source === 2 /* Source.ChildListRemove */ && has(node) === false) {
@@ -1932,7 +1985,7 @@ function processNode (node, source) {
1932
1985
  try {
1933
1986
  ld(JSON.parse(element.text.replace(newlineRegex, "" /* Constant.Empty */)));
1934
1987
  }
1935
- catch ( /* do nothing */_a) { /* do nothing */ }
1988
+ catch ( /* do nothing */_b) { /* do nothing */ }
1936
1989
  }
1937
1990
  break;
1938
1991
  case "NOSCRIPT":
@@ -1958,11 +2011,20 @@ function processNode (node, source) {
1958
2011
  break;
1959
2012
  case "HEAD":
1960
2013
  var head = { tag: tag, attributes: attributes };
1961
- if (location) {
1962
- head.attributes["*B" /* Constant.Base */] = location.protocol + "//" + location.hostname;
1963
- }
2014
+ var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
2015
+ head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.hostname + l.pathname;
1964
2016
  dom[call](node, parent, head, source);
1965
2017
  break;
2018
+ case "BASE":
2019
+ // Override the auto detected base path to explicit value specified in this tag
2020
+ var baseHead = get(node.parentElement);
2021
+ if (baseHead) {
2022
+ // We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
2023
+ var a = document.createElement("a");
2024
+ a.href = attributes["href"];
2025
+ baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.hostname + a.pathname;
2026
+ }
2027
+ break;
1966
2028
  case "STYLE":
1967
2029
  var styleData = { tag: tag, attributes: attributes, value: getStyleValue(element) };
1968
2030
  dom[call](node, parent, styleData, source);
@@ -2062,7 +2124,7 @@ function traverse (root, timer, source) {
2062
2124
  queue.push(next);
2063
2125
  next = next.nextSibling;
2064
2126
  }
2065
- state = state$8(timer);
2127
+ state = state$9(timer);
2066
2128
  if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
2067
2129
  return [4 /*yield*/, suspend$1(timer)];
2068
2130
  case 2:
@@ -2199,7 +2261,7 @@ function process$2() {
2199
2261
  switch (_b.label) {
2200
2262
  case 0:
2201
2263
  timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
2202
- start$w(timer);
2264
+ start$x(timer);
2203
2265
  _b.label = 1;
2204
2266
  case 1:
2205
2267
  if (!(mutations.length > 0)) return [3 /*break*/, 8];
@@ -2209,7 +2271,7 @@ function process$2() {
2209
2271
  case 2:
2210
2272
  if (!(_i < _a.length)) return [3 /*break*/, 6];
2211
2273
  mutation = _a[_i];
2212
- state = state$8(timer);
2274
+ state = state$9(timer);
2213
2275
  if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2214
2276
  return [4 /*yield*/, suspend$1(timer)];
2215
2277
  case 3:
@@ -2254,7 +2316,7 @@ function process$2() {
2254
2316
  _b.sent();
2255
2317
  return [3 /*break*/, 1];
2256
2318
  case 8:
2257
- stop$t(timer);
2319
+ stop$u(timer);
2258
2320
  return [2 /*return*/];
2259
2321
  }
2260
2322
  });
@@ -2316,7 +2378,7 @@ function processNodeList(list, source, timer) {
2316
2378
  traverse(list[i], timer, source);
2317
2379
  return [3 /*break*/, 5];
2318
2380
  case 2:
2319
- state = state$8(timer);
2381
+ state = state$9(timer);
2320
2382
  if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2321
2383
  return [4 /*yield*/, suspend$1(timer)];
2322
2384
  case 3:
@@ -2389,8 +2451,9 @@ var override = [];
2389
2451
  var unmask = [];
2390
2452
  var updatedFragments = {};
2391
2453
  var maskText = [];
2392
- var maskInput = [];
2454
+ var maskExclude = [];
2393
2455
  var maskDisable = [];
2456
+ var maskTags = [];
2394
2457
  // The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
2395
2458
  var idMap = null; // Maps node => id.
2396
2459
  var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
@@ -2412,13 +2475,14 @@ function reset$7() {
2412
2475
  override = [];
2413
2476
  unmask = [];
2414
2477
  maskText = "address,password,contact" /* Mask.Text */.split("," /* Constant.Comma */);
2415
- maskInput = "password,secret,pass,social,ssn,name,code,dob,cell,mob,contact,hidden,account,cvv,ccv,email,tel,phone,address,addr,card,zip" /* Mask.Input */.split("," /* Constant.Comma */);
2478
+ maskExclude = "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.split("," /* Constant.Comma */);
2416
2479
  maskDisable = "radio,checkbox,range,button,reset,submit" /* Mask.Disable */.split("," /* Constant.Comma */);
2480
+ maskTags = "INPUT,SELECT,TEXTAREA" /* Mask.Tags */.split("," /* Constant.Comma */);
2417
2481
  idMap = new WeakMap();
2418
2482
  iframeMap = new WeakMap();
2419
2483
  privacyMap = new WeakMap();
2420
2484
  fraudMap = new WeakMap();
2421
- reset$k();
2485
+ reset$l();
2422
2486
  }
2423
2487
  // We parse new root nodes for any regions or masked nodes in the beginning (document) and
2424
2488
  // later whenever there are new additions or modifications to DOM (mutations)
@@ -2436,7 +2500,7 @@ function parse$1(root, init) {
2436
2500
  if ("querySelectorAll" in root) {
2437
2501
  config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
2438
2502
  config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
2439
- config$1.fraud.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Check
2503
+ config$1.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
2440
2504
  unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
2441
2505
  }
2442
2506
  }
@@ -2580,6 +2644,16 @@ function privacy(node, value, parent) {
2580
2644
  var attributes = data.attributes || {};
2581
2645
  var tag = data.tag.toUpperCase();
2582
2646
  switch (true) {
2647
+ case maskTags.indexOf(tag) >= 0:
2648
+ var type = attributes["type" /* Constant.Type */];
2649
+ var meta_1 = "" /* Constant.Empty */;
2650
+ Object.keys(attributes).forEach(function (x) { return meta_1 += attributes[x].toLowerCase(); });
2651
+ var exclude = maskExclude.some(function (x) { return meta_1.indexOf(x) >= 0; });
2652
+ // Regardless of privacy mode, always mask off user input from input boxes or drop downs with two exceptions:
2653
+ // (1) The node is detected to be one of the excluded fields, in which case we drop everything
2654
+ // (2) The node's type is one of the allowed types (like checkboxes)
2655
+ metadata.privacy = tag === "INPUT" /* Constant.InputTag */ && maskDisable.indexOf(type) >= 0 ? current : (exclude ? 4 /* Privacy.Exclude */ : 2 /* Privacy.Text */);
2656
+ break;
2583
2657
  case "data-clarity-mask" /* Constant.MaskData */ in attributes:
2584
2658
  metadata.privacy = 3 /* Privacy.TextImage */;
2585
2659
  break;
@@ -2601,20 +2675,6 @@ function privacy(node, value, parent) {
2601
2675
  var tags = ["STYLE" /* Constant.StyleTag */, "TITLE" /* Constant.TitleTag */, "svg:style" /* Constant.SvgStyle */];
2602
2676
  metadata.privacy = tags.includes(pTag) || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* Privacy.None */ : current;
2603
2677
  break;
2604
- case tag === "INPUT" /* Constant.InputTag */ && current === 0 /* Privacy.None */:
2605
- // If even default privacy setting is to not mask, we still scan through input fields for any sensitive information
2606
- var field_1 = "" /* Constant.Empty */;
2607
- Object.keys(attributes).forEach(function (x) { return field_1 += attributes[x].toLowerCase(); });
2608
- metadata.privacy = inspect(field_1, maskInput, metadata);
2609
- break;
2610
- case tag === "INPUT" /* Constant.InputTag */ && current === 1 /* Privacy.Sensitive */:
2611
- // Look through class names to aggressively mask content
2612
- metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
2613
- // If this node has an explicit type assigned to it, go through masking rules to determine right privacy setting
2614
- metadata.privacy = inspect(attributes["type" /* Constant.Type */], maskInput, metadata);
2615
- // If it's a button or an input option, make an exception to disable masking in sensitive mode
2616
- metadata.privacy = maskDisable.indexOf(attributes["type" /* Constant.Type */]) >= 0 ? 0 /* Privacy.None */ : metadata.privacy;
2617
- break;
2618
2678
  case current === 1 /* Privacy.Sensitive */:
2619
2679
  // In a mode where we mask sensitive information by default, look through class names to aggressively mask content
2620
2680
  metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
@@ -2952,11 +3012,12 @@ function metadata$2(node, event, text) {
2952
3012
  return output;
2953
3013
  }
2954
3014
 
2955
- function encode$3 (type) {
3015
+ function encode$3 (type, ts) {
3016
+ if (ts === void 0) { ts = null; }
2956
3017
  return __awaiter(this, void 0, void 0, function () {
2957
- var t, tokens, _i, _a, entry, pTarget, _b, _c, entry, cTarget, cHash, _d, _e, entry, target, r, u, _f, _g, entry, iTarget, s, startTarget, endTarget, _h, _j, entry, sTarget, _k, _l, entry, target, _m, _o, entry, v;
2958
- return __generator(this, function (_p) {
2959
- t = time();
3018
+ var t, tokens, _i, _a, entry, pTarget, _b, _c, entry, cTarget, cHash, _d, _e, entry, target, r, u, _f, _g, entry, iTarget, s, startTarget, endTarget, _h, _j, entry, sTarget, _k, _l, entry, target, _m, _o, entry, target, _p, _q, entry, v;
3019
+ return __generator(this, function (_r) {
3020
+ t = ts || time();
2960
3021
  tokens = [t, type];
2961
3022
  switch (type) {
2962
3023
  case 13 /* Event.MouseDown */:
@@ -2996,8 +3057,8 @@ function encode$3 (type) {
2996
3057
  tokens.push(entry.data.button);
2997
3058
  tokens.push(entry.data.reaction);
2998
3059
  tokens.push(entry.data.context);
2999
- tokens.push(scrub(entry.data.text, "click", cTarget.privacy));
3000
- tokens.push(entry.data.link);
3060
+ tokens.push(text$1(entry.data.text, "click", cTarget.privacy));
3061
+ tokens.push(url$1(entry.data.link));
3001
3062
  tokens.push(cHash);
3002
3063
  tokens.push(entry.data.trust);
3003
3064
  queue(tokens);
@@ -3038,7 +3099,7 @@ function encode$3 (type) {
3038
3099
  iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
3039
3100
  tokens = [entry.time, entry.event];
3040
3101
  tokens.push(iTarget.id);
3041
- tokens.push(scrub(entry.data.value, "input", iTarget.privacy));
3102
+ tokens.push(text$1(entry.data.value, "input", iTarget.privacy));
3042
3103
  queue(tokens);
3043
3104
  }
3044
3105
  reset$f();
@@ -3071,11 +3132,27 @@ function encode$3 (type) {
3071
3132
  }
3072
3133
  reset$c();
3073
3134
  break;
3074
- case 39 /* Event.Submit */:
3075
- for (_k = 0, _l = state$2; _k < _l.length; _k++) {
3135
+ case 42 /* Event.Change */:
3136
+ for (_k = 0, _l = state$8; _k < _l.length; _k++) {
3076
3137
  entry = _l[_k];
3077
3138
  tokens = [entry.time, entry.event];
3078
3139
  target = metadata$2(entry.data.target, entry.event);
3140
+ if (target.id > 0) {
3141
+ tokens = [entry.time, entry.event];
3142
+ tokens.push(target.id);
3143
+ tokens.push(entry.data.type);
3144
+ tokens.push(text$1(entry.data.value, "change", target.privacy));
3145
+ tokens.push(text$1(entry.data.checksum, "checksum", target.privacy));
3146
+ queue(tokens);
3147
+ }
3148
+ }
3149
+ reset$i();
3150
+ break;
3151
+ case 39 /* Event.Submit */:
3152
+ for (_m = 0, _o = state$2; _m < _o.length; _m++) {
3153
+ entry = _o[_m];
3154
+ tokens = [entry.time, entry.event];
3155
+ target = metadata$2(entry.data.target, entry.event);
3079
3156
  if (target.id > 0) {
3080
3157
  tokens.push(target.id);
3081
3158
  queue(tokens);
@@ -3084,8 +3161,8 @@ function encode$3 (type) {
3084
3161
  reset$a();
3085
3162
  break;
3086
3163
  case 22 /* Event.Timeline */:
3087
- for (_m = 0, _o = updates$1; _m < _o.length; _m++) {
3088
- entry = _o[_m];
3164
+ for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
3165
+ entry = _q[_p];
3089
3166
  tokens = [entry.time, entry.event];
3090
3167
  tokens.push(entry.data.type);
3091
3168
  tokens.push(entry.data.hash);
@@ -3213,7 +3290,7 @@ function queue(tokens, transmit) {
3213
3290
  // We enrich the data going out with the existing upload. In these cases, call to upload comes with 'transmit' set to false.
3214
3291
  if (transmit && timeout === null) {
3215
3292
  if (type !== 25 /* Event.Ping */) {
3216
- reset$n();
3293
+ reset$o();
3217
3294
  }
3218
3295
  timeout = setTimeout(upload, gap);
3219
3296
  queuedTime = now;
@@ -3463,7 +3540,7 @@ function encode$2 (type) {
3463
3540
  tokens.push(data$7.line);
3464
3541
  tokens.push(data$7.column);
3465
3542
  tokens.push(data$7.stack);
3466
- tokens.push(data$7.source);
3543
+ tokens.push(url$1(data$7.source));
3467
3544
  queue(tokens);
3468
3545
  break;
3469
3546
  case 33 /* Event.Log */:
@@ -3480,7 +3557,7 @@ function encode$2 (type) {
3480
3557
  if (data$d) {
3481
3558
  tokens.push(data$d.id);
3482
3559
  tokens.push(data$d.target);
3483
- tokens.push(data$d.hash);
3560
+ tokens.push(data$d.checksum);
3484
3561
  queue(tokens, false);
3485
3562
  }
3486
3563
  break;
@@ -3659,7 +3736,7 @@ function encode$1 (event) {
3659
3736
  var tokens = [t, event];
3660
3737
  switch (event) {
3661
3738
  case 4 /* Event.Baseline */:
3662
- var b = state$9;
3739
+ var b = state$a;
3663
3740
  if (b) {
3664
3741
  tokens = [b.time, b.event];
3665
3742
  tokens.push(b.data.visible);
@@ -3674,7 +3751,7 @@ function encode$1 (event) {
3674
3751
  tokens.push(b.data.activityTime);
3675
3752
  queue(tokens, false);
3676
3753
  }
3677
- reset$p();
3754
+ reset$q();
3678
3755
  break;
3679
3756
  case 25 /* Event.Ping */:
3680
3757
  tokens.push(data$h.gap);
@@ -3707,7 +3784,7 @@ function encode$1 (event) {
3707
3784
  tokens.push(v);
3708
3785
  tokens.push(data$e[v]);
3709
3786
  }
3710
- reset$l();
3787
+ reset$m();
3711
3788
  queue(tokens, false);
3712
3789
  }
3713
3790
  break;
@@ -3722,7 +3799,7 @@ function encode$1 (event) {
3722
3799
  // However, for data over the wire, we round it off to milliseconds precision.
3723
3800
  tokens.push(Math.round(updates$3[m]));
3724
3801
  }
3725
- reset$o();
3802
+ reset$p();
3726
3803
  queue(tokens, false);
3727
3804
  }
3728
3805
  break;
@@ -3748,7 +3825,7 @@ function encode$1 (event) {
3748
3825
  tokens.push(key);
3749
3826
  tokens.push([].concat.apply([], data$g[e]));
3750
3827
  }
3751
- reset$m();
3828
+ reset$n();
3752
3829
  queue(tokens, false);
3753
3830
  }
3754
3831
  break;
@@ -3843,30 +3920,31 @@ function start$9() {
3843
3920
  // Populate ids for this page
3844
3921
  var s = session();
3845
3922
  var u = user();
3846
- data$2 = {
3847
- projectId: config$1.projectId || hash(location.host),
3848
- userId: u.id,
3849
- sessionId: s.session,
3850
- pageNum: s.count
3851
- };
3923
+ var projectId = config$1.projectId || hash(location.host);
3924
+ data$2 = { projectId: projectId, userId: u.id, sessionId: s.session, pageNum: s.count };
3852
3925
  // Override configuration based on what's in the session storage, unless it is blank (e.g. using upload callback, like in devtools)
3853
3926
  config$1.lean = config$1.track && s.upgrade !== null ? s.upgrade === 0 /* BooleanFlag.False */ : config$1.lean;
3854
3927
  config$1.upload = config$1.track && typeof config$1.upload === "string" /* Constant.String */ && s.upload && s.upload.length > "https://" /* Constant.HTTPS */.length ? s.upload : config$1.upload;
3855
- // Log dimensions
3928
+ // Log page metadata as dimensions
3856
3929
  log(0 /* Dimension.UserAgent */, ua);
3857
3930
  log(3 /* Dimension.PageTitle */, title);
3858
- log(1 /* Dimension.Url */, location.href);
3931
+ log(1 /* Dimension.Url */, url$1(location.href));
3859
3932
  log(2 /* Dimension.Referrer */, document.referrer);
3860
3933
  log(15 /* Dimension.TabId */, tab());
3861
3934
  log(16 /* Dimension.PageLanguage */, document.documentElement.lang);
3862
3935
  log(17 /* Dimension.DocumentDirection */, document.dir);
3936
+ log(26 /* Dimension.DevicePixelRatio */, "".concat(window.devicePixelRatio));
3937
+ // Capture additional metadata as metrics
3938
+ max(0 /* Metric.ClientTimestamp */, s.ts);
3939
+ max(1 /* Metric.Playback */, 0 /* BooleanFlag.False */);
3940
+ // Capture navigator specific dimensions
3863
3941
  if (navigator) {
3864
- log(9 /* Dimension.Language */, navigator.userLanguage || navigator.language);
3942
+ log(9 /* Dimension.Language */, navigator.language);
3943
+ max(33 /* Metric.HardwareConcurrency */, navigator.hardwareConcurrency);
3944
+ max(32 /* Metric.MaxTouchPoints */, navigator.maxTouchPoints);
3945
+ max(34 /* Metric.DeviceMemory */, Math.round(navigator.deviceMemory));
3865
3946
  userAgentData();
3866
3947
  }
3867
- // Metrics
3868
- max(0 /* Metric.ClientTimestamp */, s.ts);
3869
- max(1 /* Metric.Playback */, 0 /* BooleanFlag.False */);
3870
3948
  if (screen) {
3871
3949
  max(14 /* Metric.ScreenWidth */, Math.round(screen.width));
3872
3950
  max(15 /* Metric.ScreenHeight */, Math.round(screen.height));
@@ -3884,22 +3962,20 @@ function start$9() {
3884
3962
  track(u);
3885
3963
  }
3886
3964
  function userAgentData() {
3887
- if (navigator["userAgentData"] && navigator["userAgentData"].getHighEntropyValues) {
3888
- navigator["userAgentData"].getHighEntropyValues(["model",
3889
- "platform",
3890
- "platformVersion",
3891
- "uaFullVersion"])
3892
- .then(function (ua) {
3965
+ var uaData = navigator["userAgentData"];
3966
+ if (uaData && uaData.getHighEntropyValues) {
3967
+ uaData.getHighEntropyValues(["model", "platform", "platformVersion", "uaFullVersion"]).then(function (ua) {
3893
3968
  var _a;
3894
3969
  log(22 /* Dimension.Platform */, ua.platform);
3895
3970
  log(23 /* Dimension.PlatformVersion */, ua.platformVersion);
3896
- (_a = ua.brands) === null || _a === void 0 ? void 0 : _a.forEach(function (brand) {
3897
- log(24 /* Dimension.Brand */, brand.name + "~" /* Constant.Tilde */ + brand.version);
3898
- });
3971
+ (_a = ua.brands) === null || _a === void 0 ? void 0 : _a.forEach(function (brand) { log(24 /* Dimension.Brand */, brand.name + "~" /* Constant.Tilde */ + brand.version); });
3899
3972
  log(25 /* Dimension.Model */, ua.model);
3900
3973
  max(27 /* Metric.Mobile */, ua.mobile ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */);
3901
3974
  });
3902
3975
  }
3976
+ else {
3977
+ log(22 /* Dimension.Platform */, navigator.platform);
3978
+ }
3903
3979
  }
3904
3980
  function stop$8() {
3905
3981
  rootDomain = null;
@@ -4258,8 +4334,8 @@ function stop$6() {
4258
4334
  var status = false;
4259
4335
  function start$6() {
4260
4336
  status = true;
4261
- start$F();
4262
- reset$j();
4337
+ start$G();
4338
+ reset$k();
4263
4339
  reset$1();
4264
4340
  reset$2();
4265
4341
  start$7();
@@ -4268,8 +4344,8 @@ function stop$5() {
4268
4344
  stop$6();
4269
4345
  reset$2();
4270
4346
  reset$1();
4271
- reset$j();
4272
- stop$B();
4347
+ reset$k();
4348
+ stop$C();
4273
4349
  status = false;
4274
4350
  }
4275
4351
  function active() {
@@ -4323,7 +4399,7 @@ function restart() {
4323
4399
  }
4324
4400
 
4325
4401
  function start$5() {
4326
- start$x();
4402
+ start$y();
4327
4403
  start$e();
4328
4404
  start$d();
4329
4405
  }
@@ -4351,14 +4427,14 @@ function discover() {
4351
4427
  case 0:
4352
4428
  ts = time();
4353
4429
  timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
4354
- start$w(timer);
4430
+ start$x(timer);
4355
4431
  return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */)];
4356
4432
  case 1:
4357
4433
  _a.sent();
4358
4434
  return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
4359
4435
  case 2:
4360
4436
  _a.sent();
4361
- stop$t(timer);
4437
+ stop$u(timer);
4362
4438
  return [2 /*return*/];
4363
4439
  }
4364
4440
  });
@@ -4368,7 +4444,7 @@ function discover() {
4368
4444
  function start$3() {
4369
4445
  // The order below is important
4370
4446
  // and is determined by interdependencies of modules
4371
- start$v();
4447
+ start$w();
4372
4448
  start$h();
4373
4449
  start$i();
4374
4450
  start$j();
@@ -4450,6 +4526,10 @@ function compute(entry) {
4450
4526
  var observer;
4451
4527
  var types = ["navigation" /* Constant.Navigation */, "resource" /* Constant.Resource */, "longtask" /* Constant.LongTask */, "first-input" /* Constant.FID */, "layout-shift" /* Constant.CLS */, "largest-contentful-paint" /* Constant.LCP */];
4452
4528
  function start$2() {
4529
+ // Capture connection properties, if available
4530
+ if (navigator && "connection" in navigator) {
4531
+ log(27 /* Dimension.ConnectionType */, navigator["connection"]["effectiveType"]);
4532
+ }
4453
4533
  // Check the browser support performance observer as a pre-requisite for any performance measurement
4454
4534
  if (window["PerformanceObserver"] && PerformanceObserver.supportedEntryTypes) {
4455
4535
  // Start monitoring performance data after page has finished loading.
@@ -4573,7 +4653,7 @@ function start(config$1) {
4573
4653
  if (check()) {
4574
4654
  config(config$1);
4575
4655
  start$6();
4576
- start$y();
4656
+ start$z();
4577
4657
  modules.forEach(function (x) { return measure(x.start)(); });
4578
4658
  }
4579
4659
  }
@@ -4599,7 +4679,7 @@ function stop() {
4599
4679
  if (active()) {
4600
4680
  // Stop modules in the reverse order of their initialization
4601
4681
  modules.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
4602
- stop$u();
4682
+ stop$v();
4603
4683
  stop$5();
4604
4684
  }
4605
4685
  }