clarity-js 0.7.18 → 0.7.19

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
@@ -142,7 +142,7 @@ function api(method) {
142
142
  }
143
143
 
144
144
  var startTime = 0;
145
- function start$H() {
145
+ function start$I() {
146
146
  startTime = performance.now();
147
147
  }
148
148
  function time(event) {
@@ -150,11 +150,11 @@ function time(event) {
150
150
  var ts = event && event.timeStamp > 0 ? event.timeStamp : performance.now();
151
151
  return Math.max(Math.round(ts - startTime), 0);
152
152
  }
153
- function stop$E() {
153
+ function stop$F() {
154
154
  startTime = 0;
155
155
  }
156
156
 
157
- var version$1 = "0.7.18";
157
+ var version$1 = "0.7.19";
158
158
 
159
159
  // tslint:disable: no-bitwise
160
160
  function hash (input, precision) {
@@ -355,18 +355,18 @@ function redact$1(value) {
355
355
  return array ? array.join("" /* Data.Constant.Empty */) : value;
356
356
  }
357
357
 
358
- var state$b = null;
358
+ var state$c = null;
359
359
  var buffer = null;
360
360
  var update$2 = false;
361
- function start$G() {
361
+ function start$H() {
362
362
  update$2 = false;
363
- reset$r();
363
+ reset$s();
364
364
  }
365
- function reset$r() {
365
+ function reset$s() {
366
366
  // Baseline state holds the previous values - if it is updated in the current payload,
367
367
  // reset the state to current value after sending the previous state
368
368
  if (update$2) {
369
- state$b = { time: time(), event: 4 /* Event.Baseline */, data: {
369
+ state$c = { time: time(), event: 4 /* Event.Baseline */, data: {
370
370
  visible: buffer.visible,
371
371
  docWidth: buffer.docWidth,
372
372
  docHeight: buffer.docHeight,
@@ -424,23 +424,23 @@ function visibility(t, visible) {
424
424
  }
425
425
  update$2 = true;
426
426
  }
427
- function compute$c() {
427
+ function compute$d() {
428
428
  if (update$2) {
429
429
  encode$1(4 /* Event.Baseline */);
430
430
  }
431
431
  }
432
- function stop$D() {
433
- reset$r();
432
+ function stop$E() {
433
+ reset$s();
434
434
  }
435
435
 
436
436
  var baseline = /*#__PURE__*/Object.freeze({
437
437
  __proto__: null,
438
438
  activity: activity,
439
- compute: compute$c,
440
- reset: reset$r,
441
- start: start$G,
442
- get state () { return state$b; },
443
- stop: stop$D,
439
+ compute: compute$d,
440
+ reset: reset$s,
441
+ start: start$H,
442
+ get state () { return state$c; },
443
+ stop: stop$E,
444
444
  track: track$8,
445
445
  visibility: visibility
446
446
  });
@@ -465,12 +465,12 @@ function event(a, b) {
465
465
 
466
466
  var data$i = null;
467
467
  var updates$3 = null;
468
- function start$F() {
468
+ function start$G() {
469
469
  data$i = {};
470
470
  updates$3 = {};
471
471
  count$1(5 /* Metric.InvokeCount */);
472
472
  }
473
- function stop$C() {
473
+ function stop$D() {
474
474
  data$i = {};
475
475
  updates$3 = {};
476
476
  }
@@ -508,10 +508,10 @@ function max(metric, value) {
508
508
  }
509
509
  }
510
510
  }
511
- function compute$b() {
511
+ function compute$c() {
512
512
  encode$1(0 /* Event.Metric */);
513
513
  }
514
- function reset$q() {
514
+ function reset$r() {
515
515
  updates$3 = {};
516
516
  }
517
517
 
@@ -526,11 +526,11 @@ var data$h;
526
526
  var last = 0;
527
527
  var interval = 0;
528
528
  var timeout$6 = null;
529
- function start$E() {
529
+ function start$F() {
530
530
  interval = 60000 /* Setting.PingInterval */;
531
531
  last = 0;
532
532
  }
533
- function reset$p() {
533
+ function reset$q() {
534
534
  if (timeout$6) {
535
535
  clearTimeout(timeout$6);
536
536
  }
@@ -548,7 +548,7 @@ function ping() {
548
548
  suspend();
549
549
  }
550
550
  }
551
- function stop$B() {
551
+ function stop$C() {
552
552
  clearTimeout(timeout$6);
553
553
  last = 0;
554
554
  interval = 0;
@@ -557,16 +557,16 @@ function stop$B() {
557
557
  var ping$1 = /*#__PURE__*/Object.freeze({
558
558
  __proto__: null,
559
559
  get data () { return data$h; },
560
- reset: reset$p,
561
- start: start$E,
562
- stop: stop$B
560
+ reset: reset$q,
561
+ start: start$F,
562
+ stop: stop$C
563
563
  });
564
564
 
565
565
  var data$g = null;
566
- function start$D() {
566
+ function start$E() {
567
567
  data$g = {};
568
568
  }
569
- function stop$A() {
569
+ function stop$B() {
570
570
  data$g = {};
571
571
  }
572
572
  function track$7(event, time) {
@@ -586,25 +586,25 @@ function track$7(event, time) {
586
586
  }
587
587
  }
588
588
  }
589
- function compute$a() {
589
+ function compute$b() {
590
590
  encode$1(36 /* Event.Summary */);
591
591
  }
592
- function reset$o() {
592
+ function reset$p() {
593
593
  data$g = {};
594
594
  }
595
595
 
596
596
  var summary = /*#__PURE__*/Object.freeze({
597
597
  __proto__: null,
598
- compute: compute$a,
598
+ compute: compute$b,
599
599
  get data () { return data$g; },
600
- reset: reset$o,
601
- start: start$D,
602
- stop: stop$A,
600
+ reset: reset$p,
601
+ start: start$E,
602
+ stop: stop$B,
603
603
  track: track$7
604
604
  });
605
605
 
606
606
  var data$f = null;
607
- function start$C() {
607
+ function start$D() {
608
608
  if (!config$1.lean && config$1.upgrade) {
609
609
  config$1.upgrade("Config" /* Constant.Config */);
610
610
  }
@@ -628,15 +628,15 @@ function upgrade(key) {
628
628
  encode$1(3 /* Event.Upgrade */);
629
629
  }
630
630
  }
631
- function stop$z() {
631
+ function stop$A() {
632
632
  data$f = null;
633
633
  }
634
634
 
635
635
  var upgrade$1 = /*#__PURE__*/Object.freeze({
636
636
  __proto__: null,
637
637
  get data () { return data$f; },
638
- start: start$C,
639
- stop: stop$z,
638
+ start: start$D,
639
+ stop: stop$A,
640
640
  upgrade: upgrade
641
641
  });
642
642
 
@@ -694,8 +694,8 @@ function __generator(thisArg, body) {
694
694
  }
695
695
 
696
696
  var data$e = null;
697
- function start$B() {
698
- reset$n();
697
+ function start$C() {
698
+ reset$o();
699
699
  }
700
700
  function set(variable, value) {
701
701
  var values = typeof value === "string" /* Constant.String */ ? [value] : value;
@@ -750,14 +750,14 @@ function log$2(variable, value) {
750
750
  data$e[variable] = validValues;
751
751
  }
752
752
  }
753
- function compute$9() {
753
+ function compute$a() {
754
754
  encode$1(34 /* Event.Variable */);
755
755
  }
756
- function reset$n() {
756
+ function reset$o() {
757
757
  data$e = {};
758
758
  }
759
- function stop$y() {
760
- reset$n();
759
+ function stop$z() {
760
+ reset$o();
761
761
  }
762
762
  function redact(input) {
763
763
  return input && input.length >= 5 /* Setting.WordLength */ ?
@@ -791,13 +791,13 @@ function detect(input) {
791
791
 
792
792
  var variable = /*#__PURE__*/Object.freeze({
793
793
  __proto__: null,
794
- compute: compute$9,
794
+ compute: compute$a,
795
795
  get data () { return data$e; },
796
796
  identify: identify,
797
- reset: reset$n,
797
+ reset: reset$o,
798
798
  set: set,
799
- start: start$B,
800
- stop: stop$y
799
+ start: start$C,
800
+ stop: stop$z
801
801
  });
802
802
 
803
803
  var supported$1 = "CompressionStream" /* Constant.CompressionStream */ in window;
@@ -859,32 +859,32 @@ function read(stream) {
859
859
  }
860
860
 
861
861
  var modules$1 = [baseline, dimension, variable, limit, summary, metadata$1, envelope$1, upload$1, ping$1, upgrade$1, extract];
862
- function start$A() {
862
+ function start$B() {
863
863
  // Metric needs to be initialized before we can start measuring. so metric is not wrapped in measure
864
- start$F();
864
+ start$G();
865
865
  modules$1.forEach(function (x) { return measure(x.start)(); });
866
866
  }
867
- function stop$x() {
867
+ function stop$y() {
868
868
  // Stop modules in the reverse order of their initialization
869
869
  // The ordering below should respect inter-module dependency.
870
870
  // E.g. if upgrade depends on upload, then upgrade needs to end before upload.
871
871
  // Similarly, if upload depends on metadata, upload needs to end before metadata.
872
872
  modules$1.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
873
- stop$C();
873
+ stop$D();
874
874
  }
875
- function compute$8() {
876
- compute$9();
877
- compute$c();
875
+ function compute$9() {
876
+ compute$a();
877
+ compute$d();
878
878
  compute$2();
879
+ compute$c();
879
880
  compute$b();
880
- compute$a();
881
881
  compute$3();
882
882
  compute$4();
883
883
  }
884
884
 
885
885
  var history$5 = [];
886
886
  var data$d;
887
- function start$z() {
887
+ function start$A() {
888
888
  history$5 = [];
889
889
  max(26 /* Metric.Automation */, navigator.webdriver ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */);
890
890
  try {
@@ -908,7 +908,7 @@ function check$4(id, target, input) {
908
908
 
909
909
  var excludeClassNames = "load,active,fixed,visible,focus,show,collaps,animat" /* Constant.ExcludeClassNames */.split("," /* Constant.Comma */);
910
910
  var selectorMap = {};
911
- function reset$m() {
911
+ function reset$n() {
912
912
  selectorMap = {};
913
913
  }
914
914
  function get$1(input, type) {
@@ -997,7 +997,7 @@ function filter(value) {
997
997
  var selector = /*#__PURE__*/Object.freeze({
998
998
  __proto__: null,
999
999
  get: get$1,
1000
- reset: reset$m
1000
+ reset: reset$n
1001
1001
  });
1002
1002
 
1003
1003
  var index = 1;
@@ -1016,14 +1016,14 @@ var idMap = null; // Maps node => id.
1016
1016
  var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
1017
1017
  var privacyMap = null; // Maps node => Privacy (enum)
1018
1018
  var fraudMap = null; // Maps node => FraudId (number)
1019
- function start$y() {
1020
- reset$l();
1019
+ function start$z() {
1020
+ reset$m();
1021
1021
  parse$1(document, true);
1022
1022
  }
1023
- function stop$w() {
1024
- reset$l();
1023
+ function stop$x() {
1024
+ reset$m();
1025
1025
  }
1026
- function reset$l() {
1026
+ function reset$m() {
1027
1027
  index = 1;
1028
1028
  values = [];
1029
1029
  updateMap = [];
@@ -1039,7 +1039,7 @@ function reset$l() {
1039
1039
  iframeMap = new WeakMap();
1040
1040
  privacyMap = new WeakMap();
1041
1041
  fraudMap = new WeakMap();
1042
- reset$m();
1042
+ reset$n();
1043
1043
  }
1044
1044
  // We parse new root nodes for any regions or masked nodes in the beginning (document) and
1045
1045
  // later whenever there are new additions or modifications to DOM (mutations)
@@ -1055,7 +1055,7 @@ function parse$1(root, init) {
1055
1055
  // Since mutations may happen on leaf nodes too, e.g. text nodes, which may not support all selector APIs.
1056
1056
  // We ensure that the root note supports querySelectorAll API before executing the code below to identify new regions.
1057
1057
  if ("querySelectorAll" in root) {
1058
- config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$c(e, "".concat(x[0])); }); }); // Regions
1058
+ config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
1059
1059
  config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
1060
1060
  config$1.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
1061
1061
  unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
@@ -1094,7 +1094,7 @@ function add(node, parent, data, source) {
1094
1094
  }
1095
1095
  // If there's an explicit region attribute set on the element, use it to mark a region on the page
1096
1096
  if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
1097
- observe$c(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
1097
+ observe$1(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
1098
1098
  regionId = id;
1099
1099
  }
1100
1100
  nodesMap.set(id, node);
@@ -1375,8 +1375,8 @@ var dom = /*#__PURE__*/Object.freeze({
1375
1375
  lookup: lookup,
1376
1376
  parse: parse$1,
1377
1377
  sameorigin: sameorigin,
1378
- start: start$y,
1379
- stop: stop$w,
1378
+ start: start$z,
1379
+ stop: stop$x,
1380
1380
  update: update$1,
1381
1381
  updates: updates$2
1382
1382
  });
@@ -1404,7 +1404,7 @@ function resume$1() {
1404
1404
  }
1405
1405
  }
1406
1406
  }
1407
- function reset$k() {
1407
+ function reset$l() {
1408
1408
  tracker = {};
1409
1409
  queuedTasks = [];
1410
1410
  activeTask = null;
@@ -1465,7 +1465,7 @@ function run() {
1465
1465
  });
1466
1466
  }
1467
1467
  }
1468
- function state$a(timer) {
1468
+ function state$b(timer) {
1469
1469
  var id = key(timer);
1470
1470
  if (id in tracker) {
1471
1471
  var elapsed = performance.now() - tracker[id].start;
@@ -1474,7 +1474,7 @@ function state$a(timer) {
1474
1474
  // If this task is no longer being tracked, send stop message to the caller
1475
1475
  return 2 /* Task.Stop */;
1476
1476
  }
1477
- function start$x(timer) {
1477
+ function start$y(timer) {
1478
1478
  tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* Setting.LongTask */ };
1479
1479
  }
1480
1480
  function restart$2(timer) {
@@ -1482,12 +1482,12 @@ function restart$2(timer) {
1482
1482
  if (tracker && tracker[id]) {
1483
1483
  var c = tracker[id].calls;
1484
1484
  var y = tracker[id].yield;
1485
- start$x(timer);
1485
+ start$y(timer);
1486
1486
  tracker[id].calls = c + 1;
1487
1487
  tracker[id].yield = y;
1488
1488
  }
1489
1489
  }
1490
- function stop$v(timer) {
1490
+ function stop$w(timer) {
1491
1491
  var end = performance.now();
1492
1492
  var id = key(timer);
1493
1493
  var duration = end - tracker[id].start;
@@ -1507,7 +1507,7 @@ function suspend$1(timer) {
1507
1507
  case 0:
1508
1508
  id = key(timer);
1509
1509
  if (!(id in tracker)) return [3 /*break*/, 2];
1510
- stop$v(timer);
1510
+ stop$w(timer);
1511
1511
  _a = tracker[id];
1512
1512
  return [4 /*yield*/, wait()];
1513
1513
  case 1:
@@ -1620,14 +1620,14 @@ function tokenize (tokens) {
1620
1620
  }
1621
1621
 
1622
1622
  var data$c;
1623
- function reset$j() {
1623
+ function reset$k() {
1624
1624
  data$c = null;
1625
1625
  }
1626
- function start$w() {
1627
- reset$j();
1628
- compute$7();
1626
+ function start$x() {
1627
+ reset$k();
1628
+ compute$8();
1629
1629
  }
1630
- function compute$7() {
1630
+ function compute$8() {
1631
1631
  var body = document.body;
1632
1632
  var d = document.documentElement;
1633
1633
  var bodyClientWidth = body ? body.clientWidth : null;
@@ -1650,437 +1650,256 @@ function compute$7() {
1650
1650
  encode$4(8 /* Event.Document */);
1651
1651
  }
1652
1652
  }
1653
+ function stop$v() {
1654
+ reset$k();
1655
+ }
1656
+
1657
+ var state$a = [];
1658
+ function start$w() {
1659
+ reset$j();
1660
+ }
1661
+ function observe$c(root) {
1662
+ bind(root, "change", recompute$8, true);
1663
+ }
1664
+ function recompute$8(evt) {
1665
+ var element = target(evt);
1666
+ if (element) {
1667
+ var value = element.value;
1668
+ var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$1.fraud && "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.indexOf(element.type) === -1 ? hash(value, 24 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
1669
+ state$a.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
1670
+ schedule$1(encode$3.bind(this, 42 /* Event.Change */));
1671
+ }
1672
+ }
1673
+ function reset$j() {
1674
+ state$a = [];
1675
+ }
1653
1676
  function stop$u() {
1654
1677
  reset$j();
1655
1678
  }
1656
1679
 
1680
+ function offset(element) {
1681
+ var output = { x: 0, y: 0 };
1682
+ // Walk up the chain to ensure we compute offset distance correctly
1683
+ // In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
1684
+ if (element && element.offsetParent) {
1685
+ do {
1686
+ var parent_1 = element.offsetParent;
1687
+ var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
1688
+ output.x += element.offsetLeft;
1689
+ output.y += element.offsetTop;
1690
+ element = frame ? frame : parent_1;
1691
+ } while (element);
1692
+ }
1693
+ return output;
1694
+ }
1695
+
1696
+ var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
1657
1697
  var state$9 = [];
1658
- var animationPlay = null;
1659
- var animationPause = null;
1660
- var animationCancel = null;
1661
- var animationFinish = null;
1662
- var animationId = 'clarityAnimationId';
1663
- var operationCount = 'clarityOperationCount';
1664
- var maxOperations = 20;
1665
1698
  function start$v() {
1666
- if (window["Animation"] &&
1667
- window["KeyframeEffect"] &&
1668
- window["KeyframeEffect"].prototype.getKeyframes &&
1669
- window["KeyframeEffect"].prototype.getTiming) {
1670
- reset$i();
1671
- overrideAnimationHelper(animationPlay, "play");
1672
- overrideAnimationHelper(animationPause, "pause");
1673
- overrideAnimationHelper(animationCancel, "cancel");
1674
- overrideAnimationHelper(animationFinish, "finish");
1699
+ reset$i();
1700
+ }
1701
+ function observe$b(root) {
1702
+ bind(root, "click", handler$3.bind(this, 9 /* Event.Click */, root), true);
1703
+ }
1704
+ function handler$3(event, root, evt) {
1705
+ var frame = iframe(root);
1706
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1707
+ var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
1708
+ var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
1709
+ // In case of iframe, we adjust (x,y) to be relative to top parent's origin
1710
+ if (frame) {
1711
+ var distance = offset(frame);
1712
+ x = x ? x + Math.round(distance.x) : x;
1713
+ y = y ? y + Math.round(distance.y) : y;
1714
+ }
1715
+ var t = target(evt);
1716
+ // Find nearest anchor tag (<a/>) parent if current target node is part of one
1717
+ // If present, we use the returned link element to populate text and link properties below
1718
+ var a = link(t);
1719
+ // Get layout rectangle for the target element
1720
+ var l = layout$1(t);
1721
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
1722
+ // This property helps differentiate between a keyboard navigation vs. pointer click
1723
+ // In case of a keyboard navigation, we use center of target element as (x,y)
1724
+ if (evt.detail === 0 && l) {
1725
+ x = Math.round(l.x + (l.w / 2));
1726
+ y = Math.round(l.y + (l.h / 2));
1727
+ }
1728
+ var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
1729
+ var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
1730
+ // Check for null values before processing this event
1731
+ if (x !== null && y !== null) {
1732
+ state$9.push({
1733
+ time: time(evt),
1734
+ event: event,
1735
+ data: {
1736
+ target: t,
1737
+ x: x,
1738
+ y: y,
1739
+ eX: eX,
1740
+ eY: eY,
1741
+ button: evt.button,
1742
+ reaction: reaction(t),
1743
+ context: context(a),
1744
+ text: text(t),
1745
+ link: a ? a.href : null,
1746
+ hash: null,
1747
+ trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
1748
+ }
1749
+ });
1750
+ schedule$1(encode$3.bind(this, event));
1675
1751
  }
1676
1752
  }
1677
- function reset$i() {
1678
- state$9 = [];
1753
+ function link(node) {
1754
+ while (node && node !== document) {
1755
+ if (node.nodeType === Node.ELEMENT_NODE) {
1756
+ var element = node;
1757
+ if (element.tagName === "A") {
1758
+ return element;
1759
+ }
1760
+ }
1761
+ node = node.parentNode;
1762
+ }
1763
+ return null;
1679
1764
  }
1680
- function track$5(time, id, operation, keyFrames, timing, targetId, timeline) {
1681
- state$9.push({
1682
- time: time,
1683
- event: 44 /* Event.Animation */,
1684
- data: {
1685
- id: id,
1686
- operation: operation,
1687
- keyFrames: keyFrames,
1688
- timing: timing,
1689
- targetId: targetId,
1690
- timeline: timeline
1765
+ function text(element) {
1766
+ var output = null;
1767
+ if (element) {
1768
+ // Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
1769
+ var t = element.textContent || element.value || element.alt;
1770
+ if (t) {
1771
+ // Replace multiple occurrence of space characters with a single white space
1772
+ // Also, trim any spaces at the beginning or at the end of string
1773
+ // Finally, send only first few characters as specified by the Setting
1774
+ output = t.replace(/\s+/g, " " /* Constant.Space */).trim().substr(0, 25 /* Setting.ClickText */);
1691
1775
  }
1692
- });
1693
- encode$4(44 /* Event.Animation */);
1776
+ }
1777
+ return output;
1694
1778
  }
1695
- function stop$t() {
1696
- reset$i();
1779
+ function reaction(element) {
1780
+ if (element.nodeType === Node.ELEMENT_NODE) {
1781
+ var tag = element.tagName.toLowerCase();
1782
+ if (UserInputTags.indexOf(tag) >= 0) {
1783
+ return 0 /* BooleanFlag.False */;
1784
+ }
1785
+ }
1786
+ return 1 /* BooleanFlag.True */;
1697
1787
  }
1698
- function overrideAnimationHelper(functionToOverride, name) {
1699
- if (functionToOverride === null) {
1700
- functionToOverride = Animation.prototype[name];
1701
- Animation.prototype[name] = function () {
1702
- if (active()) {
1703
- var effect = this.effect;
1704
- var target = getId(this.effect.target);
1705
- if (target !== null && effect.getKeyframes && effect.getTiming) {
1706
- if (!this[animationId]) {
1707
- this[animationId] = shortid();
1708
- this[operationCount] = 0;
1709
- var keyframes = effect.getKeyframes();
1710
- var timing = effect.getTiming();
1711
- track$5(time(), this[animationId], 0 /* AnimationOperation.Create */, JSON.stringify(keyframes), JSON.stringify(timing), target);
1712
- }
1713
- if (this[operationCount]++ < maxOperations) {
1714
- var operation = null;
1715
- switch (name) {
1716
- case "play":
1717
- operation = 1 /* AnimationOperation.Play */;
1718
- break;
1719
- case "pause":
1720
- operation = 2 /* AnimationOperation.Pause */;
1721
- break;
1722
- case "cancel":
1723
- operation = 3 /* AnimationOperation.Cancel */;
1724
- break;
1725
- case "finish":
1726
- operation = 4 /* AnimationOperation.Finish */;
1727
- break;
1728
- }
1729
- if (operation) {
1730
- track$5(time(), this[animationId], operation);
1731
- }
1732
- }
1733
- }
1734
- }
1735
- return functionToOverride.apply(this, arguments);
1736
- };
1788
+ function layout$1(element) {
1789
+ var box = null;
1790
+ var de = document.documentElement;
1791
+ if (typeof element.getBoundingClientRect === "function") {
1792
+ // getBoundingClientRect returns rectangle relative positioning to viewport
1793
+ var rect = element.getBoundingClientRect();
1794
+ if (rect && rect.width > 0 && rect.height > 0) {
1795
+ // Add viewport's scroll position to rectangle to get position relative to document origin
1796
+ // Also: using Math.floor() instead of Math.round() because in Edge,
1797
+ // getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
1798
+ // floors the value (e.g. 162px). This keeps consistent behavior across browsers.
1799
+ box = {
1800
+ x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
1801
+ y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
1802
+ w: Math.floor(rect.width),
1803
+ h: Math.floor(rect.height)
1804
+ };
1805
+ }
1737
1806
  }
1738
- }
1739
-
1740
- function encode$4 (type, timer, ts) {
1741
- if (timer === void 0) { timer = null; }
1742
- if (ts === void 0) { ts = null; }
1743
- return __awaiter(this, void 0, void 0, function () {
1744
- var eventTime, tokens, _a, d, _i, _b, r, _c, _d, entry, values, _e, values_1, value, state, data, active, suspend, privacy, mangle, keys, _f, keys_1, key, box, factor, attr;
1745
- return __generator(this, function (_g) {
1746
- switch (_g.label) {
1747
- case 0:
1748
- eventTime = ts || time();
1749
- tokens = [eventTime, type];
1750
- _a = type;
1751
- switch (_a) {
1752
- case 8 /* Event.Document */: return [3 /*break*/, 1];
1753
- case 7 /* Event.Region */: return [3 /*break*/, 2];
1754
- case 44 /* Event.Animation */: return [3 /*break*/, 3];
1755
- case 5 /* Event.Discover */: return [3 /*break*/, 4];
1756
- case 6 /* Event.Mutation */: return [3 /*break*/, 4];
1757
- }
1758
- return [3 /*break*/, 11];
1759
- case 1:
1760
- d = data$c;
1761
- tokens.push(d.width);
1762
- tokens.push(d.height);
1763
- track$8(type, d.width, d.height);
1764
- queue(tokens);
1765
- return [3 /*break*/, 11];
1766
- case 2:
1767
- for (_i = 0, _b = state$8; _i < _b.length; _i++) {
1768
- r = _b[_i];
1769
- tokens = [r.time, 7 /* Event.Region */];
1770
- tokens.push(r.data.id);
1771
- tokens.push(r.data.interaction);
1772
- tokens.push(r.data.visibility);
1773
- tokens.push(r.data.name);
1774
- queue(tokens);
1775
- }
1776
- reset$h();
1777
- return [3 /*break*/, 11];
1778
- case 3:
1779
- for (_c = 0, _d = state$9; _c < _d.length; _c++) {
1780
- entry = _d[_c];
1781
- tokens = [entry.time, entry.event];
1782
- tokens.push(entry.data.id);
1783
- tokens.push(entry.data.operation);
1784
- tokens.push(entry.data.keyFrames);
1785
- tokens.push(entry.data.timing);
1786
- tokens.push(entry.data.timeline);
1787
- tokens.push(entry.data.targetId);
1788
- queue(tokens);
1789
- }
1790
- reset$i();
1791
- return [3 /*break*/, 11];
1792
- case 4:
1793
- // Check if we are operating within the context of the current page
1794
- if (state$a(timer) === 2 /* Task.Stop */) {
1795
- return [3 /*break*/, 11];
1796
- }
1797
- values = updates$2();
1798
- if (!(values.length > 0)) return [3 /*break*/, 10];
1799
- _e = 0, values_1 = values;
1800
- _g.label = 5;
1801
- case 5:
1802
- if (!(_e < values_1.length)) return [3 /*break*/, 9];
1803
- value = values_1[_e];
1804
- state = state$a(timer);
1805
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 7];
1806
- return [4 /*yield*/, suspend$1(timer)];
1807
- case 6:
1808
- state = _g.sent();
1809
- _g.label = 7;
1810
- case 7:
1811
- if (state === 2 /* Task.Stop */) {
1812
- return [3 /*break*/, 9];
1813
- }
1814
- data = value.data;
1815
- active = value.metadata.active;
1816
- suspend = value.metadata.suspend;
1817
- privacy = value.metadata.privacy;
1818
- mangle = shouldMangle(value);
1819
- keys = active ? ["tag", "attributes", "value"] : ["tag"];
1820
- for (_f = 0, keys_1 = keys; _f < keys_1.length; _f++) {
1821
- key = keys_1[_f];
1822
- if (data[key]) {
1823
- switch (key) {
1824
- case "tag":
1825
- box = size(value);
1826
- factor = mangle ? -1 : 1;
1827
- tokens.push(value.id * factor);
1828
- if (value.parent && active) {
1829
- tokens.push(value.parent);
1830
- }
1831
- if (value.previous && active) {
1832
- tokens.push(value.previous);
1833
- }
1834
- tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
1835
- if (box && box.length === 2) {
1836
- tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
1837
- }
1838
- break;
1839
- case "attributes":
1840
- for (attr in data[key]) {
1841
- if (data[key][attr] !== undefined) {
1842
- tokens.push(attribute(attr, data[key][attr], privacy));
1843
- }
1844
- }
1845
- break;
1846
- case "value":
1847
- check$4(value.metadata.fraud, value.id, data[key]);
1848
- tokens.push(text$1(data[key], data.tag, privacy, mangle));
1849
- break;
1850
- }
1851
- }
1852
- }
1853
- _g.label = 8;
1854
- case 8:
1855
- _e++;
1856
- return [3 /*break*/, 5];
1857
- case 9:
1858
- if (type === 6 /* Event.Mutation */) {
1859
- activity(eventTime);
1860
- }
1861
- queue(tokenize(tokens), !config$1.lean);
1862
- _g.label = 10;
1863
- case 10: return [3 /*break*/, 11];
1864
- case 11: return [2 /*return*/];
1865
- }
1866
- });
1867
- });
1868
- }
1869
- function shouldMangle(value) {
1870
- var privacy = value.metadata.privacy;
1871
- return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
1807
+ return box;
1872
1808
  }
1873
- function size(value) {
1874
- if (value.metadata.size !== null && value.metadata.size.length === 0) {
1875
- var img = getNode(value.id);
1876
- if (img) {
1877
- return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
1809
+ function context(a) {
1810
+ if (a && a.hasAttribute("target" /* Constant.Target */)) {
1811
+ switch (a.getAttribute("target" /* Constant.Target */)) {
1812
+ case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
1813
+ case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
1814
+ case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
1878
1815
  }
1879
1816
  }
1880
- return value.metadata.size;
1817
+ return 0 /* BrowsingContext.Self */;
1881
1818
  }
1882
- function str$1(input) {
1883
- return input.toString(36);
1819
+ function reset$i() {
1820
+ state$9 = [];
1884
1821
  }
1885
- function attribute(key, value, privacy) {
1886
- return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
1822
+ function stop$t() {
1823
+ reset$i();
1887
1824
  }
1888
1825
 
1889
1826
  var state$8 = [];
1890
- var regionMap = null; // Maps region nodes => region name
1891
- var regions = {};
1892
- var queue$2 = [];
1893
- var watch = false;
1894
- var observer$1 = null;
1895
1827
  function start$u() {
1896
1828
  reset$h();
1897
- observer$1 = null;
1898
- regionMap = new WeakMap();
1899
- regions = {};
1900
- queue$2 = [];
1901
- watch = window["IntersectionObserver"] ? true : false;
1902
1829
  }
1903
- function observe$c(node, name) {
1904
- if (regionMap.has(node) === false) {
1905
- regionMap.set(node, name);
1906
- observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$3, {
1907
- // Get notified as intersection continues to change
1908
- // This allows us to process regions that get partially hidden during the lifetime of the page
1909
- // See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
1910
- // By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
1911
- threshold: [0, 0.2, 0.4, 0.6, 0.8, 1]
1912
- }) : observer$1;
1913
- if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
1914
- observer$1.observe(node);
1915
- }
1916
- }
1830
+ function observe$a(root) {
1831
+ bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
1832
+ bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
1833
+ bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
1917
1834
  }
1918
- function exists(node) {
1919
- // Check if regionMap is not null before looking up a node
1920
- // Since, dom module stops after region module, it's possible that we may set regionMap to be null
1921
- // and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
1922
- return regionMap && regionMap.has(node);
1835
+ function recompute$7(action, evt) {
1836
+ state$8.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
1837
+ schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
1923
1838
  }
1924
- function track$4(id, event) {
1925
- var node = getNode(id);
1926
- var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
1927
- // Determine the interaction state based on incoming event
1928
- var interaction = 16 /* InteractionState.None */;
1929
- switch (event) {
1930
- case 9 /* Event.Click */:
1931
- interaction = 20 /* InteractionState.Clicked */;
1932
- break;
1933
- case 27 /* Event.Input */:
1934
- interaction = 30 /* InteractionState.Input */;
1935
- break;
1936
- }
1937
- // Process updates to this region, if applicable
1938
- process$6(node, data, interaction, data.visibility);
1839
+ function reset$h() {
1840
+ state$8 = [];
1939
1841
  }
1940
- function compute$6() {
1941
- // Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
1942
- // This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
1943
- // For those cases we add them to the queue and re-process them below
1944
- var q = [];
1945
- for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
1946
- var r = queue_1[_i];
1947
- var id = getId(r.node);
1948
- if (!(id in regions)) {
1949
- if (id) {
1950
- r.data.id = id;
1951
- regions[id] = r.data;
1952
- state$8.push(clone$1(r.data));
1953
- }
1954
- else {
1955
- q.push(r);
1956
- }
1842
+ function stop$s() {
1843
+ reset$h();
1844
+ }
1845
+
1846
+ var timeout$5 = null;
1847
+ var state$7 = [];
1848
+ function start$t() {
1849
+ reset$g();
1850
+ }
1851
+ function observe$9(root) {
1852
+ bind(root, "input", recompute$6, true);
1853
+ }
1854
+ function recompute$6(evt) {
1855
+ var input = target(evt);
1856
+ var value = get(input);
1857
+ if (input && input.type && value) {
1858
+ var v = input.value;
1859
+ switch (input.type) {
1860
+ case "radio":
1861
+ case "checkbox":
1862
+ v = input.checked ? "true" : "false";
1863
+ break;
1957
1864
  }
1958
- }
1959
- queue$2 = q;
1960
- // Schedule encode only when we have at least one valid data entry
1961
- if (state$8.length > 0) {
1962
- encode$4(7 /* Event.Region */);
1865
+ var data = { target: input, value: v };
1866
+ // If last entry in the queue is for the same target node as the current one, remove it so we can later swap it with current data.
1867
+ if (state$7.length > 0 && (state$7[state$7.length - 1].data.target === data.target)) {
1868
+ state$7.pop();
1869
+ }
1870
+ state$7.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
1871
+ clearTimeout(timeout$5);
1872
+ timeout$5 = setTimeout(process$6, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
1963
1873
  }
1964
1874
  }
1965
- function handler$3(entries) {
1966
- for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
1967
- var entry = entries_1[_i];
1968
- var target = entry.target;
1969
- var rect = entry.boundingClientRect;
1970
- var overlap = entry.intersectionRect;
1971
- var viewport = entry.rootBounds;
1972
- // Only capture regions that have non-zero width or height to avoid tracking and sending regions
1973
- // that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
1974
- // like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
1975
- // Also, if these regions ever become non-zero width or height (through AJAX, user action or orientation change) - we will automatically start monitoring them from that point onwards
1976
- if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
1977
- var id = target ? getId(target) : null;
1978
- var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
1979
- // For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
1980
- // However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
1981
- var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
1982
- var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
1983
- // If an element is either visible or was visible and has been scrolled to the end
1984
- // i.e. Scrolled to end is determined by if the starting position of the element + the window height is more than the total element height.
1985
- // starting position is relative to the viewport - so Intersection observer returns a negative value for rect.top to indicate that the element top is above the viewport
1986
- var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
1987
- // Process updates to this region, if applicable
1988
- process$6(target, data, data.interaction, (scrolledToEnd ?
1989
- 13 /* RegionVisibility.ScrolledToEnd */ :
1990
- (visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
1991
- // Stop observing this element now that we have already received scrolled signal
1992
- if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
1993
- observer$1.unobserve(target);
1994
- }
1995
- }
1996
- }
1997
- if (state$8.length > 0) {
1998
- encode$4(7 /* Event.Region */);
1999
- }
2000
- }
2001
- function process$6(n, d, s, v) {
2002
- // Check if received a state that supersedes existing state
2003
- var updated = s > d.interaction || v > d.visibility;
2004
- d.interaction = s > d.interaction ? s : d.interaction;
2005
- d.visibility = v > d.visibility ? v : d.visibility;
2006
- // If the corresponding node is already discovered, update the internal state
2007
- // Otherwise, track it in a queue to reprocess later.
2008
- if (d.id) {
2009
- if ((d.id in regions && updated) || !(d.id in regions)) {
2010
- regions[d.id] = d;
2011
- state$8.push(clone$1(d));
2012
- }
2013
- }
2014
- else {
2015
- queue$2.push({ node: n, data: d });
2016
- }
2017
- }
2018
- function clone$1(r) {
2019
- return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
2020
- }
2021
- function reset$h() {
2022
- state$8 = [];
2023
- }
2024
- function stop$s() {
2025
- reset$h();
2026
- regionMap = null;
2027
- regions = {};
2028
- queue$2 = [];
2029
- if (observer$1) {
2030
- observer$1.disconnect();
2031
- observer$1 = null;
2032
- }
2033
- watch = false;
2034
- }
2035
-
2036
- var state$7 = [];
2037
- function start$t() {
2038
- reset$g();
2039
- }
2040
- function observe$b(root) {
2041
- bind(root, "change", recompute$8, true);
2042
- }
2043
- function recompute$8(evt) {
2044
- var element = target(evt);
2045
- if (element) {
2046
- var value = element.value;
2047
- var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$1.fraud && "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.indexOf(element.type) === -1 ? hash(value, 24 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
2048
- state$7.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
2049
- schedule$1(encode$3.bind(this, 42 /* Event.Change */));
2050
- }
1875
+ function process$6(event) {
1876
+ schedule$1(encode$3.bind(this, event));
2051
1877
  }
2052
1878
  function reset$g() {
2053
1879
  state$7 = [];
2054
1880
  }
2055
1881
  function stop$r() {
1882
+ clearTimeout(timeout$5);
2056
1883
  reset$g();
2057
1884
  }
2058
1885
 
2059
- function offset(element) {
2060
- var output = { x: 0, y: 0 };
2061
- // Walk up the chain to ensure we compute offset distance correctly
2062
- // In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
2063
- if (element && element.offsetParent) {
2064
- do {
2065
- var parent_1 = element.offsetParent;
2066
- var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
2067
- output.x += element.offsetLeft;
2068
- output.y += element.offsetTop;
2069
- element = frame ? frame : parent_1;
2070
- } while (element);
2071
- }
2072
- return output;
2073
- }
2074
-
2075
- var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
2076
1886
  var state$6 = [];
1887
+ var timeout$4 = null;
2077
1888
  function start$s() {
2078
1889
  reset$f();
2079
1890
  }
2080
- function observe$a(root) {
2081
- bind(root, "click", handler$2.bind(this, 9 /* Event.Click */, root), true);
1891
+ function observe$8(root) {
1892
+ bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
1893
+ bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
1894
+ bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
1895
+ bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
1896
+ bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
1897
+ bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
1898
+ bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
1899
+ bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
1900
+ bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
2082
1901
  }
2083
- function handler$2(event, root, evt) {
1902
+ function mouse(event, root, evt) {
2084
1903
  var frame = iframe(root);
2085
1904
  var d = frame ? frame.contentDocument.documentElement : document.documentElement;
2086
1905
  var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
@@ -2091,274 +1910,76 @@ function handler$2(event, root, evt) {
2091
1910
  x = x ? x + Math.round(distance.x) : x;
2092
1911
  y = y ? y + Math.round(distance.y) : y;
2093
1912
  }
2094
- var t = target(evt);
2095
- // Find nearest anchor tag (<a/>) parent if current target node is part of one
2096
- // If present, we use the returned link element to populate text and link properties below
2097
- var a = link(t);
2098
- // Get layout rectangle for the target element
2099
- var l = layout$1(t);
2100
- // Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
2101
- // This property helps differentiate between a keyboard navigation vs. pointer click
2102
- // In case of a keyboard navigation, we use center of target element as (x,y)
2103
- if (evt.detail === 0 && l) {
2104
- x = Math.round(l.x + (l.w / 2));
2105
- y = Math.round(l.y + (l.h / 2));
2106
- }
2107
- var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
2108
- var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
2109
1913
  // Check for null values before processing this event
2110
1914
  if (x !== null && y !== null) {
2111
- state$6.push({
2112
- time: time(evt),
2113
- event: event,
2114
- data: {
2115
- target: t,
2116
- x: x,
2117
- y: y,
2118
- eX: eX,
2119
- eY: eY,
2120
- button: evt.button,
2121
- reaction: reaction(t),
2122
- context: context(a),
2123
- text: text(t),
2124
- link: a ? a.href : null,
2125
- hash: null,
2126
- trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
2127
- }
2128
- });
2129
- schedule$1(encode$3.bind(this, event));
1915
+ handler$2({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
2130
1916
  }
2131
1917
  }
2132
- function link(node) {
2133
- while (node && node !== document) {
2134
- if (node.nodeType === Node.ELEMENT_NODE) {
2135
- var element = node;
2136
- if (element.tagName === "A") {
2137
- return element;
1918
+ function touch(event, root, evt) {
1919
+ var frame = iframe(root);
1920
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1921
+ var touches = evt.changedTouches;
1922
+ var t = time(evt);
1923
+ if (touches) {
1924
+ for (var i = 0; i < touches.length; i++) {
1925
+ var entry = touches[i];
1926
+ var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
1927
+ var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
1928
+ x = x && frame ? x + Math.round(frame.offsetLeft) : x;
1929
+ y = y && frame ? y + Math.round(frame.offsetTop) : y;
1930
+ // Check for null values before processing this event
1931
+ if (x !== null && y !== null) {
1932
+ handler$2({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
2138
1933
  }
2139
1934
  }
2140
- node = node.parentNode;
2141
- }
2142
- return null;
2143
- }
2144
- function text(element) {
2145
- var output = null;
2146
- if (element) {
2147
- // Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
2148
- var t = element.textContent || element.value || element.alt;
2149
- if (t) {
2150
- // Replace multiple occurrence of space characters with a single white space
2151
- // Also, trim any spaces at the beginning or at the end of string
2152
- // Finally, send only first few characters as specified by the Setting
2153
- output = t.replace(/\s+/g, " " /* Constant.Space */).trim().substr(0, 25 /* Setting.ClickText */);
2154
- }
2155
- }
2156
- return output;
2157
- }
2158
- function reaction(element) {
2159
- if (element.nodeType === Node.ELEMENT_NODE) {
2160
- var tag = element.tagName.toLowerCase();
2161
- if (UserInputTags.indexOf(tag) >= 0) {
2162
- return 0 /* BooleanFlag.False */;
2163
- }
2164
1935
  }
2165
- return 1 /* BooleanFlag.True */;
2166
1936
  }
2167
- function layout$1(element) {
2168
- var box = null;
2169
- var de = document.documentElement;
2170
- if (typeof element.getBoundingClientRect === "function") {
2171
- // getBoundingClientRect returns rectangle relative positioning to viewport
2172
- var rect = element.getBoundingClientRect();
2173
- if (rect && rect.width > 0 && rect.height > 0) {
2174
- // Add viewport's scroll position to rectangle to get position relative to document origin
2175
- // Also: using Math.floor() instead of Math.round() because in Edge,
2176
- // getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
2177
- // floors the value (e.g. 162px). This keeps consistent behavior across browsers.
2178
- box = {
2179
- x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
2180
- y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
2181
- w: Math.floor(rect.width),
2182
- h: Math.floor(rect.height)
2183
- };
2184
- }
1937
+ function handler$2(current) {
1938
+ switch (current.event) {
1939
+ case 12 /* Event.MouseMove */:
1940
+ case 15 /* Event.MouseWheel */:
1941
+ case 19 /* Event.TouchMove */:
1942
+ var length_1 = state$6.length;
1943
+ var last = length_1 > 1 ? state$6[length_1 - 2] : null;
1944
+ if (last && similar$1(last, current)) {
1945
+ state$6.pop();
1946
+ }
1947
+ state$6.push(current);
1948
+ clearTimeout(timeout$4);
1949
+ timeout$4 = setTimeout(process$5, 500 /* Setting.LookAhead */, current.event);
1950
+ break;
1951
+ default:
1952
+ state$6.push(current);
1953
+ process$5(current.event);
1954
+ break;
2185
1955
  }
2186
- return box;
2187
1956
  }
2188
- function context(a) {
2189
- if (a && a.hasAttribute("target" /* Constant.Target */)) {
2190
- switch (a.getAttribute("target" /* Constant.Target */)) {
2191
- case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
2192
- case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
2193
- case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
2194
- }
2195
- }
2196
- return 0 /* BrowsingContext.Self */;
1957
+ function process$5(event) {
1958
+ schedule$1(encode$3.bind(this, event));
2197
1959
  }
2198
1960
  function reset$f() {
2199
1961
  state$6 = [];
2200
1962
  }
1963
+ function similar$1(last, current) {
1964
+ var dx = last.data.x - current.data.x;
1965
+ var dy = last.data.y - current.data.y;
1966
+ var distance = Math.sqrt(dx * dx + dy * dy);
1967
+ var gap = current.time - last.time;
1968
+ var match = current.data.target === last.data.target;
1969
+ return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
1970
+ }
2201
1971
  function stop$q() {
2202
- reset$f();
1972
+ clearTimeout(timeout$4);
1973
+ // Send out any pending pointer events in the pipeline
1974
+ if (state$6.length > 0) {
1975
+ process$5(state$6[state$6.length - 1].event);
1976
+ }
2203
1977
  }
2204
1978
 
2205
- var state$5 = [];
1979
+ var data$b;
2206
1980
  function start$r() {
2207
- reset$e();
2208
- }
2209
- function observe$9(root) {
2210
- bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
2211
- bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
2212
- bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
2213
- }
2214
- function recompute$7(action, evt) {
2215
- state$5.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
2216
- schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
2217
- }
2218
- function reset$e() {
2219
- state$5 = [];
2220
- }
2221
- function stop$p() {
2222
- reset$e();
2223
- }
2224
-
2225
- var timeout$5 = null;
2226
- var state$4 = [];
2227
- function start$q() {
2228
- reset$d();
2229
- }
2230
- function observe$8(root) {
2231
- bind(root, "input", recompute$6, true);
2232
- }
2233
- function recompute$6(evt) {
2234
- var input = target(evt);
2235
- var value = get(input);
2236
- if (input && input.type && value) {
2237
- var v = input.value;
2238
- switch (input.type) {
2239
- case "radio":
2240
- case "checkbox":
2241
- v = input.checked ? "true" : "false";
2242
- break;
2243
- }
2244
- var data = { target: input, value: v };
2245
- // If last entry in the queue is for the same target node as the current one, remove it so we can later swap it with current data.
2246
- if (state$4.length > 0 && (state$4[state$4.length - 1].data.target === data.target)) {
2247
- state$4.pop();
2248
- }
2249
- state$4.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
2250
- clearTimeout(timeout$5);
2251
- timeout$5 = setTimeout(process$5, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
2252
- }
2253
- }
2254
- function process$5(event) {
2255
- schedule$1(encode$3.bind(this, event));
2256
- }
2257
- function reset$d() {
2258
- state$4 = [];
2259
- }
2260
- function stop$o() {
2261
- clearTimeout(timeout$5);
2262
- reset$d();
2263
- }
2264
-
2265
- var state$3 = [];
2266
- var timeout$4 = null;
2267
- function start$p() {
2268
- reset$c();
2269
- }
2270
- function observe$7(root) {
2271
- bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
2272
- bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
2273
- bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
2274
- bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
2275
- bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
2276
- bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
2277
- bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
2278
- bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
2279
- bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
2280
- }
2281
- function mouse(event, root, evt) {
2282
- var frame = iframe(root);
2283
- var d = frame ? frame.contentDocument.documentElement : document.documentElement;
2284
- var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
2285
- var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
2286
- // In case of iframe, we adjust (x,y) to be relative to top parent's origin
2287
- if (frame) {
2288
- var distance = offset(frame);
2289
- x = x ? x + Math.round(distance.x) : x;
2290
- y = y ? y + Math.round(distance.y) : y;
2291
- }
2292
- // Check for null values before processing this event
2293
- if (x !== null && y !== null) {
2294
- handler$1({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
2295
- }
2296
- }
2297
- function touch(event, root, evt) {
2298
- var frame = iframe(root);
2299
- var d = frame ? frame.contentDocument.documentElement : document.documentElement;
2300
- var touches = evt.changedTouches;
2301
- var t = time(evt);
2302
- if (touches) {
2303
- for (var i = 0; i < touches.length; i++) {
2304
- var entry = touches[i];
2305
- var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
2306
- var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
2307
- x = x && frame ? x + Math.round(frame.offsetLeft) : x;
2308
- y = y && frame ? y + Math.round(frame.offsetTop) : y;
2309
- // Check for null values before processing this event
2310
- if (x !== null && y !== null) {
2311
- handler$1({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
2312
- }
2313
- }
2314
- }
2315
- }
2316
- function handler$1(current) {
2317
- switch (current.event) {
2318
- case 12 /* Event.MouseMove */:
2319
- case 15 /* Event.MouseWheel */:
2320
- case 19 /* Event.TouchMove */:
2321
- var length_1 = state$3.length;
2322
- var last = length_1 > 1 ? state$3[length_1 - 2] : null;
2323
- if (last && similar$1(last, current)) {
2324
- state$3.pop();
2325
- }
2326
- state$3.push(current);
2327
- clearTimeout(timeout$4);
2328
- timeout$4 = setTimeout(process$4, 500 /* Setting.LookAhead */, current.event);
2329
- break;
2330
- default:
2331
- state$3.push(current);
2332
- process$4(current.event);
2333
- break;
2334
- }
2335
- }
2336
- function process$4(event) {
2337
- schedule$1(encode$3.bind(this, event));
2338
- }
2339
- function reset$c() {
2340
- state$3 = [];
2341
- }
2342
- function similar$1(last, current) {
2343
- var dx = last.data.x - current.data.x;
2344
- var dy = last.data.y - current.data.y;
2345
- var distance = Math.sqrt(dx * dx + dy * dy);
2346
- var gap = current.time - last.time;
2347
- var match = current.data.target === last.data.target;
2348
- return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
2349
- }
2350
- function stop$n() {
2351
- clearTimeout(timeout$4);
2352
- // Send out any pending pointer events in the pipeline
2353
- if (state$3.length > 0) {
2354
- process$4(state$3[state$3.length - 1].event);
2355
- }
2356
- }
2357
-
2358
- var data$b;
2359
- function start$o() {
2360
- bind(window, "resize", recompute$5);
2361
- recompute$5();
1981
+ bind(window, "resize", recompute$5);
1982
+ recompute$5();
2362
1983
  }
2363
1984
  function recompute$5() {
2364
1985
  var de = document.documentElement;
@@ -2370,20 +1991,20 @@ function recompute$5() {
2370
1991
  };
2371
1992
  encode$3(11 /* Event.Resize */);
2372
1993
  }
2373
- function reset$b() {
1994
+ function reset$e() {
2374
1995
  data$b = null;
2375
1996
  }
2376
- function stop$m() {
2377
- reset$b();
1997
+ function stop$p() {
1998
+ reset$e();
2378
1999
  }
2379
2000
 
2380
- var state$2 = [];
2001
+ var state$5 = [];
2381
2002
  var timeout$3 = null;
2382
- function start$n() {
2383
- state$2 = [];
2003
+ function start$q() {
2004
+ state$5 = [];
2384
2005
  recompute$4();
2385
2006
  }
2386
- function observe$6(root) {
2007
+ function observe$7(root) {
2387
2008
  var frame = iframe(root);
2388
2009
  var node = frame ? frame.contentWindow : (root === document ? window : root);
2389
2010
  bind(node, "scroll", recompute$4, true);
@@ -2409,19 +2030,19 @@ function recompute$4(event) {
2409
2030
  if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
2410
2031
  return;
2411
2032
  }
2412
- var length = state$2.length;
2413
- var last = length > 1 ? state$2[length - 2] : null;
2033
+ var length = state$5.length;
2034
+ var last = length > 1 ? state$5[length - 2] : null;
2414
2035
  if (last && similar(last, current)) {
2415
- state$2.pop();
2036
+ state$5.pop();
2416
2037
  }
2417
- state$2.push(current);
2038
+ state$5.push(current);
2418
2039
  clearTimeout(timeout$3);
2419
- timeout$3 = setTimeout(process$3, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
2040
+ timeout$3 = setTimeout(process$4, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
2420
2041
  }
2421
- function reset$a() {
2422
- state$2 = [];
2042
+ function reset$d() {
2043
+ state$5 = [];
2423
2044
  }
2424
- function process$3(event) {
2045
+ function process$4(event) {
2425
2046
  schedule$1(encode$3.bind(this, event));
2426
2047
  }
2427
2048
  function similar(last, current) {
@@ -2429,18 +2050,18 @@ function similar(last, current) {
2429
2050
  var dy = last.data.y - current.data.y;
2430
2051
  return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
2431
2052
  }
2432
- function stop$l() {
2053
+ function stop$o() {
2433
2054
  clearTimeout(timeout$3);
2434
- state$2 = [];
2055
+ state$5 = [];
2435
2056
  }
2436
2057
 
2437
2058
  var data$a = null;
2438
2059
  var previous = null;
2439
2060
  var timeout$2 = null;
2440
- function start$m() {
2441
- reset$9();
2061
+ function start$p() {
2062
+ reset$c();
2442
2063
  }
2443
- function observe$5(root) {
2064
+ function observe$6(root) {
2444
2065
  bind(root, "selectstart", recompute$3.bind(this, root), true);
2445
2066
  bind(root, "selectionchange", recompute$3.bind(this, root), true);
2446
2067
  }
@@ -2462,7 +2083,7 @@ function recompute$3(root) {
2462
2083
  var startNode = data$a.start ? data$a.start : null;
2463
2084
  if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
2464
2085
  clearTimeout(timeout$2);
2465
- process$2(21 /* Event.Selection */);
2086
+ process$3(21 /* Event.Selection */);
2466
2087
  }
2467
2088
  data$a = {
2468
2089
  start: current.anchorNode,
@@ -2472,40 +2093,40 @@ function recompute$3(root) {
2472
2093
  };
2473
2094
  previous = current;
2474
2095
  clearTimeout(timeout$2);
2475
- timeout$2 = setTimeout(process$2, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
2096
+ timeout$2 = setTimeout(process$3, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
2476
2097
  }
2477
- function process$2(event) {
2098
+ function process$3(event) {
2478
2099
  schedule$1(encode$3.bind(this, event));
2479
2100
  }
2480
- function reset$9() {
2101
+ function reset$c() {
2481
2102
  previous = null;
2482
2103
  data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
2483
2104
  }
2484
- function stop$k() {
2485
- reset$9();
2105
+ function stop$n() {
2106
+ reset$c();
2486
2107
  clearTimeout(timeout$2);
2487
2108
  }
2488
2109
 
2489
- var state$1 = [];
2490
- function start$l() {
2491
- reset$8();
2110
+ var state$4 = [];
2111
+ function start$o() {
2112
+ reset$b();
2492
2113
  }
2493
- function observe$4(root) {
2114
+ function observe$5(root) {
2494
2115
  bind(root, "submit", recompute$2, true);
2495
2116
  }
2496
2117
  function recompute$2(evt) {
2497
- state$1.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
2118
+ state$4.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
2498
2119
  schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
2499
2120
  }
2500
- function reset$8() {
2501
- state$1 = [];
2121
+ function reset$b() {
2122
+ state$4 = [];
2502
2123
  }
2503
- function stop$j() {
2504
- reset$8();
2124
+ function stop$m() {
2125
+ reset$b();
2505
2126
  }
2506
2127
 
2507
2128
  var data$9;
2508
- function start$k() {
2129
+ function start$n() {
2509
2130
  bind(window, "pagehide", recompute$1);
2510
2131
  }
2511
2132
  function recompute$1(evt) {
@@ -2513,15 +2134,15 @@ function recompute$1(evt) {
2513
2134
  encode$3(26 /* Event.Unload */, time(evt));
2514
2135
  stop();
2515
2136
  }
2516
- function reset$7() {
2137
+ function reset$a() {
2517
2138
  data$9 = null;
2518
2139
  }
2519
- function stop$i() {
2520
- reset$7();
2140
+ function stop$l() {
2141
+ reset$a();
2521
2142
  }
2522
2143
 
2523
2144
  var data$8;
2524
- function start$j() {
2145
+ function start$m() {
2525
2146
  bind(document, "visibilitychange", recompute);
2526
2147
  recompute();
2527
2148
  }
@@ -2530,97 +2151,432 @@ function recompute(evt) {
2530
2151
  data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
2531
2152
  encode$3(28 /* Event.Visibility */, time(evt));
2532
2153
  }
2533
- function reset$6() {
2154
+ function reset$9() {
2534
2155
  data$8 = null;
2535
2156
  }
2536
- function stop$h() {
2537
- reset$6();
2157
+ function stop$k() {
2158
+ reset$9();
2538
2159
  }
2539
2160
 
2540
- function start$i() {
2161
+ function start$l() {
2541
2162
  start$g();
2163
+ start$v();
2164
+ start$u();
2542
2165
  start$s();
2166
+ start$t();
2543
2167
  start$r();
2544
- start$p();
2168
+ start$m();
2545
2169
  start$q();
2170
+ start$p();
2171
+ start$w();
2546
2172
  start$o();
2547
- start$j();
2548
2173
  start$n();
2549
- start$m();
2550
- start$t();
2551
- start$l();
2552
- start$k();
2553
2174
  }
2554
- function stop$g() {
2175
+ function stop$j() {
2555
2176
  stop$e();
2177
+ stop$t();
2178
+ stop$s();
2556
2179
  stop$q();
2180
+ stop$r();
2557
2181
  stop$p();
2558
- stop$n();
2182
+ stop$k();
2559
2183
  stop$o();
2184
+ stop$n();
2185
+ stop$u();
2560
2186
  stop$m();
2561
- stop$h();
2562
2187
  stop$l();
2563
- stop$k();
2564
- stop$r();
2565
- stop$j();
2566
- stop$i();
2567
2188
  }
2568
- function observe$3(root) {
2569
- observe$6(root);
2189
+ function observe$4(root) {
2190
+ observe$7(root);
2570
2191
  // Only monitor following interactions if the root node is a document
2571
2192
  // In case of shadow DOM, following events automatically bubble up to the parent document.
2572
2193
  if (root.nodeType === Node.DOCUMENT_NODE) {
2194
+ observe$b(root);
2573
2195
  observe$a(root);
2574
- observe$9(root);
2575
- observe$7(root);
2576
2196
  observe$8(root);
2197
+ observe$9(root);
2198
+ observe$6(root);
2199
+ observe$c(root);
2577
2200
  observe$5(root);
2578
- observe$b(root);
2579
- observe$4(root);
2580
2201
  }
2581
2202
  }
2582
2203
 
2583
2204
  var interaction = /*#__PURE__*/Object.freeze({
2584
2205
  __proto__: null,
2585
- observe: observe$3,
2586
- start: start$i,
2587
- stop: stop$g
2206
+ observe: observe$4,
2207
+ start: start$l,
2208
+ stop: stop$j
2588
2209
  });
2589
2210
 
2590
- var digitsRegex = /[^0-9\.]/g;
2591
- /* JSON+LD (Linked Data) Recursive Parser */
2592
- function ld(json) {
2593
- for (var _i = 0, _a = Object.keys(json); _i < _a.length; _i++) {
2594
- var key = _a[_i];
2595
- var value = json[key];
2596
- if (key === "@type" /* JsonLD.Type */ && typeof value === "string") {
2597
- value = value.toLowerCase();
2598
- /* Normalizations */
2599
- value = value.indexOf("article" /* JsonLD.Article */) >= 0 || value.indexOf("posting" /* JsonLD.Posting */) >= 0 ? "article" /* JsonLD.Article */ : value;
2600
- switch (value) {
2601
- case "article" /* JsonLD.Article */:
2602
- case "recipe" /* JsonLD.Recipe */:
2603
- log(5 /* Dimension.SchemaType */, json[key]);
2604
- log(8 /* Dimension.AuthorName */, json["creator" /* JsonLD.Creator */]);
2605
- log(18 /* Dimension.Headline */, json["headline" /* JsonLD.Headline */]);
2606
- break;
2607
- case "product" /* JsonLD.Product */:
2608
- log(5 /* Dimension.SchemaType */, json[key]);
2609
- log(10 /* Dimension.ProductName */, json["name" /* JsonLD.Name */]);
2610
- log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
2611
- if (json["brand" /* JsonLD.Brand */]) {
2612
- log(6 /* Dimension.ProductBrand */, json["brand" /* JsonLD.Brand */]["name" /* JsonLD.Name */]);
2613
- }
2614
- break;
2615
- case "aggregaterating" /* JsonLD.AggregateRating */:
2616
- if (json["ratingValue" /* JsonLD.RatingValue */]) {
2617
- max(11 /* Metric.RatingValue */, num$1(json["ratingValue" /* JsonLD.RatingValue */], 100 /* Setting.RatingScale */));
2618
- max(18 /* Metric.BestRating */, num$1(json["bestRating" /* JsonLD.BestRating */]));
2619
- max(19 /* Metric.WorstRating */, num$1(json["worstRating" /* JsonLD.WorstRating */]));
2620
- }
2621
- max(12 /* Metric.RatingCount */, num$1(json["ratingCount" /* JsonLD.RatingCount */]));
2622
- max(17 /* Metric.ReviewCount */, num$1(json["reviewCount" /* JsonLD.ReviewCount */]));
2623
- break;
2211
+ function traverse (root, timer, source) {
2212
+ return __awaiter(this, void 0, void 0, function () {
2213
+ var queue, entry, next, state, subnode;
2214
+ return __generator(this, function (_a) {
2215
+ switch (_a.label) {
2216
+ case 0:
2217
+ queue = [root];
2218
+ _a.label = 1;
2219
+ case 1:
2220
+ if (!(queue.length > 0)) return [3 /*break*/, 4];
2221
+ entry = queue.shift();
2222
+ next = entry.firstChild;
2223
+ while (next) {
2224
+ queue.push(next);
2225
+ next = next.nextSibling;
2226
+ }
2227
+ state = state$b(timer);
2228
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
2229
+ return [4 /*yield*/, suspend$1(timer)];
2230
+ case 2:
2231
+ state = _a.sent();
2232
+ _a.label = 3;
2233
+ case 3:
2234
+ if (state === 2 /* Task.Stop */) {
2235
+ return [3 /*break*/, 4];
2236
+ }
2237
+ subnode = processNode(entry, source);
2238
+ if (subnode) {
2239
+ queue.push(subnode);
2240
+ }
2241
+ return [3 /*break*/, 1];
2242
+ case 4: return [2 /*return*/];
2243
+ }
2244
+ });
2245
+ });
2246
+ }
2247
+
2248
+ var observers = [];
2249
+ var mutations = [];
2250
+ var insertRule = null;
2251
+ var deleteRule = null;
2252
+ var attachShadow = null;
2253
+ var queue$2 = [];
2254
+ var timeout$1 = null;
2255
+ var activePeriod = null;
2256
+ var history$4 = {};
2257
+ function start$k() {
2258
+ observers = [];
2259
+ queue$2 = [];
2260
+ timeout$1 = null;
2261
+ activePeriod = 0;
2262
+ history$4 = {};
2263
+ // Some popular open source libraries, like styled-components, optimize performance
2264
+ // by injecting CSS using insertRule API vs. appending text node. A side effect of
2265
+ // using javascript API is that it doesn't trigger DOM mutation and therefore we
2266
+ // need to override the insertRule API and listen for changes manually.
2267
+ if (insertRule === null) {
2268
+ insertRule = CSSStyleSheet.prototype.insertRule;
2269
+ CSSStyleSheet.prototype.insertRule = function () {
2270
+ if (active()) {
2271
+ schedule(this.ownerNode);
2272
+ }
2273
+ return insertRule.apply(this, arguments);
2274
+ };
2275
+ }
2276
+ if (deleteRule === null) {
2277
+ deleteRule = CSSStyleSheet.prototype.deleteRule;
2278
+ CSSStyleSheet.prototype.deleteRule = function () {
2279
+ if (active()) {
2280
+ schedule(this.ownerNode);
2281
+ }
2282
+ return deleteRule.apply(this, arguments);
2283
+ };
2284
+ }
2285
+ // Add a hook to attachShadow API calls
2286
+ // In case we are unable to add a hook and browser throws an exception,
2287
+ // reset attachShadow variable and resume processing like before
2288
+ if (attachShadow === null) {
2289
+ attachShadow = Element.prototype.attachShadow;
2290
+ try {
2291
+ Element.prototype.attachShadow = function () {
2292
+ if (active()) {
2293
+ return schedule(attachShadow.apply(this, arguments));
2294
+ }
2295
+ else {
2296
+ return attachShadow.apply(this, arguments);
2297
+ }
2298
+ };
2299
+ }
2300
+ catch (_a) {
2301
+ attachShadow = null;
2302
+ }
2303
+ }
2304
+ }
2305
+ function observe$3(node) {
2306
+ // Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
2307
+ // In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
2308
+ // For this reason, we need to wire up mutations every time we see a new shadow dom.
2309
+ // Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
2310
+ try {
2311
+ var m = api("MutationObserver" /* Constant.MutationObserver */);
2312
+ var observer = m in window ? new window[m](measure(handle$1)) : null;
2313
+ if (observer) {
2314
+ observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
2315
+ observers.push(observer);
2316
+ }
2317
+ }
2318
+ catch (e) {
2319
+ log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
2320
+ }
2321
+ }
2322
+ function monitor(frame) {
2323
+ // Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
2324
+ // This includes cases where iframe location is updated without explicitly updating src attribute
2325
+ // E.g. iframe.contentWindow.location.href = "new-location";
2326
+ if (has(frame) === false) {
2327
+ bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
2328
+ }
2329
+ }
2330
+ function stop$i() {
2331
+ for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
2332
+ var observer = observers_1[_i];
2333
+ if (observer) {
2334
+ observer.disconnect();
2335
+ }
2336
+ }
2337
+ observers = [];
2338
+ history$4 = {};
2339
+ mutations = [];
2340
+ queue$2 = [];
2341
+ activePeriod = 0;
2342
+ timeout$1 = null;
2343
+ }
2344
+ function active$2() {
2345
+ activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
2346
+ }
2347
+ function handle$1(m) {
2348
+ // Queue up mutation records for asynchronous processing
2349
+ var now = time();
2350
+ track$7(6 /* Event.Mutation */, now);
2351
+ mutations.push({ time: now, mutations: m });
2352
+ schedule$1(process$2, 1 /* Priority.High */).then(function () {
2353
+ setTimeout(compute$8);
2354
+ measure(compute$6)();
2355
+ });
2356
+ }
2357
+ function process$2() {
2358
+ return __awaiter(this, void 0, void 0, function () {
2359
+ var timer, record, instance, _i, _a, mutation, state, target, type, value;
2360
+ return __generator(this, function (_b) {
2361
+ switch (_b.label) {
2362
+ case 0:
2363
+ timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
2364
+ start$y(timer);
2365
+ _b.label = 1;
2366
+ case 1:
2367
+ if (!(mutations.length > 0)) return [3 /*break*/, 8];
2368
+ record = mutations.shift();
2369
+ instance = time();
2370
+ _i = 0, _a = record.mutations;
2371
+ _b.label = 2;
2372
+ case 2:
2373
+ if (!(_i < _a.length)) return [3 /*break*/, 6];
2374
+ mutation = _a[_i];
2375
+ state = state$b(timer);
2376
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2377
+ return [4 /*yield*/, suspend$1(timer)];
2378
+ case 3:
2379
+ state = _b.sent();
2380
+ _b.label = 4;
2381
+ case 4:
2382
+ if (state === 2 /* Task.Stop */) {
2383
+ return [3 /*break*/, 6];
2384
+ }
2385
+ target = mutation.target;
2386
+ type = track$5(mutation, timer, instance);
2387
+ if (type && target && target.ownerDocument) {
2388
+ parse$1(target.ownerDocument);
2389
+ }
2390
+ if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
2391
+ parse$1(target);
2392
+ }
2393
+ switch (type) {
2394
+ case "attributes" /* Constant.Attributes */:
2395
+ processNode(target, 3 /* Source.Attributes */);
2396
+ break;
2397
+ case "characterData" /* Constant.CharacterData */:
2398
+ processNode(target, 4 /* Source.CharacterData */);
2399
+ break;
2400
+ case "childList" /* Constant.ChildList */:
2401
+ processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer);
2402
+ processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer);
2403
+ break;
2404
+ case "suspend" /* Constant.Suspend */:
2405
+ value = get(target);
2406
+ if (value) {
2407
+ value.metadata.suspend = true;
2408
+ }
2409
+ break;
2410
+ }
2411
+ _b.label = 5;
2412
+ case 5:
2413
+ _i++;
2414
+ return [3 /*break*/, 2];
2415
+ case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
2416
+ case 7:
2417
+ _b.sent();
2418
+ return [3 /*break*/, 1];
2419
+ case 8:
2420
+ stop$w(timer);
2421
+ return [2 /*return*/];
2422
+ }
2423
+ });
2424
+ });
2425
+ }
2426
+ function track$5(m, timer, instance) {
2427
+ var value = m.target ? get(m.target.parentNode) : null;
2428
+ // Check if the parent is already discovered and that the parent is not the document root
2429
+ if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
2430
+ var inactive = time() > activePeriod;
2431
+ var target = get(m.target);
2432
+ var element = target && target.selector ? target.selector.join() : m.target.nodeName;
2433
+ var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
2434
+ // We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
2435
+ // repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
2436
+ // In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
2437
+ var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
2438
+ // Initialize an entry if it doesn't already exist
2439
+ history$4[key] = key in history$4 ? history$4[key] : [0, instance];
2440
+ var h = history$4[key];
2441
+ // Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
2442
+ if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
2443
+ processNodeList(h[2], 2 /* Source.ChildListRemove */, timer);
2444
+ }
2445
+ // Update the counter
2446
+ h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
2447
+ h[1] = instance;
2448
+ // Return updated mutation type based on if we have already hit the threshold or not
2449
+ if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
2450
+ // Store a reference to removedNodes so we can process them later
2451
+ // when we resume mutations again on user interactions
2452
+ h[2] = m.removedNodes;
2453
+ return "suspend" /* Constant.Suspend */;
2454
+ }
2455
+ else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
2456
+ return "" /* Constant.Empty */;
2457
+ }
2458
+ }
2459
+ return m.type;
2460
+ }
2461
+ function names(nodes) {
2462
+ var output = [];
2463
+ for (var i = 0; nodes && i < nodes.length; i++) {
2464
+ output.push(nodes[i].nodeName);
2465
+ }
2466
+ return output.join();
2467
+ }
2468
+ function processNodeList(list, source, timer) {
2469
+ return __awaiter(this, void 0, void 0, function () {
2470
+ var length, i, state;
2471
+ return __generator(this, function (_a) {
2472
+ switch (_a.label) {
2473
+ case 0:
2474
+ length = list ? list.length : 0;
2475
+ i = 0;
2476
+ _a.label = 1;
2477
+ case 1:
2478
+ if (!(i < length)) return [3 /*break*/, 6];
2479
+ if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
2480
+ traverse(list[i], timer, source);
2481
+ return [3 /*break*/, 5];
2482
+ case 2:
2483
+ state = state$b(timer);
2484
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2485
+ return [4 /*yield*/, suspend$1(timer)];
2486
+ case 3:
2487
+ state = _a.sent();
2488
+ _a.label = 4;
2489
+ case 4:
2490
+ if (state === 2 /* Task.Stop */) {
2491
+ return [3 /*break*/, 6];
2492
+ }
2493
+ processNode(list[i], source);
2494
+ _a.label = 5;
2495
+ case 5:
2496
+ i++;
2497
+ return [3 /*break*/, 1];
2498
+ case 6: return [2 /*return*/];
2499
+ }
2500
+ });
2501
+ });
2502
+ }
2503
+ function schedule(node) {
2504
+ // Only schedule manual trigger for this node if it's not already in the queue
2505
+ if (queue$2.indexOf(node) < 0) {
2506
+ queue$2.push(node);
2507
+ }
2508
+ // Cancel any previous trigger before scheduling a new one.
2509
+ // It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
2510
+ // And in those cases we do not wish to monitor changes multiple times for the same node.
2511
+ if (timeout$1) {
2512
+ clearTimeout(timeout$1);
2513
+ }
2514
+ timeout$1 = setTimeout(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
2515
+ return node;
2516
+ }
2517
+ function trigger$2() {
2518
+ for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
2519
+ var node = queue_1[_i];
2520
+ // Generate a mutation for this node only if it still exists
2521
+ if (node) {
2522
+ var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
2523
+ // Skip re-processing shadowRoot if it was already discovered
2524
+ if (shadowRoot && has(node)) {
2525
+ continue;
2526
+ }
2527
+ generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
2528
+ }
2529
+ }
2530
+ queue$2 = [];
2531
+ }
2532
+ function generate(target, type) {
2533
+ measure(handle$1)([{
2534
+ addedNodes: [target],
2535
+ attributeName: null,
2536
+ attributeNamespace: null,
2537
+ nextSibling: null,
2538
+ oldValue: null,
2539
+ previousSibling: null,
2540
+ removedNodes: [],
2541
+ target: target,
2542
+ type: type
2543
+ }]);
2544
+ }
2545
+
2546
+ var digitsRegex = /[^0-9\.]/g;
2547
+ /* JSON+LD (Linked Data) Recursive Parser */
2548
+ function ld(json) {
2549
+ for (var _i = 0, _a = Object.keys(json); _i < _a.length; _i++) {
2550
+ var key = _a[_i];
2551
+ var value = json[key];
2552
+ if (key === "@type" /* JsonLD.Type */ && typeof value === "string") {
2553
+ value = value.toLowerCase();
2554
+ /* Normalizations */
2555
+ value = value.indexOf("article" /* JsonLD.Article */) >= 0 || value.indexOf("posting" /* JsonLD.Posting */) >= 0 ? "article" /* JsonLD.Article */ : value;
2556
+ switch (value) {
2557
+ case "article" /* JsonLD.Article */:
2558
+ case "recipe" /* JsonLD.Recipe */:
2559
+ log(5 /* Dimension.SchemaType */, json[key]);
2560
+ log(8 /* Dimension.AuthorName */, json["creator" /* JsonLD.Creator */]);
2561
+ log(18 /* Dimension.Headline */, json["headline" /* JsonLD.Headline */]);
2562
+ break;
2563
+ case "product" /* JsonLD.Product */:
2564
+ log(5 /* Dimension.SchemaType */, json[key]);
2565
+ log(10 /* Dimension.ProductName */, json["name" /* JsonLD.Name */]);
2566
+ log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
2567
+ if (json["brand" /* JsonLD.Brand */]) {
2568
+ log(6 /* Dimension.ProductBrand */, json["brand" /* JsonLD.Brand */]["name" /* JsonLD.Name */]);
2569
+ }
2570
+ break;
2571
+ case "aggregaterating" /* JsonLD.AggregateRating */:
2572
+ if (json["ratingValue" /* JsonLD.RatingValue */]) {
2573
+ max(11 /* Metric.RatingValue */, num$1(json["ratingValue" /* JsonLD.RatingValue */], 100 /* Setting.RatingScale */));
2574
+ max(18 /* Metric.BestRating */, num$1(json["bestRating" /* JsonLD.BestRating */]));
2575
+ max(19 /* Metric.WorstRating */, num$1(json["worstRating" /* JsonLD.WorstRating */]));
2576
+ }
2577
+ max(12 /* Metric.RatingCount */, num$1(json["ratingCount" /* JsonLD.RatingCount */]));
2578
+ max(17 /* Metric.ReviewCount */, num$1(json["reviewCount" /* JsonLD.ReviewCount */]));
2579
+ break;
2624
2580
  case "person" /* JsonLD.Author */:
2625
2581
  log(8 /* Dimension.AuthorName */, json["name" /* JsonLD.Name */]);
2626
2582
  break;
@@ -2687,6 +2643,7 @@ function processNode (node, source) {
2687
2643
  // later whenever there are new additions or modifications to DOM (mutations)
2688
2644
  if (node === document)
2689
2645
  parse$1(document);
2646
+ checkDocumentStyles(node);
2690
2647
  observe$2(node);
2691
2648
  break;
2692
2649
  case Node.DOCUMENT_FRAGMENT_NODE:
@@ -2701,11 +2658,6 @@ function processNode (node, source) {
2701
2658
  // In future we may decide to proxy "attachShadow" call to gain access, but at the moment, we don't want to
2702
2659
  // cause any unintended side effect to the page. We will re-evaluate after we gather more real world data on this.
2703
2660
  var style = "" /* Constant.Empty */;
2704
- var adoptedStyleSheets = "adoptedStyleSheets" in shadowRoot ? shadowRoot["adoptedStyleSheets"] : [];
2705
- for (var _i = 0, adoptedStyleSheets_1 = adoptedStyleSheets; _i < adoptedStyleSheets_1.length; _i++) {
2706
- var styleSheet = adoptedStyleSheets_1[_i];
2707
- style += getCssRules(styleSheet);
2708
- }
2709
2661
  var fragmentData = { tag: "*S" /* Constant.ShadowDomTag */, attributes: { style: style } };
2710
2662
  dom[call](node, shadowRoot.host, fragmentData, source);
2711
2663
  }
@@ -2715,6 +2667,7 @@ function processNode (node, source) {
2715
2667
  // the same way we observe real shadow DOM nodes (encapsulation provided by the browser).
2716
2668
  dom[call](node, shadowRoot.host, { tag: "*P" /* Constant.PolyfillShadowDomTag */, attributes: {} }, source);
2717
2669
  }
2670
+ checkDocumentStyles(node);
2718
2671
  }
2719
2672
  break;
2720
2673
  case Node.TEXT_NODE:
@@ -2843,8 +2796,8 @@ function observe$2(root) {
2843
2796
  if (has(root)) {
2844
2797
  return;
2845
2798
  }
2846
- observe$1(root); // Observe mutations for this root node
2847
- observe$3(root); // Observe interactions for this root node
2799
+ observe$3(root); // Observe mutations for this root node
2800
+ observe$4(root); // Observe interactions for this root node
2848
2801
  }
2849
2802
  function getStyleValue(style) {
2850
2803
  // Call trim on the text content to ensure we do not process white spaces ( , \n, \r\n, \t, etc.)
@@ -2894,339 +2847,511 @@ function getAttributes(element) {
2894
2847
  return output;
2895
2848
  }
2896
2849
 
2897
- function traverse (root, timer, source) {
2898
- return __awaiter(this, void 0, void 0, function () {
2899
- var queue, entry, next, state, subnode;
2900
- return __generator(this, function (_a) {
2901
- switch (_a.label) {
2902
- case 0:
2903
- queue = [root];
2904
- _a.label = 1;
2905
- case 1:
2906
- if (!(queue.length > 0)) return [3 /*break*/, 4];
2907
- entry = queue.shift();
2908
- next = entry.firstChild;
2909
- while (next) {
2910
- queue.push(next);
2911
- next = next.nextSibling;
2912
- }
2913
- state = state$a(timer);
2914
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
2915
- return [4 /*yield*/, suspend$1(timer)];
2916
- case 2:
2917
- state = _a.sent();
2918
- _a.label = 3;
2919
- case 3:
2920
- if (state === 2 /* Task.Stop */) {
2921
- return [3 /*break*/, 4];
2922
- }
2923
- subnode = processNode(entry, source);
2924
- if (subnode) {
2925
- queue.push(subnode);
2926
- }
2927
- return [3 /*break*/, 1];
2928
- case 4: return [2 /*return*/];
2929
- }
2930
- });
2931
- });
2932
- }
2933
-
2934
- var observers = [];
2935
- var mutations = [];
2936
- var insertRule = null;
2937
- var deleteRule = null;
2938
- var attachShadow = null;
2939
- var queue$1 = [];
2940
- var timeout$1 = null;
2941
- var activePeriod = null;
2942
- var history$4 = {};
2943
- function start$h() {
2944
- observers = [];
2945
- queue$1 = [];
2946
- timeout$1 = null;
2947
- activePeriod = 0;
2948
- history$4 = {};
2949
- // Some popular open source libraries, like styled-components, optimize performance
2950
- // by injecting CSS using insertRule API vs. appending text node. A side effect of
2951
- // using javascript API is that it doesn't trigger DOM mutation and therefore we
2952
- // need to override the insertRule API and listen for changes manually.
2953
- if (insertRule === null) {
2954
- insertRule = CSSStyleSheet.prototype.insertRule;
2955
- CSSStyleSheet.prototype.insertRule = function () {
2850
+ var state$3 = [];
2851
+ var replace = null;
2852
+ var replaceSync = null;
2853
+ var styleSheetId = 'claritySheetId';
2854
+ var styleSheetMap = {};
2855
+ function start$j() {
2856
+ reset$8();
2857
+ if (replace === null) {
2858
+ replace = CSSStyleSheet.prototype.replace;
2859
+ CSSStyleSheet.prototype.replace = function () {
2956
2860
  if (active()) {
2957
- schedule(this.ownerNode);
2861
+ if (!this[styleSheetId]) {
2862
+ this[styleSheetId] = shortid();
2863
+ // need to pass a create style sheet event (don't add it to any nodes, but do create it)
2864
+ trackStyleChange(time(), this[styleSheetId], 0 /* StyleSheetOperation.Create */);
2865
+ }
2866
+ trackStyleChange(time(), this[styleSheetId], 1 /* StyleSheetOperation.Replace */, arguments[0]);
2958
2867
  }
2959
- return insertRule.apply(this, arguments);
2868
+ return replace.apply(this, arguments);
2960
2869
  };
2961
2870
  }
2962
- if (deleteRule === null) {
2963
- deleteRule = CSSStyleSheet.prototype.deleteRule;
2964
- CSSStyleSheet.prototype.deleteRule = function () {
2871
+ if (replaceSync === null) {
2872
+ replaceSync = CSSStyleSheet.prototype.replaceSync;
2873
+ CSSStyleSheet.prototype.replaceSync = function () {
2965
2874
  if (active()) {
2966
- schedule(this.ownerNode);
2875
+ if (!this[styleSheetId]) {
2876
+ this[styleSheetId] = shortid();
2877
+ // need to pass a create style sheet event (don't add it to any nodes, but do create it)
2878
+ trackStyleChange(time(), this[styleSheetId], 0 /* StyleSheetOperation.Create */);
2879
+ }
2880
+ trackStyleChange(time(), this[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, arguments[0]);
2967
2881
  }
2968
- return deleteRule.apply(this, arguments);
2882
+ return replaceSync.apply(this, arguments);
2969
2883
  };
2970
2884
  }
2971
- // Add a hook to attachShadow API calls
2972
- // In case we are unable to add a hook and browser throws an exception,
2973
- // reset attachShadow variable and resume processing like before
2974
- if (attachShadow === null) {
2975
- attachShadow = Element.prototype.attachShadow;
2976
- try {
2977
- Element.prototype.attachShadow = function () {
2978
- if (active()) {
2979
- return schedule(attachShadow.apply(this, arguments));
2980
- }
2981
- else {
2982
- return attachShadow.apply(this, arguments);
2983
- }
2984
- };
2985
- }
2986
- catch (_a) {
2987
- attachShadow = null;
2988
- }
2989
- }
2990
2885
  }
2991
- function observe$1(node) {
2992
- // Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
2993
- // In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
2994
- // For this reason, we need to wire up mutations every time we see a new shadow dom.
2995
- // Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
2996
- try {
2997
- var m = api("MutationObserver" /* Constant.MutationObserver */);
2998
- var observer = m in window ? new window[m](measure(handle$1)) : null;
2999
- if (observer) {
3000
- observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
3001
- observers.push(observer);
2886
+ function checkDocumentStyles(documentNode) {
2887
+ if (!(documentNode === null || documentNode === void 0 ? void 0 : documentNode.adoptedStyleSheets)) {
2888
+ // if we don't have adoptedStyledSheets on the Node passed to us, we can short circuit.
2889
+ return;
2890
+ }
2891
+ var currentStyleSheets = [];
2892
+ for (var _i = 0, _a = documentNode.adoptedStyleSheets; _i < _a.length; _i++) {
2893
+ var styleSheet = _a[_i];
2894
+ // if we haven't seen this style sheet, create it and pass a replaceSync with its contents
2895
+ if (!styleSheet[styleSheetId]) {
2896
+ styleSheet[styleSheetId] = shortid();
2897
+ trackStyleChange(time(), styleSheet[styleSheetId], 0 /* StyleSheetOperation.Create */);
2898
+ trackStyleChange(time(), styleSheet[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, getCssRules(styleSheet));
3002
2899
  }
2900
+ currentStyleSheets.push(styleSheet[styleSheetId]);
3003
2901
  }
3004
- catch (e) {
3005
- log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
2902
+ var documentId = getId(documentNode, true);
2903
+ if (!styleSheetMap[documentId]) {
2904
+ styleSheetMap[documentId] = [];
3006
2905
  }
3007
- }
3008
- function monitor(frame) {
3009
- // Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
3010
- // This includes cases where iframe location is updated without explicitly updating src attribute
3011
- // E.g. iframe.contentWindow.location.href = "new-location";
3012
- if (has(frame) === false) {
3013
- bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
2906
+ if (!arraysEqual(currentStyleSheets, styleSheetMap[documentId])) {
2907
+ // Using -1 to signify the root document node as we don't track that as part of our nodeMap
2908
+ trackStyleAdoption(time(), documentNode == document ? -1 : getId(documentNode), 3 /* StyleSheetOperation.SetAdoptedStyles */, currentStyleSheets);
2909
+ styleSheetMap[documentId] = currentStyleSheets;
3014
2910
  }
3015
2911
  }
3016
- function stop$f() {
3017
- for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
3018
- var observer = observers_1[_i];
3019
- if (observer) {
3020
- observer.disconnect();
2912
+ function compute$7() {
2913
+ checkDocumentStyles(document);
2914
+ Object.keys(styleSheetMap).forEach(function (x) { return checkDocumentStyles(getNode(parseInt(x, 10))); });
2915
+ }
2916
+ function reset$8() {
2917
+ state$3 = [];
2918
+ }
2919
+ function stop$h() {
2920
+ styleSheetMap = {};
2921
+ reset$8();
2922
+ }
2923
+ function trackStyleChange(time, id, operation, cssRules) {
2924
+ state$3.push({
2925
+ time: time,
2926
+ event: 46 /* Event.StyleSheetUpdate */,
2927
+ data: {
2928
+ id: id,
2929
+ operation: operation,
2930
+ cssRules: cssRules
3021
2931
  }
2932
+ });
2933
+ encode$4(46 /* Event.StyleSheetUpdate */);
2934
+ }
2935
+ function trackStyleAdoption(time, id, operation, newIds) {
2936
+ state$3.push({
2937
+ time: time,
2938
+ event: 45 /* Event.StyleSheetAdoption */,
2939
+ data: {
2940
+ id: id,
2941
+ operation: operation,
2942
+ newIds: newIds
2943
+ }
2944
+ });
2945
+ encode$4(45 /* Event.StyleSheetAdoption */);
2946
+ }
2947
+ function arraysEqual(a, b) {
2948
+ if (a.length !== b.length) {
2949
+ return false;
2950
+ }
2951
+ return a.every(function (value, index) { return value === b[index]; });
2952
+ }
2953
+
2954
+ var state$2 = [];
2955
+ var animationPlay = null;
2956
+ var animationPause = null;
2957
+ var animationCancel = null;
2958
+ var animationFinish = null;
2959
+ var animationId = 'clarityAnimationId';
2960
+ var operationCount = 'clarityOperationCount';
2961
+ var maxOperations = 20;
2962
+ function start$i() {
2963
+ if (window["Animation"] &&
2964
+ window["KeyframeEffect"] &&
2965
+ window["KeyframeEffect"].prototype.getKeyframes &&
2966
+ window["KeyframeEffect"].prototype.getTiming) {
2967
+ reset$7();
2968
+ overrideAnimationHelper(animationPlay, "play");
2969
+ overrideAnimationHelper(animationPause, "pause");
2970
+ overrideAnimationHelper(animationCancel, "cancel");
2971
+ overrideAnimationHelper(animationFinish, "finish");
3022
2972
  }
3023
- observers = [];
3024
- history$4 = {};
3025
- mutations = [];
3026
- queue$1 = [];
3027
- activePeriod = 0;
3028
- timeout$1 = null;
3029
2973
  }
3030
- function active$2() {
3031
- activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
2974
+ function reset$7() {
2975
+ state$2 = [];
3032
2976
  }
3033
- function handle$1(m) {
3034
- // Queue up mutation records for asynchronous processing
3035
- var now = time();
3036
- track$7(6 /* Event.Mutation */, now);
3037
- mutations.push({ time: now, mutations: m });
3038
- schedule$1(process$1, 1 /* Priority.High */).then(function () {
3039
- setTimeout(compute$7);
3040
- measure(compute$6)();
2977
+ function track$4(time, id, operation, keyFrames, timing, targetId, timeline) {
2978
+ state$2.push({
2979
+ time: time,
2980
+ event: 44 /* Event.Animation */,
2981
+ data: {
2982
+ id: id,
2983
+ operation: operation,
2984
+ keyFrames: keyFrames,
2985
+ timing: timing,
2986
+ targetId: targetId,
2987
+ timeline: timeline
2988
+ }
3041
2989
  });
2990
+ encode$4(44 /* Event.Animation */);
3042
2991
  }
3043
- function process$1() {
2992
+ function stop$g() {
2993
+ reset$7();
2994
+ }
2995
+ function overrideAnimationHelper(functionToOverride, name) {
2996
+ if (functionToOverride === null) {
2997
+ functionToOverride = Animation.prototype[name];
2998
+ Animation.prototype[name] = function () {
2999
+ if (active()) {
3000
+ var effect = this.effect;
3001
+ var target = getId(this.effect.target);
3002
+ if (target !== null && effect.getKeyframes && effect.getTiming) {
3003
+ if (!this[animationId]) {
3004
+ this[animationId] = shortid();
3005
+ this[operationCount] = 0;
3006
+ var keyframes = effect.getKeyframes();
3007
+ var timing = effect.getTiming();
3008
+ track$4(time(), this[animationId], 0 /* AnimationOperation.Create */, JSON.stringify(keyframes), JSON.stringify(timing), target);
3009
+ }
3010
+ if (this[operationCount]++ < maxOperations) {
3011
+ var operation = null;
3012
+ switch (name) {
3013
+ case "play":
3014
+ operation = 1 /* AnimationOperation.Play */;
3015
+ break;
3016
+ case "pause":
3017
+ operation = 2 /* AnimationOperation.Pause */;
3018
+ break;
3019
+ case "cancel":
3020
+ operation = 3 /* AnimationOperation.Cancel */;
3021
+ break;
3022
+ case "finish":
3023
+ operation = 4 /* AnimationOperation.Finish */;
3024
+ break;
3025
+ }
3026
+ if (operation) {
3027
+ track$4(time(), this[animationId], operation);
3028
+ }
3029
+ }
3030
+ }
3031
+ }
3032
+ return functionToOverride.apply(this, arguments);
3033
+ };
3034
+ }
3035
+ }
3036
+
3037
+ function encode$4 (type, timer, ts) {
3038
+ if (timer === void 0) { timer = null; }
3039
+ if (ts === void 0) { ts = null; }
3044
3040
  return __awaiter(this, void 0, void 0, function () {
3045
- var timer, record, instance, _i, _a, mutation, state, target, type, value;
3046
- return __generator(this, function (_b) {
3047
- switch (_b.label) {
3041
+ var eventTime, tokens, _a, d, _i, _b, r, _c, _d, entry, _e, _f, entry, _g, _h, entry, values, _j, values_1, value, state, data, active, suspend, privacy, mangle, keys, _k, keys_1, key, box, factor, attr;
3042
+ return __generator(this, function (_l) {
3043
+ switch (_l.label) {
3048
3044
  case 0:
3049
- timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
3050
- start$x(timer);
3051
- _b.label = 1;
3045
+ eventTime = ts || time();
3046
+ tokens = [eventTime, type];
3047
+ _a = type;
3048
+ switch (_a) {
3049
+ case 8 /* Event.Document */: return [3 /*break*/, 1];
3050
+ case 7 /* Event.Region */: return [3 /*break*/, 2];
3051
+ case 45 /* Event.StyleSheetAdoption */: return [3 /*break*/, 3];
3052
+ case 46 /* Event.StyleSheetUpdate */: return [3 /*break*/, 4];
3053
+ case 44 /* Event.Animation */: return [3 /*break*/, 5];
3054
+ case 5 /* Event.Discover */: return [3 /*break*/, 6];
3055
+ case 6 /* Event.Mutation */: return [3 /*break*/, 6];
3056
+ }
3057
+ return [3 /*break*/, 13];
3052
3058
  case 1:
3053
- if (!(mutations.length > 0)) return [3 /*break*/, 8];
3054
- record = mutations.shift();
3055
- instance = time();
3056
- _i = 0, _a = record.mutations;
3057
- _b.label = 2;
3059
+ d = data$c;
3060
+ tokens.push(d.width);
3061
+ tokens.push(d.height);
3062
+ track$8(type, d.width, d.height);
3063
+ queue(tokens);
3064
+ return [3 /*break*/, 13];
3058
3065
  case 2:
3059
- if (!(_i < _a.length)) return [3 /*break*/, 6];
3060
- mutation = _a[_i];
3061
- state = state$a(timer);
3062
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
3063
- return [4 /*yield*/, suspend$1(timer)];
3066
+ for (_i = 0, _b = state$1; _i < _b.length; _i++) {
3067
+ r = _b[_i];
3068
+ tokens = [r.time, 7 /* Event.Region */];
3069
+ tokens.push(r.data.id);
3070
+ tokens.push(r.data.interaction);
3071
+ tokens.push(r.data.visibility);
3072
+ tokens.push(r.data.name);
3073
+ queue(tokens);
3074
+ }
3075
+ reset$6();
3076
+ return [3 /*break*/, 13];
3064
3077
  case 3:
3065
- state = _b.sent();
3066
- _b.label = 4;
3067
- case 4:
3068
- if (state === 2 /* Task.Stop */) {
3069
- return [3 /*break*/, 6];
3078
+ for (_c = 0, _d = state$3; _c < _d.length; _c++) {
3079
+ entry = _d[_c];
3080
+ tokens = [entry.time, entry.event];
3081
+ tokens.push(entry.data.id);
3082
+ tokens.push(entry.data.operation);
3083
+ tokens.push(entry.data.newIds);
3084
+ queue(tokens);
3070
3085
  }
3071
- target = mutation.target;
3072
- type = track$3(mutation, timer, instance);
3073
- if (type && target && target.ownerDocument) {
3074
- parse$1(target.ownerDocument);
3086
+ reset$8();
3087
+ return [3 /*break*/, 13];
3088
+ case 4:
3089
+ for (_e = 0, _f = state$3; _e < _f.length; _e++) {
3090
+ entry = _f[_e];
3091
+ tokens = [entry.time, entry.event];
3092
+ tokens.push(entry.data.id);
3093
+ tokens.push(entry.data.operation);
3094
+ tokens.push(entry.data.cssRules);
3095
+ queue(tokens);
3075
3096
  }
3076
- if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
3077
- parse$1(target);
3097
+ reset$8();
3098
+ _l.label = 5;
3099
+ case 5:
3100
+ for (_g = 0, _h = state$2; _g < _h.length; _g++) {
3101
+ entry = _h[_g];
3102
+ tokens = [entry.time, entry.event];
3103
+ tokens.push(entry.data.id);
3104
+ tokens.push(entry.data.operation);
3105
+ tokens.push(entry.data.keyFrames);
3106
+ tokens.push(entry.data.timing);
3107
+ tokens.push(entry.data.timeline);
3108
+ tokens.push(entry.data.targetId);
3109
+ queue(tokens);
3078
3110
  }
3079
- switch (type) {
3080
- case "attributes" /* Constant.Attributes */:
3081
- processNode(target, 3 /* Source.Attributes */);
3082
- break;
3083
- case "characterData" /* Constant.CharacterData */:
3084
- processNode(target, 4 /* Source.CharacterData */);
3085
- break;
3086
- case "childList" /* Constant.ChildList */:
3087
- processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer);
3088
- processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer);
3089
- break;
3090
- case "suspend" /* Constant.Suspend */:
3091
- value = get(target);
3092
- if (value) {
3093
- value.metadata.suspend = true;
3094
- }
3095
- break;
3111
+ reset$7();
3112
+ return [3 /*break*/, 13];
3113
+ case 6:
3114
+ // Check if we are operating within the context of the current page
3115
+ if (state$b(timer) === 2 /* Task.Stop */) {
3116
+ return [3 /*break*/, 13];
3096
3117
  }
3097
- _b.label = 5;
3098
- case 5:
3099
- _i++;
3100
- return [3 /*break*/, 2];
3101
- case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
3118
+ values = updates$2();
3119
+ if (!(values.length > 0)) return [3 /*break*/, 12];
3120
+ _j = 0, values_1 = values;
3121
+ _l.label = 7;
3102
3122
  case 7:
3103
- _b.sent();
3104
- return [3 /*break*/, 1];
3123
+ if (!(_j < values_1.length)) return [3 /*break*/, 11];
3124
+ value = values_1[_j];
3125
+ state = state$b(timer);
3126
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 9];
3127
+ return [4 /*yield*/, suspend$1(timer)];
3105
3128
  case 8:
3106
- stop$v(timer);
3107
- return [2 /*return*/];
3108
- }
3109
- });
3110
- });
3111
- }
3112
- function track$3(m, timer, instance) {
3113
- var value = m.target ? get(m.target.parentNode) : null;
3114
- // Check if the parent is already discovered and that the parent is not the document root
3115
- if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
3116
- var inactive = time() > activePeriod;
3117
- var target = get(m.target);
3118
- var element = target && target.selector ? target.selector.join() : m.target.nodeName;
3119
- var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
3120
- // We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
3121
- // repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
3122
- // In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
3123
- var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
3124
- // Initialize an entry if it doesn't already exist
3125
- history$4[key] = key in history$4 ? history$4[key] : [0, instance];
3126
- var h = history$4[key];
3127
- // Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
3128
- if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
3129
- processNodeList(h[2], 2 /* Source.ChildListRemove */, timer);
3130
- }
3131
- // Update the counter
3132
- h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
3133
- h[1] = instance;
3134
- // Return updated mutation type based on if we have already hit the threshold or not
3135
- if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
3136
- // Store a reference to removedNodes so we can process them later
3137
- // when we resume mutations again on user interactions
3138
- h[2] = m.removedNodes;
3139
- return "suspend" /* Constant.Suspend */;
3129
+ state = _l.sent();
3130
+ _l.label = 9;
3131
+ case 9:
3132
+ if (state === 2 /* Task.Stop */) {
3133
+ return [3 /*break*/, 11];
3134
+ }
3135
+ data = value.data;
3136
+ active = value.metadata.active;
3137
+ suspend = value.metadata.suspend;
3138
+ privacy = value.metadata.privacy;
3139
+ mangle = shouldMangle(value);
3140
+ keys = active ? ["tag", "attributes", "value"] : ["tag"];
3141
+ for (_k = 0, keys_1 = keys; _k < keys_1.length; _k++) {
3142
+ key = keys_1[_k];
3143
+ if (data[key]) {
3144
+ switch (key) {
3145
+ case "tag":
3146
+ box = size(value);
3147
+ factor = mangle ? -1 : 1;
3148
+ tokens.push(value.id * factor);
3149
+ if (value.parent && active) {
3150
+ tokens.push(value.parent);
3151
+ }
3152
+ if (value.previous && active) {
3153
+ tokens.push(value.previous);
3154
+ }
3155
+ tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
3156
+ if (box && box.length === 2) {
3157
+ tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
3158
+ }
3159
+ break;
3160
+ case "attributes":
3161
+ for (attr in data[key]) {
3162
+ if (data[key][attr] !== undefined) {
3163
+ tokens.push(attribute(attr, data[key][attr], privacy));
3164
+ }
3165
+ }
3166
+ break;
3167
+ case "value":
3168
+ check$4(value.metadata.fraud, value.id, data[key]);
3169
+ tokens.push(text$1(data[key], data.tag, privacy, mangle));
3170
+ break;
3171
+ }
3172
+ }
3173
+ }
3174
+ _l.label = 10;
3175
+ case 10:
3176
+ _j++;
3177
+ return [3 /*break*/, 7];
3178
+ case 11:
3179
+ if (type === 6 /* Event.Mutation */) {
3180
+ activity(eventTime);
3181
+ }
3182
+ queue(tokenize(tokens), !config$1.lean);
3183
+ _l.label = 12;
3184
+ case 12: return [3 /*break*/, 13];
3185
+ case 13: return [2 /*return*/];
3186
+ }
3187
+ });
3188
+ });
3189
+ }
3190
+ function shouldMangle(value) {
3191
+ var privacy = value.metadata.privacy;
3192
+ return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
3193
+ }
3194
+ function size(value) {
3195
+ if (value.metadata.size !== null && value.metadata.size.length === 0) {
3196
+ var img = getNode(value.id);
3197
+ if (img) {
3198
+ return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
3140
3199
  }
3141
- else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
3142
- return "" /* Constant.Empty */;
3200
+ }
3201
+ return value.metadata.size;
3202
+ }
3203
+ function str$1(input) {
3204
+ return input.toString(36);
3205
+ }
3206
+ function attribute(key, value, privacy) {
3207
+ return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
3208
+ }
3209
+
3210
+ var state$1 = [];
3211
+ var regionMap = null; // Maps region nodes => region name
3212
+ var regions = {};
3213
+ var queue$1 = [];
3214
+ var watch = false;
3215
+ var observer$1 = null;
3216
+ function start$h() {
3217
+ reset$6();
3218
+ observer$1 = null;
3219
+ regionMap = new WeakMap();
3220
+ regions = {};
3221
+ queue$1 = [];
3222
+ watch = window["IntersectionObserver"] ? true : false;
3223
+ }
3224
+ function observe$1(node, name) {
3225
+ if (regionMap.has(node) === false) {
3226
+ regionMap.set(node, name);
3227
+ observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$1, {
3228
+ // Get notified as intersection continues to change
3229
+ // This allows us to process regions that get partially hidden during the lifetime of the page
3230
+ // See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
3231
+ // By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
3232
+ threshold: [0, 0.2, 0.4, 0.6, 0.8, 1]
3233
+ }) : observer$1;
3234
+ if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
3235
+ observer$1.observe(node);
3143
3236
  }
3144
3237
  }
3145
- return m.type;
3146
3238
  }
3147
- function names(nodes) {
3148
- var output = [];
3149
- for (var i = 0; nodes && i < nodes.length; i++) {
3150
- output.push(nodes[i].nodeName);
3239
+ function exists(node) {
3240
+ // Check if regionMap is not null before looking up a node
3241
+ // Since, dom module stops after region module, it's possible that we may set regionMap to be null
3242
+ // and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
3243
+ return regionMap && regionMap.has(node);
3244
+ }
3245
+ function track$3(id, event) {
3246
+ var node = getNode(id);
3247
+ var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
3248
+ // Determine the interaction state based on incoming event
3249
+ var interaction = 16 /* InteractionState.None */;
3250
+ switch (event) {
3251
+ case 9 /* Event.Click */:
3252
+ interaction = 20 /* InteractionState.Clicked */;
3253
+ break;
3254
+ case 27 /* Event.Input */:
3255
+ interaction = 30 /* InteractionState.Input */;
3256
+ break;
3151
3257
  }
3152
- return output.join();
3258
+ // Process updates to this region, if applicable
3259
+ process$1(node, data, interaction, data.visibility);
3153
3260
  }
3154
- function processNodeList(list, source, timer) {
3155
- return __awaiter(this, void 0, void 0, function () {
3156
- var length, i, state;
3157
- return __generator(this, function (_a) {
3158
- switch (_a.label) {
3159
- case 0:
3160
- length = list ? list.length : 0;
3161
- i = 0;
3162
- _a.label = 1;
3163
- case 1:
3164
- if (!(i < length)) return [3 /*break*/, 6];
3165
- if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
3166
- traverse(list[i], timer, source);
3167
- return [3 /*break*/, 5];
3168
- case 2:
3169
- state = state$a(timer);
3170
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
3171
- return [4 /*yield*/, suspend$1(timer)];
3172
- case 3:
3173
- state = _a.sent();
3174
- _a.label = 4;
3175
- case 4:
3176
- if (state === 2 /* Task.Stop */) {
3177
- return [3 /*break*/, 6];
3178
- }
3179
- processNode(list[i], source);
3180
- _a.label = 5;
3181
- case 5:
3182
- i++;
3183
- return [3 /*break*/, 1];
3184
- case 6: return [2 /*return*/];
3261
+ function compute$6() {
3262
+ // Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
3263
+ // This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
3264
+ // For those cases we add them to the queue and re-process them below
3265
+ var q = [];
3266
+ for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
3267
+ var r = queue_1[_i];
3268
+ var id = getId(r.node);
3269
+ if (!(id in regions)) {
3270
+ if (id) {
3271
+ r.data.id = id;
3272
+ regions[id] = r.data;
3273
+ state$1.push(clone$1(r.data));
3185
3274
  }
3186
- });
3187
- });
3188
- }
3189
- function schedule(node) {
3190
- // Only schedule manual trigger for this node if it's not already in the queue
3191
- if (queue$1.indexOf(node) < 0) {
3192
- queue$1.push(node);
3275
+ else {
3276
+ q.push(r);
3277
+ }
3278
+ }
3193
3279
  }
3194
- // Cancel any previous trigger before scheduling a new one.
3195
- // It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
3196
- // And in those cases we do not wish to monitor changes multiple times for the same node.
3197
- if (timeout$1) {
3198
- clearTimeout(timeout$1);
3280
+ queue$1 = q;
3281
+ // Schedule encode only when we have at least one valid data entry
3282
+ if (state$1.length > 0) {
3283
+ encode$4(7 /* Event.Region */);
3199
3284
  }
3200
- timeout$1 = setTimeout(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
3201
- return node;
3202
3285
  }
3203
- function trigger$2() {
3204
- for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
3205
- var node = queue_1[_i];
3206
- // Generate a mutation for this node only if it still exists
3207
- if (node) {
3208
- var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
3209
- // Skip re-processing shadowRoot if it was already discovered
3210
- if (shadowRoot && has(node)) {
3211
- continue;
3286
+ function handler$1(entries) {
3287
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
3288
+ var entry = entries_1[_i];
3289
+ var target = entry.target;
3290
+ var rect = entry.boundingClientRect;
3291
+ var overlap = entry.intersectionRect;
3292
+ var viewport = entry.rootBounds;
3293
+ // Only capture regions that have non-zero width or height to avoid tracking and sending regions
3294
+ // that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
3295
+ // like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
3296
+ // Also, if these regions ever become non-zero width or height (through AJAX, user action or orientation change) - we will automatically start monitoring them from that point onwards
3297
+ if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
3298
+ var id = target ? getId(target) : null;
3299
+ var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
3300
+ // For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
3301
+ // However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
3302
+ var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
3303
+ var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
3304
+ // If an element is either visible or was visible and has been scrolled to the end
3305
+ // i.e. Scrolled to end is determined by if the starting position of the element + the window height is more than the total element height.
3306
+ // starting position is relative to the viewport - so Intersection observer returns a negative value for rect.top to indicate that the element top is above the viewport
3307
+ var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
3308
+ // Process updates to this region, if applicable
3309
+ process$1(target, data, data.interaction, (scrolledToEnd ?
3310
+ 13 /* RegionVisibility.ScrolledToEnd */ :
3311
+ (visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
3312
+ // Stop observing this element now that we have already received scrolled signal
3313
+ if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
3314
+ observer$1.unobserve(target);
3212
3315
  }
3213
- generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
3214
3316
  }
3215
3317
  }
3216
- queue$1 = [];
3318
+ if (state$1.length > 0) {
3319
+ encode$4(7 /* Event.Region */);
3320
+ }
3217
3321
  }
3218
- function generate(target, type) {
3219
- measure(handle$1)([{
3220
- addedNodes: [target],
3221
- attributeName: null,
3222
- attributeNamespace: null,
3223
- nextSibling: null,
3224
- oldValue: null,
3225
- previousSibling: null,
3226
- removedNodes: [],
3227
- target: target,
3228
- type: type
3229
- }]);
3322
+ function process$1(n, d, s, v) {
3323
+ // Check if received a state that supersedes existing state
3324
+ var updated = s > d.interaction || v > d.visibility;
3325
+ d.interaction = s > d.interaction ? s : d.interaction;
3326
+ d.visibility = v > d.visibility ? v : d.visibility;
3327
+ // If the corresponding node is already discovered, update the internal state
3328
+ // Otherwise, track it in a queue to reprocess later.
3329
+ if (d.id) {
3330
+ if ((d.id in regions && updated) || !(d.id in regions)) {
3331
+ regions[d.id] = d;
3332
+ state$1.push(clone$1(d));
3333
+ }
3334
+ }
3335
+ else {
3336
+ queue$1.push({ node: n, data: d });
3337
+ }
3338
+ }
3339
+ function clone$1(r) {
3340
+ return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
3341
+ }
3342
+ function reset$6() {
3343
+ state$1 = [];
3344
+ }
3345
+ function stop$f() {
3346
+ reset$6();
3347
+ regionMap = null;
3348
+ regions = {};
3349
+ queue$1 = [];
3350
+ if (observer$1) {
3351
+ observer$1.disconnect();
3352
+ observer$1 = null;
3353
+ }
3354
+ watch = false;
3230
3355
  }
3231
3356
 
3232
3357
  function target(evt) {
@@ -3247,7 +3372,7 @@ function metadata$2(node, event, text) {
3247
3372
  output.hash = value.hash;
3248
3373
  output.privacy = metadata_1.privacy;
3249
3374
  if (value.region) {
3250
- track$4(value.region, event);
3375
+ track$3(value.region, event);
3251
3376
  }
3252
3377
  if (metadata_1.fraud) {
3253
3378
  check$4(metadata_1.fraud, value.id, text || value.data.value);
@@ -3274,7 +3399,7 @@ function encode$3 (type, ts) {
3274
3399
  case 18 /* Event.TouchEnd */:
3275
3400
  case 19 /* Event.TouchMove */:
3276
3401
  case 20 /* Event.TouchCancel */:
3277
- for (_i = 0, _a = state$3; _i < _a.length; _i++) {
3402
+ for (_i = 0, _a = state$6; _i < _a.length; _i++) {
3278
3403
  entry = _a[_i];
3279
3404
  pTarget = metadata$2(entry.data.target, entry.event);
3280
3405
  if (pTarget.id > 0) {
@@ -3286,10 +3411,10 @@ function encode$3 (type, ts) {
3286
3411
  track$8(entry.event, entry.data.x, entry.data.y);
3287
3412
  }
3288
3413
  }
3289
- reset$c();
3414
+ reset$f();
3290
3415
  break;
3291
3416
  case 9 /* Event.Click */:
3292
- for (_b = 0, _c = state$6; _b < _c.length; _b++) {
3417
+ for (_b = 0, _c = state$9; _b < _c.length; _b++) {
3293
3418
  entry = _c[_b];
3294
3419
  cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
3295
3420
  tokens = [entry.time, entry.event];
@@ -3309,10 +3434,10 @@ function encode$3 (type, ts) {
3309
3434
  queue(tokens);
3310
3435
  track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
3311
3436
  }
3312
- reset$f();
3437
+ reset$i();
3313
3438
  break;
3314
3439
  case 38 /* Event.Clipboard */:
3315
- for (_d = 0, _e = state$5; _d < _e.length; _d++) {
3440
+ for (_d = 0, _e = state$8; _d < _e.length; _d++) {
3316
3441
  entry = _e[_d];
3317
3442
  tokens = [entry.time, entry.event];
3318
3443
  target = metadata$2(entry.data.target, entry.event);
@@ -3322,24 +3447,24 @@ function encode$3 (type, ts) {
3322
3447
  queue(tokens);
3323
3448
  }
3324
3449
  }
3325
- reset$e();
3450
+ reset$h();
3326
3451
  break;
3327
3452
  case 11 /* Event.Resize */:
3328
3453
  r = data$b;
3329
3454
  tokens.push(r.width);
3330
3455
  tokens.push(r.height);
3331
3456
  track$8(type, r.width, r.height);
3332
- reset$b();
3457
+ reset$e();
3333
3458
  queue(tokens);
3334
3459
  break;
3335
3460
  case 26 /* Event.Unload */:
3336
3461
  u = data$9;
3337
3462
  tokens.push(u.name);
3338
- reset$7();
3463
+ reset$a();
3339
3464
  queue(tokens);
3340
3465
  break;
3341
3466
  case 27 /* Event.Input */:
3342
- for (_f = 0, _g = state$4; _f < _g.length; _f++) {
3467
+ for (_f = 0, _g = state$7; _f < _g.length; _f++) {
3343
3468
  entry = _g[_f];
3344
3469
  iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
3345
3470
  tokens = [entry.time, entry.event];
@@ -3347,7 +3472,7 @@ function encode$3 (type, ts) {
3347
3472
  tokens.push(text$1(entry.data.value, "input", iTarget.privacy));
3348
3473
  queue(tokens);
3349
3474
  }
3350
- reset$d();
3475
+ reset$g();
3351
3476
  break;
3352
3477
  case 21 /* Event.Selection */:
3353
3478
  s = data$a;
@@ -3358,12 +3483,12 @@ function encode$3 (type, ts) {
3358
3483
  tokens.push(s.startOffset);
3359
3484
  tokens.push(endTarget.id);
3360
3485
  tokens.push(s.endOffset);
3361
- reset$9();
3486
+ reset$c();
3362
3487
  queue(tokens);
3363
3488
  }
3364
3489
  break;
3365
3490
  case 10 /* Event.Scroll */:
3366
- for (_h = 0, _j = state$2; _h < _j.length; _h++) {
3491
+ for (_h = 0, _j = state$5; _h < _j.length; _h++) {
3367
3492
  entry = _j[_h];
3368
3493
  sTarget = metadata$2(entry.data.target, entry.event);
3369
3494
  if (sTarget.id > 0) {
@@ -3375,10 +3500,10 @@ function encode$3 (type, ts) {
3375
3500
  track$8(entry.event, entry.data.x, entry.data.y);
3376
3501
  }
3377
3502
  }
3378
- reset$a();
3503
+ reset$d();
3379
3504
  break;
3380
3505
  case 42 /* Event.Change */:
3381
- for (_k = 0, _l = state$7; _k < _l.length; _k++) {
3506
+ for (_k = 0, _l = state$a; _k < _l.length; _k++) {
3382
3507
  entry = _l[_k];
3383
3508
  tokens = [entry.time, entry.event];
3384
3509
  target = metadata$2(entry.data.target, entry.event);
@@ -3391,10 +3516,10 @@ function encode$3 (type, ts) {
3391
3516
  queue(tokens);
3392
3517
  }
3393
3518
  }
3394
- reset$g();
3519
+ reset$j();
3395
3520
  break;
3396
3521
  case 39 /* Event.Submit */:
3397
- for (_m = 0, _o = state$1; _m < _o.length; _m++) {
3522
+ for (_m = 0, _o = state$4; _m < _o.length; _m++) {
3398
3523
  entry = _o[_m];
3399
3524
  tokens = [entry.time, entry.event];
3400
3525
  target = metadata$2(entry.data.target, entry.event);
@@ -3403,7 +3528,7 @@ function encode$3 (type, ts) {
3403
3528
  queue(tokens);
3404
3529
  }
3405
3530
  }
3406
- reset$8();
3531
+ reset$b();
3407
3532
  break;
3408
3533
  case 22 /* Event.Timeline */:
3409
3534
  for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
@@ -3424,7 +3549,7 @@ function encode$3 (type, ts) {
3424
3549
  tokens.push(v.visible);
3425
3550
  queue(tokens);
3426
3551
  visibility(t, v.visible);
3427
- reset$6();
3552
+ reset$9();
3428
3553
  break;
3429
3554
  }
3430
3555
  return [2 /*return*/];
@@ -3514,6 +3639,8 @@ function queue(tokens, transmit) {
3514
3639
  case 37 /* Event.Box */:
3515
3640
  case 6 /* Event.Mutation */:
3516
3641
  case 43 /* Event.Snapshot */:
3642
+ case 45 /* Event.StyleSheetAdoption */:
3643
+ case 46 /* Event.StyleSheetUpdate */:
3517
3644
  playbackBytes += event_1.length;
3518
3645
  playback.push(event_1);
3519
3646
  break;
@@ -3536,7 +3663,7 @@ function queue(tokens, transmit) {
3536
3663
  // We enrich the data going out with the existing upload. In these cases, call to upload comes with 'transmit' set to false.
3537
3664
  if (transmit && timeout === null) {
3538
3665
  if (type !== 25 /* Event.Ping */) {
3539
- reset$p();
3666
+ reset$q();
3540
3667
  }
3541
3668
  timeout = setTimeout(upload, gap);
3542
3669
  queuedTime = now;
@@ -3572,7 +3699,8 @@ function upload(final) {
3572
3699
  // Otherwise you run a risk of infinite loop.
3573
3700
  compute$6();
3574
3701
  compute$5();
3575
- compute$8();
3702
+ compute$9();
3703
+ compute$7();
3576
3704
  last = final === true;
3577
3705
  e = JSON.stringify(envelope(last));
3578
3706
  a = "[".concat(analysis.join(), "]");
@@ -4040,7 +4168,7 @@ function encode$1 (event) {
4040
4168
  var tokens = [t, event];
4041
4169
  switch (event) {
4042
4170
  case 4 /* Event.Baseline */:
4043
- var b = state$b;
4171
+ var b = state$c;
4044
4172
  if (b) {
4045
4173
  tokens = [b.time, b.event];
4046
4174
  tokens.push(b.data.visible);
@@ -4055,7 +4183,7 @@ function encode$1 (event) {
4055
4183
  tokens.push(b.data.activityTime);
4056
4184
  queue(tokens, false);
4057
4185
  }
4058
- reset$r();
4186
+ reset$s();
4059
4187
  break;
4060
4188
  case 25 /* Event.Ping */:
4061
4189
  tokens.push(data$h.gap);
@@ -4089,7 +4217,7 @@ function encode$1 (event) {
4089
4217
  tokens.push(v);
4090
4218
  tokens.push(data$e[v]);
4091
4219
  }
4092
- reset$n();
4220
+ reset$o();
4093
4221
  queue(tokens, false);
4094
4222
  }
4095
4223
  break;
@@ -4104,7 +4232,7 @@ function encode$1 (event) {
4104
4232
  // However, for data over the wire, we round it off to milliseconds precision.
4105
4233
  tokens.push(Math.round(updates$3[m]));
4106
4234
  }
4107
- reset$q();
4235
+ reset$r();
4108
4236
  queue(tokens, false);
4109
4237
  }
4110
4238
  break;
@@ -4130,7 +4258,7 @@ function encode$1 (event) {
4130
4258
  tokens.push(key);
4131
4259
  tokens.push([].concat.apply([], data$g[e]));
4132
4260
  }
4133
- reset$o();
4261
+ reset$p();
4134
4262
  queue(tokens, false);
4135
4263
  }
4136
4264
  break;
@@ -4699,8 +4827,8 @@ function stop$6() {
4699
4827
  var status = false;
4700
4828
  function start$6() {
4701
4829
  status = true;
4702
- start$H();
4703
- reset$k();
4830
+ start$I();
4831
+ reset$l();
4704
4832
  reset$1();
4705
4833
  reset$2();
4706
4834
  start$7();
@@ -4709,8 +4837,8 @@ function stop$5() {
4709
4837
  stop$6();
4710
4838
  reset$2();
4711
4839
  reset$1();
4712
- reset$k();
4713
- stop$E();
4840
+ reset$l();
4841
+ stop$F();
4714
4842
  status = false;
4715
4843
  }
4716
4844
  function active() {
@@ -4764,7 +4892,7 @@ function restart() {
4764
4892
  }
4765
4893
 
4766
4894
  function start$5() {
4767
- start$z();
4895
+ start$A();
4768
4896
  start$e();
4769
4897
  start$d();
4770
4898
  }
@@ -4780,7 +4908,7 @@ var diagnostic = /*#__PURE__*/Object.freeze({
4780
4908
 
4781
4909
  function start$4() {
4782
4910
  schedule$1(discover, 1 /* Priority.High */).then(function () {
4783
- measure(compute$7)();
4911
+ measure(compute$8)();
4784
4912
  measure(compute$6)();
4785
4913
  });
4786
4914
  }
@@ -4792,14 +4920,15 @@ function discover() {
4792
4920
  case 0:
4793
4921
  ts = time();
4794
4922
  timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
4795
- start$x(timer);
4923
+ start$y(timer);
4796
4924
  return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */)];
4797
4925
  case 1:
4798
4926
  _a.sent();
4927
+ checkDocumentStyles(document);
4799
4928
  return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
4800
4929
  case 2:
4801
4930
  _a.sent();
4802
- stop$v(timer);
4931
+ stop$w(timer);
4803
4932
  return [2 /*return*/];
4804
4933
  }
4805
4934
  });
@@ -4809,19 +4938,21 @@ function discover() {
4809
4938
  function start$3() {
4810
4939
  // The order below is important
4811
4940
  // and is determined by interdependencies of modules
4812
- start$w();
4813
- start$u();
4814
- start$y();
4941
+ start$x();
4815
4942
  start$h();
4943
+ start$z();
4944
+ start$k();
4816
4945
  start$4();
4817
- start$v();
4946
+ start$j();
4947
+ start$i();
4818
4948
  }
4819
4949
  function stop$3() {
4820
- stop$s();
4821
- stop$w();
4822
4950
  stop$f();
4823
- stop$u();
4824
- stop$t();
4951
+ stop$x();
4952
+ stop$i();
4953
+ stop$v();
4954
+ stop$h();
4955
+ stop$g();
4825
4956
  }
4826
4957
 
4827
4958
  var layout = /*#__PURE__*/Object.freeze({
@@ -5015,7 +5146,7 @@ function start(config$1) {
5015
5146
  if (check()) {
5016
5147
  config(config$1);
5017
5148
  start$6();
5018
- start$A();
5149
+ start$B();
5019
5150
  modules.forEach(function (x) { return measure(x.start)(); });
5020
5151
  // If it's an internal call to start, without explicit configuration,
5021
5152
  // re-process any newly accumulated items in the queue
@@ -5046,7 +5177,7 @@ function stop() {
5046
5177
  if (active()) {
5047
5178
  // Stop modules in the reverse order of their initialization and start queuing up items again
5048
5179
  modules.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
5049
- stop$x();
5180
+ stop$y();
5050
5181
  stop$5();
5051
5182
  setup();
5052
5183
  }