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