clarity-js 0.7.43 → 0.7.44

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.
@@ -161,7 +161,7 @@ function stop$F() {
161
161
  startTime = 0;
162
162
  }
163
163
 
164
- var version$1 = "0.7.43";
164
+ var version$1 = "0.7.44";
165
165
 
166
166
  // tslint:disable: no-bitwise
167
167
  function hash (input, precision) {
@@ -1093,7 +1093,7 @@ function parse$1(root, init) {
1093
1093
  // Since mutations may happen on leaf nodes too, e.g. text nodes, which may not support all selector APIs.
1094
1094
  // We ensure that the root note supports querySelectorAll API before executing the code below to identify new regions.
1095
1095
  if ("querySelectorAll" in root) {
1096
- config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$c(e, "".concat(x[0])); }); }); // Regions
1096
+ config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
1097
1097
  config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
1098
1098
  config$1.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
1099
1099
  unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
@@ -1132,7 +1132,7 @@ function add(node, parent, data, source) {
1132
1132
  }
1133
1133
  // If there's an explicit region attribute set on the element, use it to mark a region on the page
1134
1134
  if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
1135
- observe$c(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
1135
+ observe$1(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
1136
1136
  regionId = id;
1137
1137
  }
1138
1138
  nodesMap.set(id, node);
@@ -1700,507 +1700,252 @@ function stop$v() {
1700
1700
  reset$k();
1701
1701
  }
1702
1702
 
1703
- var sheetAdoptionState = [];
1704
- var sheetUpdateState = [];
1705
- var replace = null;
1706
- var replaceSync = null;
1703
+ var state$9 = [];
1707
1704
  function start$w() {
1708
- if (replace === null) {
1709
- replace = CSSStyleSheet.prototype.replace;
1710
- CSSStyleSheet.prototype.replace = function () {
1711
- if (active()) {
1712
- max(36 /* Metric.ConstructedStyles */, 1);
1713
- }
1714
- return replace.apply(this, arguments);
1715
- };
1716
- }
1717
- if (replaceSync === null) {
1718
- replaceSync = CSSStyleSheet.prototype.replaceSync;
1719
- CSSStyleSheet.prototype.replaceSync = function () {
1720
- if (active()) {
1721
- max(36 /* Metric.ConstructedStyles */, 1);
1722
- }
1723
- return replaceSync.apply(this, arguments);
1724
- };
1725
- }
1705
+ reset$j();
1726
1706
  }
1727
- function checkDocumentStyles(documentNode) {
1728
- if (!(documentNode === null || documentNode === void 0 ? void 0 : documentNode.adoptedStyleSheets)) {
1729
- // if we don't have adoptedStyledSheets on the Node passed to us, we can short circuit.
1730
- return;
1731
- }
1732
- max(36 /* Metric.ConstructedStyles */, 1);
1707
+ function observe$c(root) {
1708
+ bind(root, "change", recompute$8, true);
1733
1709
  }
1734
- function compute$8() {
1735
- checkDocumentStyles(document);
1710
+ function recompute$8(evt) {
1711
+ var element = target(evt);
1712
+ if (element) {
1713
+ var value = element.value;
1714
+ 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 */;
1715
+ state$9.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
1716
+ schedule$1(encode$3.bind(this, 42 /* Event.Change */));
1717
+ }
1736
1718
  }
1737
1719
  function reset$j() {
1738
- sheetAdoptionState = [];
1739
- sheetUpdateState = [];
1720
+ state$9 = [];
1740
1721
  }
1741
1722
  function stop$u() {
1742
1723
  reset$j();
1743
1724
  }
1744
1725
 
1745
- var state$9 = [];
1746
- var elementAnimate = null;
1747
- var animationPlay = null;
1748
- var animationPause = null;
1749
- var animationCancel = null;
1750
- var animationFinish = null;
1751
- var animationId = 'clarityAnimationId';
1752
- var operationCount = 'clarityOperationCount';
1753
- var maxOperations = 20;
1726
+ function offset(element) {
1727
+ var output = { x: 0, y: 0 };
1728
+ // Walk up the chain to ensure we compute offset distance correctly
1729
+ // In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
1730
+ if (element && element.offsetParent) {
1731
+ do {
1732
+ var parent_1 = element.offsetParent;
1733
+ var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
1734
+ output.x += element.offsetLeft;
1735
+ output.y += element.offsetTop;
1736
+ element = frame ? frame : parent_1;
1737
+ } while (element);
1738
+ }
1739
+ return output;
1740
+ }
1741
+
1742
+ var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
1743
+ var state$8 = [];
1754
1744
  function start$v() {
1755
- if (window["Animation"] &&
1756
- window["KeyframeEffect"] &&
1757
- window["KeyframeEffect"].prototype.getKeyframes &&
1758
- window["KeyframeEffect"].prototype.getTiming) {
1759
- reset$i();
1760
- overrideAnimationHelper(animationPlay, "play");
1761
- overrideAnimationHelper(animationPause, "pause");
1762
- overrideAnimationHelper(animationCancel, "cancel");
1763
- overrideAnimationHelper(animationFinish, "finish");
1764
- if (elementAnimate === null) {
1765
- elementAnimate = Element.prototype.animate;
1766
- Element.prototype.animate = function () {
1767
- var createdAnimation = elementAnimate.apply(this, arguments);
1768
- trackAnimationOperation(createdAnimation, "play");
1769
- return createdAnimation;
1770
- };
1771
- }
1745
+ reset$i();
1746
+ }
1747
+ function observe$b(root) {
1748
+ bind(root, "click", handler$3.bind(this, 9 /* Event.Click */, root), true);
1749
+ }
1750
+ function handler$3(event, root, evt) {
1751
+ var frame = iframe(root);
1752
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1753
+ var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
1754
+ var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
1755
+ // In case of iframe, we adjust (x,y) to be relative to top parent's origin
1756
+ if (frame) {
1757
+ var distance = offset(frame);
1758
+ x = x ? x + Math.round(distance.x) : x;
1759
+ y = y ? y + Math.round(distance.y) : y;
1760
+ }
1761
+ var t = target(evt);
1762
+ // Find nearest anchor tag (<a/>) parent if current target node is part of one
1763
+ // If present, we use the returned link element to populate text and link properties below
1764
+ var a = link(t);
1765
+ // Get layout rectangle for the target element
1766
+ var l = layout$1(t);
1767
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
1768
+ // This property helps differentiate between a keyboard navigation vs. pointer click
1769
+ // In case of a keyboard navigation, we use center of target element as (x,y)
1770
+ if (evt.detail === 0 && l) {
1771
+ x = Math.round(l.x + (l.w / 2));
1772
+ y = Math.round(l.y + (l.h / 2));
1773
+ }
1774
+ var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
1775
+ var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
1776
+ // Check for null values before processing this event
1777
+ if (x !== null && y !== null) {
1778
+ state$8.push({
1779
+ time: time(evt),
1780
+ event: event,
1781
+ data: {
1782
+ target: t,
1783
+ x: x,
1784
+ y: y,
1785
+ eX: eX,
1786
+ eY: eY,
1787
+ button: evt.button,
1788
+ reaction: reaction(t),
1789
+ context: context(a),
1790
+ text: text(t),
1791
+ link: a ? a.href : null,
1792
+ hash: null,
1793
+ trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
1794
+ }
1795
+ });
1796
+ schedule$1(encode$3.bind(this, event));
1772
1797
  }
1773
1798
  }
1774
- function reset$i() {
1775
- state$9 = [];
1799
+ function link(node) {
1800
+ while (node && node !== document) {
1801
+ if (node.nodeType === Node.ELEMENT_NODE) {
1802
+ var element = node;
1803
+ if (element.tagName === "A") {
1804
+ return element;
1805
+ }
1806
+ }
1807
+ node = node.parentNode;
1808
+ }
1809
+ return null;
1776
1810
  }
1777
- function track$5(time, id, operation, keyFrames, timing, targetId, timeline) {
1778
- state$9.push({
1779
- time: time,
1780
- event: 44 /* Event.Animation */,
1781
- data: {
1782
- id: id,
1783
- operation: operation,
1784
- keyFrames: keyFrames,
1785
- timing: timing,
1786
- targetId: targetId,
1787
- timeline: timeline
1811
+ function text(element) {
1812
+ var output = null;
1813
+ if (element) {
1814
+ // Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
1815
+ var t = element.textContent || String(element.value || '') || element.alt;
1816
+ if (t) {
1817
+ // Replace multiple occurrence of space characters with a single white space
1818
+ // Also, trim any spaces at the beginning or at the end of string
1819
+ // Finally, send only first few characters as specified by the Setting
1820
+ output = t.replace(/\s+/g, " " /* Constant.Space */).trim().substr(0, 25 /* Setting.ClickText */);
1788
1821
  }
1789
- });
1790
- encode$4(44 /* Event.Animation */);
1822
+ }
1823
+ return output;
1791
1824
  }
1792
- function stop$t() {
1793
- reset$i();
1825
+ function reaction(element) {
1826
+ if (element.nodeType === Node.ELEMENT_NODE) {
1827
+ var tag = element.tagName.toLowerCase();
1828
+ if (UserInputTags.indexOf(tag) >= 0) {
1829
+ return 0 /* BooleanFlag.False */;
1830
+ }
1831
+ }
1832
+ return 1 /* BooleanFlag.True */;
1794
1833
  }
1795
- function overrideAnimationHelper(functionToOverride, name) {
1796
- if (functionToOverride === null) {
1797
- functionToOverride = Animation.prototype[name];
1798
- Animation.prototype[name] = function () {
1799
- trackAnimationOperation(this, name);
1800
- return functionToOverride.apply(this, arguments);
1801
- };
1834
+ function layout$1(element) {
1835
+ var box = null;
1836
+ var de = document.documentElement;
1837
+ if (typeof element.getBoundingClientRect === "function") {
1838
+ // getBoundingClientRect returns rectangle relative positioning to viewport
1839
+ var rect = element.getBoundingClientRect();
1840
+ if (rect && rect.width > 0 && rect.height > 0) {
1841
+ // Add viewport's scroll position to rectangle to get position relative to document origin
1842
+ // Also: using Math.floor() instead of Math.round() because in Edge,
1843
+ // getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
1844
+ // floors the value (e.g. 162px). This keeps consistent behavior across browsers.
1845
+ box = {
1846
+ x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
1847
+ y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
1848
+ w: Math.floor(rect.width),
1849
+ h: Math.floor(rect.height)
1850
+ };
1851
+ }
1802
1852
  }
1853
+ return box;
1803
1854
  }
1804
- function trackAnimationOperation(animation, name) {
1805
- if (active()) {
1806
- var effect = animation.effect;
1807
- var target = getId(effect.target);
1808
- if (target !== null && effect.getKeyframes && effect.getTiming) {
1809
- if (!animation[animationId]) {
1810
- animation[animationId] = shortid();
1811
- animation[operationCount] = 0;
1812
- var keyframes = effect.getKeyframes();
1813
- var timing = effect.getTiming();
1814
- track$5(time(), animation[animationId], 0 /* AnimationOperation.Create */, JSON.stringify(keyframes), JSON.stringify(timing), target);
1815
- }
1816
- if (animation[operationCount]++ < maxOperations) {
1817
- var operation = null;
1818
- switch (name) {
1819
- case "play":
1820
- operation = 1 /* AnimationOperation.Play */;
1821
- break;
1822
- case "pause":
1823
- operation = 2 /* AnimationOperation.Pause */;
1824
- break;
1825
- case "cancel":
1826
- operation = 3 /* AnimationOperation.Cancel */;
1827
- break;
1828
- case "finish":
1829
- operation = 4 /* AnimationOperation.Finish */;
1830
- break;
1831
- }
1832
- if (operation) {
1833
- track$5(time(), animation[animationId], operation);
1834
- }
1835
- }
1855
+ function context(a) {
1856
+ if (a && a.hasAttribute("target" /* Constant.Target */)) {
1857
+ switch (a.getAttribute("target" /* Constant.Target */)) {
1858
+ case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
1859
+ case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
1860
+ case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
1836
1861
  }
1837
1862
  }
1863
+ return 0 /* BrowsingContext.Self */;
1864
+ }
1865
+ function reset$i() {
1866
+ state$8 = [];
1867
+ }
1868
+ function stop$t() {
1869
+ reset$i();
1838
1870
  }
1839
1871
 
1840
- function encode$4 (type, timer, ts) {
1841
- if (timer === void 0) { timer = null; }
1842
- if (ts === void 0) { ts = null; }
1843
- return __awaiter(this, void 0, void 0, function () {
1844
- 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;
1845
- return __generator(this, function (_l) {
1846
- switch (_l.label) {
1847
- case 0:
1848
- eventTime = ts || time();
1849
- tokens = [eventTime, type];
1850
- _a = type;
1851
- switch (_a) {
1852
- case 8 /* Event.Document */: return [3 /*break*/, 1];
1853
- case 7 /* Event.Region */: return [3 /*break*/, 2];
1854
- case 45 /* Event.StyleSheetAdoption */: return [3 /*break*/, 3];
1855
- case 46 /* Event.StyleSheetUpdate */: return [3 /*break*/, 3];
1856
- case 44 /* Event.Animation */: return [3 /*break*/, 4];
1857
- case 5 /* Event.Discover */: return [3 /*break*/, 5];
1858
- case 6 /* Event.Mutation */: return [3 /*break*/, 5];
1859
- }
1860
- return [3 /*break*/, 12];
1861
- case 1:
1862
- d = data$c;
1863
- tokens.push(d.width);
1864
- tokens.push(d.height);
1865
- track$8(type, d.width, d.height);
1866
- queue(tokens);
1867
- return [3 /*break*/, 12];
1868
- case 2:
1869
- for (_i = 0, _b = state$8; _i < _b.length; _i++) {
1870
- r = _b[_i];
1871
- tokens = [r.time, 7 /* Event.Region */];
1872
- tokens.push(r.data.id);
1873
- tokens.push(r.data.interaction);
1874
- tokens.push(r.data.visibility);
1875
- tokens.push(r.data.name);
1876
- queue(tokens);
1877
- }
1878
- reset$h();
1879
- return [3 /*break*/, 12];
1880
- case 3:
1881
- for (_c = 0, _d = sheetAdoptionState; _c < _d.length; _c++) {
1882
- entry = _d[_c];
1883
- tokens = [entry.time, entry.event];
1884
- tokens.push(entry.data.id);
1885
- tokens.push(entry.data.operation);
1886
- tokens.push(entry.data.newIds);
1887
- queue(tokens);
1888
- }
1889
- for (_e = 0, _f = sheetUpdateState; _e < _f.length; _e++) {
1890
- entry = _f[_e];
1891
- tokens = [entry.time, entry.event];
1892
- tokens.push(entry.data.id);
1893
- tokens.push(entry.data.operation);
1894
- tokens.push(entry.data.cssRules);
1895
- queue(tokens);
1896
- }
1897
- reset$j();
1898
- return [3 /*break*/, 12];
1899
- case 4:
1900
- for (_g = 0, _h = state$9; _g < _h.length; _g++) {
1901
- entry = _h[_g];
1902
- tokens = [entry.time, entry.event];
1903
- tokens.push(entry.data.id);
1904
- tokens.push(entry.data.operation);
1905
- tokens.push(entry.data.keyFrames);
1906
- tokens.push(entry.data.timing);
1907
- tokens.push(entry.data.timeline);
1908
- tokens.push(entry.data.targetId);
1909
- queue(tokens);
1910
- }
1911
- reset$i();
1912
- return [3 /*break*/, 12];
1913
- case 5:
1914
- // Check if we are operating within the context of the current page
1915
- if (state$a(timer) === 2 /* Task.Stop */) {
1916
- return [3 /*break*/, 12];
1917
- }
1918
- values = updates$2();
1919
- if (!(values.length > 0)) return [3 /*break*/, 11];
1920
- _j = 0, values_1 = values;
1921
- _l.label = 6;
1922
- case 6:
1923
- if (!(_j < values_1.length)) return [3 /*break*/, 10];
1924
- value = values_1[_j];
1925
- state = state$a(timer);
1926
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 8];
1927
- return [4 /*yield*/, suspend$1(timer)];
1928
- case 7:
1929
- state = _l.sent();
1930
- _l.label = 8;
1931
- case 8:
1932
- if (state === 2 /* Task.Stop */) {
1933
- return [3 /*break*/, 10];
1934
- }
1935
- data = value.data;
1936
- active = value.metadata.active;
1937
- suspend = value.metadata.suspend;
1938
- privacy = value.metadata.privacy;
1939
- mangle = shouldMangle(value);
1940
- keys = active ? ["tag", "attributes", "value"] : ["tag"];
1941
- for (_k = 0, keys_1 = keys; _k < keys_1.length; _k++) {
1942
- key = keys_1[_k];
1943
- if (data[key]) {
1944
- switch (key) {
1945
- case "tag":
1946
- box = size(value);
1947
- factor = mangle ? -1 : 1;
1948
- tokens.push(value.id * factor);
1949
- if (value.parent && active) {
1950
- tokens.push(value.parent);
1951
- if (value.previous) {
1952
- tokens.push(value.previous);
1953
- }
1954
- }
1955
- tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
1956
- if (box && box.length === 2) {
1957
- tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
1958
- }
1959
- break;
1960
- case "attributes":
1961
- for (attr in data[key]) {
1962
- if (data[key][attr] !== undefined) {
1963
- tokens.push(attribute(attr, data[key][attr], privacy));
1964
- }
1965
- }
1966
- break;
1967
- case "value":
1968
- check$4(value.metadata.fraud, value.id, data[key]);
1969
- tokens.push(text$1(data[key], data.tag, privacy, mangle));
1970
- break;
1971
- }
1972
- }
1973
- }
1974
- _l.label = 9;
1975
- case 9:
1976
- _j++;
1977
- return [3 /*break*/, 6];
1978
- case 10:
1979
- if (type === 6 /* Event.Mutation */) {
1980
- activity(eventTime);
1981
- }
1982
- queue(tokenize(tokens), !config$1.lean);
1983
- _l.label = 11;
1984
- case 11: return [3 /*break*/, 12];
1985
- case 12: return [2 /*return*/];
1986
- }
1987
- });
1988
- });
1872
+ var state$7 = [];
1873
+ function start$u() {
1874
+ reset$h();
1989
1875
  }
1990
- function shouldMangle(value) {
1991
- var privacy = value.metadata.privacy;
1992
- return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
1876
+ function observe$a(root) {
1877
+ bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
1878
+ bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
1879
+ bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
1993
1880
  }
1994
- function size(value) {
1995
- if (value.metadata.size !== null && value.metadata.size.length === 0) {
1996
- var img = getNode(value.id);
1997
- if (img) {
1998
- return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
1999
- }
2000
- }
2001
- return value.metadata.size;
1881
+ function recompute$7(action, evt) {
1882
+ state$7.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
1883
+ schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
2002
1884
  }
2003
- function str$1(input) {
2004
- return input.toString(36);
1885
+ function reset$h() {
1886
+ state$7 = [];
2005
1887
  }
2006
- function attribute(key, value, privacy) {
2007
- return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
1888
+ function stop$s() {
1889
+ reset$h();
2008
1890
  }
2009
1891
 
2010
- var state$8 = [];
2011
- var regionMap = null; // Maps region nodes => region name
2012
- var regions = {};
2013
- var queue$2 = [];
2014
- var watch = false;
2015
- var observer$1 = null;
2016
- function start$u() {
2017
- reset$h();
2018
- observer$1 = null;
2019
- regionMap = new WeakMap();
2020
- regions = {};
2021
- queue$2 = [];
2022
- watch = window["IntersectionObserver"] ? true : false;
2023
- }
2024
- function observe$c(node, name) {
2025
- if (regionMap.has(node) === false) {
2026
- regionMap.set(node, name);
2027
- observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$3, {
2028
- // Get notified as intersection continues to change
2029
- // This allows us to process regions that get partially hidden during the lifetime of the page
2030
- // See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
2031
- // By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
2032
- threshold: [0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
2033
- }) : observer$1;
2034
- if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
2035
- observer$1.observe(node);
2036
- }
2037
- }
2038
- }
2039
- function exists(node) {
2040
- // Check if regionMap is not null before looking up a node
2041
- // Since, dom module stops after region module, it's possible that we may set regionMap to be null
2042
- // and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
2043
- return regionMap && regionMap.has(node);
1892
+ var timeout$5 = null;
1893
+ var state$6 = [];
1894
+ function start$t() {
1895
+ reset$g();
2044
1896
  }
2045
- function track$4(id, event) {
2046
- var node = getNode(id);
2047
- var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
2048
- // Determine the interaction state based on incoming event
2049
- var interaction = 16 /* InteractionState.None */;
2050
- switch (event) {
2051
- case 9 /* Event.Click */:
2052
- interaction = 20 /* InteractionState.Clicked */;
2053
- break;
2054
- case 27 /* Event.Input */:
2055
- interaction = 30 /* InteractionState.Input */;
2056
- break;
2057
- }
2058
- // Process updates to this region, if applicable
2059
- process$6(node, data, interaction, data.visibility);
1897
+ function observe$9(root) {
1898
+ bind(root, "input", recompute$6, true);
2060
1899
  }
2061
- function compute$7() {
2062
- // Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
2063
- // This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
2064
- // For those cases we add them to the queue and re-process them below
2065
- var q = [];
2066
- for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
2067
- var r = queue_1[_i];
2068
- var id = getId(r.node);
2069
- if (id) {
2070
- r.state.data.id = id;
2071
- regions[id] = r.state.data;
2072
- state$8.push(r.state);
1900
+ function recompute$6(evt) {
1901
+ var input = target(evt);
1902
+ var value = get(input);
1903
+ if (input && input.type && value) {
1904
+ var v = input.value;
1905
+ switch (input.type) {
1906
+ case "radio":
1907
+ case "checkbox":
1908
+ v = input.checked ? "true" : "false";
1909
+ break;
2073
1910
  }
2074
- else {
2075
- q.push(r);
1911
+ var data = { target: input, value: v };
1912
+ // 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.
1913
+ if (state$6.length > 0 && (state$6[state$6.length - 1].data.target === data.target)) {
1914
+ state$6.pop();
2076
1915
  }
2077
- }
2078
- queue$2 = q;
2079
- // Schedule encode only when we have at least one valid data entry
2080
- if (state$8.length > 0) {
2081
- encode$4(7 /* Event.Region */);
1916
+ state$6.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
1917
+ clearTimeout(timeout$5);
1918
+ timeout$5 = setTimeout(process$6, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
2082
1919
  }
2083
1920
  }
2084
- function handler$3(entries) {
2085
- for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
2086
- var entry = entries_1[_i];
2087
- var target = entry.target;
2088
- var rect = entry.boundingClientRect;
2089
- var overlap = entry.intersectionRect;
2090
- var viewport = entry.rootBounds;
2091
- // Only capture regions that have non-zero width or height to avoid tracking and sending regions
2092
- // that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
2093
- // like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
2094
- // 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
2095
- if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
2096
- var id = target ? getId(target) : null;
2097
- var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
2098
- // For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
2099
- // However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
2100
- var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
2101
- var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
2102
- // If an element is either visible or was visible and has been scrolled to the end
2103
- // 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.
2104
- // 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
2105
- var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
2106
- // Process updates to this region, if applicable
2107
- process$6(target, data, data.interaction, (scrolledToEnd ?
2108
- 13 /* RegionVisibility.ScrolledToEnd */ :
2109
- (visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
2110
- // Stop observing this element now that we have already received scrolled signal
2111
- if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
2112
- observer$1.unobserve(target);
2113
- }
2114
- }
2115
- }
2116
- if (state$8.length > 0) {
2117
- encode$4(7 /* Event.Region */);
2118
- }
2119
- }
2120
- function process$6(n, d, s, v) {
2121
- // Check if received a state that supersedes existing state
2122
- var updated = s > d.interaction || v > d.visibility;
2123
- d.interaction = s > d.interaction ? s : d.interaction;
2124
- d.visibility = v > d.visibility ? v : d.visibility;
2125
- // If the corresponding node is already discovered, update the internal state
2126
- // Otherwise, track it in a queue to reprocess later.
2127
- if (d.id) {
2128
- if ((d.id in regions && updated) || !(d.id in regions)) {
2129
- regions[d.id] = d;
2130
- state$8.push(clone$1(d));
2131
- }
2132
- }
2133
- else {
2134
- // Get the time before adding to queue to ensure accurate event time
2135
- queue$2.push({ node: n, state: clone$1(d) });
2136
- }
2137
- }
2138
- function clone$1(r) {
2139
- return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
2140
- }
2141
- function reset$h() {
2142
- state$8 = [];
2143
- }
2144
- function stop$s() {
2145
- reset$h();
2146
- regionMap = null;
2147
- regions = {};
2148
- queue$2 = [];
2149
- if (observer$1) {
2150
- observer$1.disconnect();
2151
- observer$1 = null;
2152
- }
2153
- watch = false;
2154
- }
2155
-
2156
- var state$7 = [];
2157
- function start$t() {
2158
- reset$g();
2159
- }
2160
- function observe$b(root) {
2161
- bind(root, "change", recompute$8, true);
2162
- }
2163
- function recompute$8(evt) {
2164
- var element = target(evt);
2165
- if (element) {
2166
- var value = element.value;
2167
- 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 */;
2168
- state$7.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
2169
- schedule$1(encode$3.bind(this, 42 /* Event.Change */));
2170
- }
1921
+ function process$6(event) {
1922
+ schedule$1(encode$3.bind(this, event));
2171
1923
  }
2172
1924
  function reset$g() {
2173
- state$7 = [];
1925
+ state$6 = [];
2174
1926
  }
2175
1927
  function stop$r() {
1928
+ clearTimeout(timeout$5);
2176
1929
  reset$g();
2177
1930
  }
2178
1931
 
2179
- function offset(element) {
2180
- var output = { x: 0, y: 0 };
2181
- // Walk up the chain to ensure we compute offset distance correctly
2182
- // In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
2183
- if (element && element.offsetParent) {
2184
- do {
2185
- var parent_1 = element.offsetParent;
2186
- var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
2187
- output.x += element.offsetLeft;
2188
- output.y += element.offsetTop;
2189
- element = frame ? frame : parent_1;
2190
- } while (element);
2191
- }
2192
- return output;
2193
- }
2194
-
2195
- var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
2196
- var state$6 = [];
1932
+ var state$5 = [];
1933
+ var timeout$4 = null;
2197
1934
  function start$s() {
2198
1935
  reset$f();
2199
1936
  }
2200
- function observe$a(root) {
2201
- bind(root, "click", handler$2.bind(this, 9 /* Event.Click */, root), true);
1937
+ function observe$8(root) {
1938
+ bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
1939
+ bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
1940
+ bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
1941
+ bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
1942
+ bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
1943
+ bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
1944
+ bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
1945
+ bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
1946
+ bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
2202
1947
  }
2203
- function handler$2(event, root, evt) {
1948
+ function mouse(event, root, evt) {
2204
1949
  var frame = iframe(root);
2205
1950
  var d = frame ? frame.contentDocument.documentElement : document.documentElement;
2206
1951
  var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
@@ -2211,274 +1956,76 @@ function handler$2(event, root, evt) {
2211
1956
  x = x ? x + Math.round(distance.x) : x;
2212
1957
  y = y ? y + Math.round(distance.y) : y;
2213
1958
  }
2214
- var t = target(evt);
2215
- // Find nearest anchor tag (<a/>) parent if current target node is part of one
2216
- // If present, we use the returned link element to populate text and link properties below
2217
- var a = link(t);
2218
- // Get layout rectangle for the target element
2219
- var l = layout$1(t);
2220
- // Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
2221
- // This property helps differentiate between a keyboard navigation vs. pointer click
2222
- // In case of a keyboard navigation, we use center of target element as (x,y)
2223
- if (evt.detail === 0 && l) {
2224
- x = Math.round(l.x + (l.w / 2));
2225
- y = Math.round(l.y + (l.h / 2));
2226
- }
2227
- var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
2228
- var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
2229
1959
  // Check for null values before processing this event
2230
1960
  if (x !== null && y !== null) {
2231
- state$6.push({
2232
- time: time(evt),
2233
- event: event,
2234
- data: {
2235
- target: t,
2236
- x: x,
2237
- y: y,
2238
- eX: eX,
2239
- eY: eY,
2240
- button: evt.button,
2241
- reaction: reaction(t),
2242
- context: context(a),
2243
- text: text(t),
2244
- link: a ? a.href : null,
2245
- hash: null,
2246
- trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
2247
- }
2248
- });
2249
- schedule$1(encode$3.bind(this, event));
1961
+ handler$2({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
2250
1962
  }
2251
1963
  }
2252
- function link(node) {
2253
- while (node && node !== document) {
2254
- if (node.nodeType === Node.ELEMENT_NODE) {
2255
- var element = node;
2256
- if (element.tagName === "A") {
2257
- return element;
1964
+ function touch(event, root, evt) {
1965
+ var frame = iframe(root);
1966
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1967
+ var touches = evt.changedTouches;
1968
+ var t = time(evt);
1969
+ if (touches) {
1970
+ for (var i = 0; i < touches.length; i++) {
1971
+ var entry = touches[i];
1972
+ var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
1973
+ var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
1974
+ x = x && frame ? x + Math.round(frame.offsetLeft) : x;
1975
+ y = y && frame ? y + Math.round(frame.offsetTop) : y;
1976
+ // Check for null values before processing this event
1977
+ if (x !== null && y !== null) {
1978
+ handler$2({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
2258
1979
  }
2259
1980
  }
2260
- node = node.parentNode;
2261
- }
2262
- return null;
2263
- }
2264
- function text(element) {
2265
- var output = null;
2266
- if (element) {
2267
- // Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
2268
- var t = element.textContent || String(element.value || '') || element.alt;
2269
- if (t) {
2270
- // Replace multiple occurrence of space characters with a single white space
2271
- // Also, trim any spaces at the beginning or at the end of string
2272
- // Finally, send only first few characters as specified by the Setting
2273
- output = t.replace(/\s+/g, " " /* Constant.Space */).trim().substr(0, 25 /* Setting.ClickText */);
2274
- }
2275
- }
2276
- return output;
2277
- }
2278
- function reaction(element) {
2279
- if (element.nodeType === Node.ELEMENT_NODE) {
2280
- var tag = element.tagName.toLowerCase();
2281
- if (UserInputTags.indexOf(tag) >= 0) {
2282
- return 0 /* BooleanFlag.False */;
2283
- }
2284
1981
  }
2285
- return 1 /* BooleanFlag.True */;
2286
1982
  }
2287
- function layout$1(element) {
2288
- var box = null;
2289
- var de = document.documentElement;
2290
- if (typeof element.getBoundingClientRect === "function") {
2291
- // getBoundingClientRect returns rectangle relative positioning to viewport
2292
- var rect = element.getBoundingClientRect();
2293
- if (rect && rect.width > 0 && rect.height > 0) {
2294
- // Add viewport's scroll position to rectangle to get position relative to document origin
2295
- // Also: using Math.floor() instead of Math.round() because in Edge,
2296
- // getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
2297
- // floors the value (e.g. 162px). This keeps consistent behavior across browsers.
2298
- box = {
2299
- x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
2300
- y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
2301
- w: Math.floor(rect.width),
2302
- h: Math.floor(rect.height)
2303
- };
2304
- }
1983
+ function handler$2(current) {
1984
+ switch (current.event) {
1985
+ case 12 /* Event.MouseMove */:
1986
+ case 15 /* Event.MouseWheel */:
1987
+ case 19 /* Event.TouchMove */:
1988
+ var length_1 = state$5.length;
1989
+ var last = length_1 > 1 ? state$5[length_1 - 2] : null;
1990
+ if (last && similar$1(last, current)) {
1991
+ state$5.pop();
1992
+ }
1993
+ state$5.push(current);
1994
+ clearTimeout(timeout$4);
1995
+ timeout$4 = setTimeout(process$5, 500 /* Setting.LookAhead */, current.event);
1996
+ break;
1997
+ default:
1998
+ state$5.push(current);
1999
+ process$5(current.event);
2000
+ break;
2305
2001
  }
2306
- return box;
2307
2002
  }
2308
- function context(a) {
2309
- if (a && a.hasAttribute("target" /* Constant.Target */)) {
2310
- switch (a.getAttribute("target" /* Constant.Target */)) {
2311
- case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
2312
- case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
2313
- case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
2314
- }
2315
- }
2316
- return 0 /* BrowsingContext.Self */;
2003
+ function process$5(event) {
2004
+ schedule$1(encode$3.bind(this, event));
2317
2005
  }
2318
2006
  function reset$f() {
2319
- state$6 = [];
2007
+ state$5 = [];
2008
+ }
2009
+ function similar$1(last, current) {
2010
+ var dx = last.data.x - current.data.x;
2011
+ var dy = last.data.y - current.data.y;
2012
+ var distance = Math.sqrt(dx * dx + dy * dy);
2013
+ var gap = current.time - last.time;
2014
+ var match = current.data.target === last.data.target;
2015
+ return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
2320
2016
  }
2321
2017
  function stop$q() {
2322
- reset$f();
2018
+ clearTimeout(timeout$4);
2019
+ // Send out any pending pointer events in the pipeline
2020
+ if (state$5.length > 0) {
2021
+ process$5(state$5[state$5.length - 1].event);
2022
+ }
2323
2023
  }
2324
2024
 
2325
- var state$5 = [];
2025
+ var data$b;
2326
2026
  function start$r() {
2327
- reset$e();
2328
- }
2329
- function observe$9(root) {
2330
- bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
2331
- bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
2332
- bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
2333
- }
2334
- function recompute$7(action, evt) {
2335
- state$5.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
2336
- schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
2337
- }
2338
- function reset$e() {
2339
- state$5 = [];
2340
- }
2341
- function stop$p() {
2342
- reset$e();
2343
- }
2344
-
2345
- var timeout$5 = null;
2346
- var state$4 = [];
2347
- function start$q() {
2348
- reset$d();
2349
- }
2350
- function observe$8(root) {
2351
- bind(root, "input", recompute$6, true);
2352
- }
2353
- function recompute$6(evt) {
2354
- var input = target(evt);
2355
- var value = get(input);
2356
- if (input && input.type && value) {
2357
- var v = input.value;
2358
- switch (input.type) {
2359
- case "radio":
2360
- case "checkbox":
2361
- v = input.checked ? "true" : "false";
2362
- break;
2363
- }
2364
- var data = { target: input, value: v };
2365
- // 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.
2366
- if (state$4.length > 0 && (state$4[state$4.length - 1].data.target === data.target)) {
2367
- state$4.pop();
2368
- }
2369
- state$4.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
2370
- clearTimeout(timeout$5);
2371
- timeout$5 = setTimeout(process$5, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
2372
- }
2373
- }
2374
- function process$5(event) {
2375
- schedule$1(encode$3.bind(this, event));
2376
- }
2377
- function reset$d() {
2378
- state$4 = [];
2379
- }
2380
- function stop$o() {
2381
- clearTimeout(timeout$5);
2382
- reset$d();
2383
- }
2384
-
2385
- var state$3 = [];
2386
- var timeout$4 = null;
2387
- function start$p() {
2388
- reset$c();
2389
- }
2390
- function observe$7(root) {
2391
- bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
2392
- bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
2393
- bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
2394
- bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
2395
- bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
2396
- bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
2397
- bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
2398
- bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
2399
- bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
2400
- }
2401
- function mouse(event, root, evt) {
2402
- var frame = iframe(root);
2403
- var d = frame ? frame.contentDocument.documentElement : document.documentElement;
2404
- var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
2405
- var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
2406
- // In case of iframe, we adjust (x,y) to be relative to top parent's origin
2407
- if (frame) {
2408
- var distance = offset(frame);
2409
- x = x ? x + Math.round(distance.x) : x;
2410
- y = y ? y + Math.round(distance.y) : y;
2411
- }
2412
- // Check for null values before processing this event
2413
- if (x !== null && y !== null) {
2414
- handler$1({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
2415
- }
2416
- }
2417
- function touch(event, root, evt) {
2418
- var frame = iframe(root);
2419
- var d = frame ? frame.contentDocument.documentElement : document.documentElement;
2420
- var touches = evt.changedTouches;
2421
- var t = time(evt);
2422
- if (touches) {
2423
- for (var i = 0; i < touches.length; i++) {
2424
- var entry = touches[i];
2425
- var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
2426
- var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
2427
- x = x && frame ? x + Math.round(frame.offsetLeft) : x;
2428
- y = y && frame ? y + Math.round(frame.offsetTop) : y;
2429
- // Check for null values before processing this event
2430
- if (x !== null && y !== null) {
2431
- handler$1({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
2432
- }
2433
- }
2434
- }
2435
- }
2436
- function handler$1(current) {
2437
- switch (current.event) {
2438
- case 12 /* Event.MouseMove */:
2439
- case 15 /* Event.MouseWheel */:
2440
- case 19 /* Event.TouchMove */:
2441
- var length_1 = state$3.length;
2442
- var last = length_1 > 1 ? state$3[length_1 - 2] : null;
2443
- if (last && similar$1(last, current)) {
2444
- state$3.pop();
2445
- }
2446
- state$3.push(current);
2447
- clearTimeout(timeout$4);
2448
- timeout$4 = setTimeout(process$4, 500 /* Setting.LookAhead */, current.event);
2449
- break;
2450
- default:
2451
- state$3.push(current);
2452
- process$4(current.event);
2453
- break;
2454
- }
2455
- }
2456
- function process$4(event) {
2457
- schedule$1(encode$3.bind(this, event));
2458
- }
2459
- function reset$c() {
2460
- state$3 = [];
2461
- }
2462
- function similar$1(last, current) {
2463
- var dx = last.data.x - current.data.x;
2464
- var dy = last.data.y - current.data.y;
2465
- var distance = Math.sqrt(dx * dx + dy * dy);
2466
- var gap = current.time - last.time;
2467
- var match = current.data.target === last.data.target;
2468
- return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
2469
- }
2470
- function stop$n() {
2471
- clearTimeout(timeout$4);
2472
- // Send out any pending pointer events in the pipeline
2473
- if (state$3.length > 0) {
2474
- process$4(state$3[state$3.length - 1].event);
2475
- }
2476
- }
2477
-
2478
- var data$b;
2479
- function start$o() {
2480
- bind(window, "resize", recompute$5);
2481
- recompute$5();
2027
+ bind(window, "resize", recompute$5);
2028
+ recompute$5();
2482
2029
  }
2483
2030
  function recompute$5() {
2484
2031
  var de = document.documentElement;
@@ -2490,22 +2037,22 @@ function recompute$5() {
2490
2037
  };
2491
2038
  encode$3(11 /* Event.Resize */);
2492
2039
  }
2493
- function reset$b() {
2040
+ function reset$e() {
2494
2041
  data$b = null;
2495
2042
  }
2496
- function stop$m() {
2497
- reset$b();
2043
+ function stop$p() {
2044
+ reset$e();
2498
2045
  }
2499
2046
 
2500
- var state$2 = [];
2047
+ var state$4 = [];
2501
2048
  var initialTop = null;
2502
2049
  var initialBottom = null;
2503
2050
  var timeout$3 = null;
2504
- function start$n() {
2505
- state$2 = [];
2051
+ function start$q() {
2052
+ state$4 = [];
2506
2053
  recompute$4();
2507
2054
  }
2508
- function observe$6(root) {
2055
+ function observe$7(root) {
2509
2056
  var frame = iframe(root);
2510
2057
  var node = frame ? frame.contentWindow : (root === document ? window : root);
2511
2058
  bind(node, "scroll", recompute$4, true);
@@ -2541,14 +2088,14 @@ function recompute$4(event) {
2541
2088
  initialBottom = bottom;
2542
2089
  return;
2543
2090
  }
2544
- var length = state$2.length;
2545
- var last = length > 1 ? state$2[length - 2] : null;
2091
+ var length = state$4.length;
2092
+ var last = length > 1 ? state$4[length - 2] : null;
2546
2093
  if (last && similar(last, current)) {
2547
- state$2.pop();
2094
+ state$4.pop();
2548
2095
  }
2549
- state$2.push(current);
2096
+ state$4.push(current);
2550
2097
  clearTimeout(timeout$3);
2551
- timeout$3 = setTimeout(process$3, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
2098
+ timeout$3 = setTimeout(process$4, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
2552
2099
  }
2553
2100
  function getPositionNode(x, y) {
2554
2101
  var _a, _b;
@@ -2567,12 +2114,12 @@ function getPositionNode(x, y) {
2567
2114
  }
2568
2115
  return node;
2569
2116
  }
2570
- function reset$a() {
2571
- state$2 = [];
2117
+ function reset$d() {
2118
+ state$4 = [];
2572
2119
  initialTop = null;
2573
2120
  initialBottom = null;
2574
2121
  }
2575
- function process$3(event) {
2122
+ function process$4(event) {
2576
2123
  schedule$1(encode$3.bind(this, event));
2577
2124
  }
2578
2125
  function similar(last, current) {
@@ -2580,7 +2127,7 @@ function similar(last, current) {
2580
2127
  var dy = last.data.y - current.data.y;
2581
2128
  return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
2582
2129
  }
2583
- function compute$6() {
2130
+ function compute$8() {
2584
2131
  var _a, _b;
2585
2132
  if (initialTop) {
2586
2133
  var top_1 = metadata$2(initialTop, null);
@@ -2591,9 +2138,9 @@ function compute$6() {
2591
2138
  log(32 /* Dimension.InitialScrollBottom */, (_b = bottom === null || bottom === void 0 ? void 0 : bottom.hash) === null || _b === void 0 ? void 0 : _b.join("." /* Constant.Dot */));
2592
2139
  }
2593
2140
  }
2594
- function stop$l() {
2141
+ function stop$o() {
2595
2142
  clearTimeout(timeout$3);
2596
- state$2 = [];
2143
+ state$4 = [];
2597
2144
  initialTop = null;
2598
2145
  initialBottom = null;
2599
2146
  }
@@ -2601,10 +2148,10 @@ function stop$l() {
2601
2148
  var data$a = null;
2602
2149
  var previous = null;
2603
2150
  var timeout$2 = null;
2604
- function start$m() {
2605
- reset$9();
2151
+ function start$p() {
2152
+ reset$c();
2606
2153
  }
2607
- function observe$5(root) {
2154
+ function observe$6(root) {
2608
2155
  bind(root, "selectstart", recompute$3.bind(this, root), true);
2609
2156
  bind(root, "selectionchange", recompute$3.bind(this, root), true);
2610
2157
  }
@@ -2626,7 +2173,7 @@ function recompute$3(root) {
2626
2173
  var startNode = data$a.start ? data$a.start : null;
2627
2174
  if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
2628
2175
  clearTimeout(timeout$2);
2629
- process$2(21 /* Event.Selection */);
2176
+ process$3(21 /* Event.Selection */);
2630
2177
  }
2631
2178
  data$a = {
2632
2179
  start: current.anchorNode,
@@ -2636,40 +2183,40 @@ function recompute$3(root) {
2636
2183
  };
2637
2184
  previous = current;
2638
2185
  clearTimeout(timeout$2);
2639
- timeout$2 = setTimeout(process$2, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
2186
+ timeout$2 = setTimeout(process$3, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
2640
2187
  }
2641
- function process$2(event) {
2188
+ function process$3(event) {
2642
2189
  schedule$1(encode$3.bind(this, event));
2643
2190
  }
2644
- function reset$9() {
2191
+ function reset$c() {
2645
2192
  previous = null;
2646
2193
  data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
2647
2194
  }
2648
- function stop$k() {
2649
- reset$9();
2195
+ function stop$n() {
2196
+ reset$c();
2650
2197
  clearTimeout(timeout$2);
2651
2198
  }
2652
2199
 
2653
- var state$1 = [];
2654
- function start$l() {
2655
- reset$8();
2200
+ var state$3 = [];
2201
+ function start$o() {
2202
+ reset$b();
2656
2203
  }
2657
- function observe$4(root) {
2204
+ function observe$5(root) {
2658
2205
  bind(root, "submit", recompute$2, true);
2659
2206
  }
2660
2207
  function recompute$2(evt) {
2661
- state$1.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
2208
+ state$3.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
2662
2209
  schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
2663
2210
  }
2664
- function reset$8() {
2665
- state$1 = [];
2211
+ function reset$b() {
2212
+ state$3 = [];
2666
2213
  }
2667
- function stop$j() {
2668
- reset$8();
2214
+ function stop$m() {
2215
+ reset$b();
2669
2216
  }
2670
2217
 
2671
2218
  var data$9;
2672
- function start$k() {
2219
+ function start$n() {
2673
2220
  bind(window, "pagehide", recompute$1);
2674
2221
  }
2675
2222
  function recompute$1(evt) {
@@ -2677,15 +2224,15 @@ function recompute$1(evt) {
2677
2224
  encode$3(26 /* Event.Unload */, time(evt));
2678
2225
  stop();
2679
2226
  }
2680
- function reset$7() {
2227
+ function reset$a() {
2681
2228
  data$9 = null;
2682
2229
  }
2683
- function stop$i() {
2684
- reset$7();
2230
+ function stop$l() {
2231
+ reset$a();
2685
2232
  }
2686
2233
 
2687
2234
  var data$8;
2688
- function start$j() {
2235
+ function start$m() {
2689
2236
  bind(document, "visibilitychange", recompute);
2690
2237
  recompute();
2691
2238
  }
@@ -2694,63 +2241,419 @@ function recompute(evt) {
2694
2241
  data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
2695
2242
  encode$3(28 /* Event.Visibility */, time(evt));
2696
2243
  }
2697
- function reset$6() {
2244
+ function reset$9() {
2698
2245
  data$8 = null;
2699
2246
  }
2700
- function stop$h() {
2701
- reset$6();
2247
+ function stop$k() {
2248
+ reset$9();
2702
2249
  }
2703
2250
 
2704
- function start$i() {
2251
+ function start$l() {
2705
2252
  start$g();
2253
+ start$v();
2254
+ start$u();
2706
2255
  start$s();
2256
+ start$t();
2707
2257
  start$r();
2708
- start$p();
2258
+ start$m();
2709
2259
  start$q();
2260
+ start$p();
2261
+ start$w();
2710
2262
  start$o();
2711
- start$j();
2712
2263
  start$n();
2713
- start$m();
2714
- start$t();
2715
- start$l();
2716
- start$k();
2717
2264
  }
2718
- function stop$g() {
2265
+ function stop$j() {
2719
2266
  stop$e();
2267
+ stop$t();
2268
+ stop$s();
2720
2269
  stop$q();
2270
+ stop$r();
2721
2271
  stop$p();
2722
- stop$n();
2272
+ stop$k();
2723
2273
  stop$o();
2274
+ stop$n();
2275
+ stop$u();
2724
2276
  stop$m();
2725
- stop$h();
2726
2277
  stop$l();
2727
- stop$k();
2728
- stop$r();
2729
- stop$j();
2730
- stop$i();
2731
2278
  }
2732
- function observe$3(root) {
2733
- observe$6(root);
2734
- // Only monitor following interactions if the root node is a document
2735
- // In case of shadow DOM, following events automatically bubble up to the parent document.
2736
- if (root.nodeType === Node.DOCUMENT_NODE) {
2737
- observe$a(root);
2738
- observe$9(root);
2739
- observe$7(root);
2740
- observe$8(root);
2741
- observe$5(root);
2742
- observe$b(root);
2743
- observe$4(root);
2279
+ function observe$4(root) {
2280
+ observe$7(root);
2281
+ // Only monitor following interactions if the root node is a document
2282
+ // In case of shadow DOM, following events automatically bubble up to the parent document.
2283
+ if (root.nodeType === Node.DOCUMENT_NODE) {
2284
+ observe$b(root);
2285
+ observe$a(root);
2286
+ observe$8(root);
2287
+ observe$9(root);
2288
+ observe$6(root);
2289
+ observe$c(root);
2290
+ observe$5(root);
2291
+ }
2292
+ }
2293
+
2294
+ var interaction = /*#__PURE__*/Object.freeze({
2295
+ __proto__: null,
2296
+ observe: observe$4,
2297
+ start: start$l,
2298
+ stop: stop$j
2299
+ });
2300
+
2301
+ function traverse (root, timer, source, timestamp) {
2302
+ return __awaiter(this, void 0, void 0, function () {
2303
+ var queue, entry, next, state, subnode;
2304
+ return __generator(this, function (_a) {
2305
+ switch (_a.label) {
2306
+ case 0:
2307
+ queue = [root];
2308
+ _a.label = 1;
2309
+ case 1:
2310
+ if (!(queue.length > 0)) return [3 /*break*/, 4];
2311
+ entry = queue.shift();
2312
+ next = entry.firstChild;
2313
+ while (next) {
2314
+ queue.push(next);
2315
+ next = next.nextSibling;
2316
+ }
2317
+ state = state$a(timer);
2318
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
2319
+ return [4 /*yield*/, suspend$1(timer)];
2320
+ case 2:
2321
+ state = _a.sent();
2322
+ _a.label = 3;
2323
+ case 3:
2324
+ if (state === 2 /* Task.Stop */) {
2325
+ return [3 /*break*/, 4];
2326
+ }
2327
+ subnode = processNode(entry, source, timestamp);
2328
+ if (subnode) {
2329
+ queue.push(subnode);
2330
+ }
2331
+ return [3 /*break*/, 1];
2332
+ case 4: return [2 /*return*/];
2333
+ }
2334
+ });
2335
+ });
2336
+ }
2337
+
2338
+ var observers = [];
2339
+ var mutations = [];
2340
+ var insertRule = null;
2341
+ var deleteRule = null;
2342
+ var attachShadow = null;
2343
+ var mediaInsertRule = null;
2344
+ var mediaDeleteRule = null;
2345
+ var queue$2 = [];
2346
+ var timeout$1 = null;
2347
+ var activePeriod = null;
2348
+ var history$4 = {};
2349
+ function start$k() {
2350
+ observers = [];
2351
+ queue$2 = [];
2352
+ timeout$1 = null;
2353
+ activePeriod = 0;
2354
+ history$4 = {};
2355
+ // Some popular open source libraries, like styled-components, optimize performance
2356
+ // by injecting CSS using insertRule API vs. appending text node. A side effect of
2357
+ // using javascript API is that it doesn't trigger DOM mutation and therefore we
2358
+ // need to override the insertRule API and listen for changes manually.
2359
+ if (insertRule === null) {
2360
+ insertRule = CSSStyleSheet.prototype.insertRule;
2361
+ CSSStyleSheet.prototype.insertRule = function () {
2362
+ if (active()) {
2363
+ schedule(this.ownerNode);
2364
+ }
2365
+ return insertRule.apply(this, arguments);
2366
+ };
2367
+ }
2368
+ if ("CSSMediaRule" in window && mediaInsertRule === null) {
2369
+ mediaInsertRule = CSSMediaRule.prototype.insertRule;
2370
+ CSSMediaRule.prototype.insertRule = function () {
2371
+ if (active()) {
2372
+ schedule(this.parentStyleSheet.ownerNode);
2373
+ }
2374
+ return mediaInsertRule.apply(this, arguments);
2375
+ };
2376
+ }
2377
+ if (deleteRule === null) {
2378
+ deleteRule = CSSStyleSheet.prototype.deleteRule;
2379
+ CSSStyleSheet.prototype.deleteRule = function () {
2380
+ if (active()) {
2381
+ schedule(this.ownerNode);
2382
+ }
2383
+ return deleteRule.apply(this, arguments);
2384
+ };
2385
+ }
2386
+ if ("CSSMediaRule" in window && mediaDeleteRule === null) {
2387
+ mediaDeleteRule = CSSMediaRule.prototype.deleteRule;
2388
+ CSSMediaRule.prototype.deleteRule = function () {
2389
+ if (active()) {
2390
+ schedule(this.parentStyleSheet.ownerNode);
2391
+ }
2392
+ return mediaDeleteRule.apply(this, arguments);
2393
+ };
2394
+ }
2395
+ // Add a hook to attachShadow API calls
2396
+ // In case we are unable to add a hook and browser throws an exception,
2397
+ // reset attachShadow variable and resume processing like before
2398
+ if (attachShadow === null) {
2399
+ attachShadow = Element.prototype.attachShadow;
2400
+ try {
2401
+ Element.prototype.attachShadow = function () {
2402
+ if (active()) {
2403
+ return schedule(attachShadow.apply(this, arguments));
2404
+ }
2405
+ else {
2406
+ return attachShadow.apply(this, arguments);
2407
+ }
2408
+ };
2409
+ }
2410
+ catch (_a) {
2411
+ attachShadow = null;
2412
+ }
2413
+ }
2414
+ }
2415
+ function observe$3(node) {
2416
+ // Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
2417
+ // In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
2418
+ // For this reason, we need to wire up mutations every time we see a new shadow dom.
2419
+ // Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
2420
+ try {
2421
+ var m = api("MutationObserver" /* Constant.MutationObserver */);
2422
+ var observer = m in window ? new window[m](measure(handle$1)) : null;
2423
+ if (observer) {
2424
+ observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
2425
+ observers.push(observer);
2426
+ }
2427
+ }
2428
+ catch (e) {
2429
+ log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
2430
+ }
2431
+ }
2432
+ function monitor(frame) {
2433
+ // Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
2434
+ // This includes cases where iframe location is updated without explicitly updating src attribute
2435
+ // E.g. iframe.contentWindow.location.href = "new-location";
2436
+ if (has(frame) === false) {
2437
+ bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
2438
+ }
2439
+ }
2440
+ function stop$i() {
2441
+ for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
2442
+ var observer = observers_1[_i];
2443
+ if (observer) {
2444
+ observer.disconnect();
2445
+ }
2446
+ }
2447
+ observers = [];
2448
+ history$4 = {};
2449
+ mutations = [];
2450
+ queue$2 = [];
2451
+ activePeriod = 0;
2452
+ timeout$1 = null;
2453
+ }
2454
+ function active$2() {
2455
+ activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
2456
+ }
2457
+ function handle$1(m) {
2458
+ // Queue up mutation records for asynchronous processing
2459
+ var now = time();
2460
+ track$7(6 /* Event.Mutation */, now);
2461
+ mutations.push({ time: now, mutations: m });
2462
+ schedule$1(process$2, 1 /* Priority.High */).then(function () {
2463
+ setTimeout(compute$9);
2464
+ measure(compute$6)();
2465
+ });
2466
+ }
2467
+ function process$2() {
2468
+ return __awaiter(this, void 0, void 0, function () {
2469
+ var timer, record, instance, _i, _a, mutation, state, target, type, value;
2470
+ return __generator(this, function (_b) {
2471
+ switch (_b.label) {
2472
+ case 0:
2473
+ timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
2474
+ start$y(timer);
2475
+ _b.label = 1;
2476
+ case 1:
2477
+ if (!(mutations.length > 0)) return [3 /*break*/, 8];
2478
+ record = mutations.shift();
2479
+ instance = time();
2480
+ _i = 0, _a = record.mutations;
2481
+ _b.label = 2;
2482
+ case 2:
2483
+ if (!(_i < _a.length)) return [3 /*break*/, 6];
2484
+ mutation = _a[_i];
2485
+ state = state$a(timer);
2486
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2487
+ return [4 /*yield*/, suspend$1(timer)];
2488
+ case 3:
2489
+ state = _b.sent();
2490
+ _b.label = 4;
2491
+ case 4:
2492
+ if (state === 2 /* Task.Stop */) {
2493
+ return [3 /*break*/, 6];
2494
+ }
2495
+ target = mutation.target;
2496
+ type = config$1.throttleDom ? track$5(mutation, timer, instance, record.time) : mutation.type;
2497
+ if (type && target && target.ownerDocument) {
2498
+ parse$1(target.ownerDocument);
2499
+ }
2500
+ if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
2501
+ parse$1(target);
2502
+ }
2503
+ switch (type) {
2504
+ case "attributes" /* Constant.Attributes */:
2505
+ processNode(target, 3 /* Source.Attributes */, record.time);
2506
+ break;
2507
+ case "characterData" /* Constant.CharacterData */:
2508
+ processNode(target, 4 /* Source.CharacterData */, record.time);
2509
+ break;
2510
+ case "childList" /* Constant.ChildList */:
2511
+ processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer, record.time);
2512
+ processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer, record.time);
2513
+ break;
2514
+ case "suspend" /* Constant.Suspend */:
2515
+ value = get(target);
2516
+ if (value) {
2517
+ value.metadata.suspend = true;
2518
+ }
2519
+ break;
2520
+ }
2521
+ _b.label = 5;
2522
+ case 5:
2523
+ _i++;
2524
+ return [3 /*break*/, 2];
2525
+ case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
2526
+ case 7:
2527
+ _b.sent();
2528
+ return [3 /*break*/, 1];
2529
+ case 8:
2530
+ stop$w(timer);
2531
+ return [2 /*return*/];
2532
+ }
2533
+ });
2534
+ });
2535
+ }
2536
+ function track$5(m, timer, instance, timestamp) {
2537
+ var value = m.target ? get(m.target.parentNode) : null;
2538
+ // Check if the parent is already discovered and that the parent is not the document root
2539
+ if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
2540
+ // calculate inactive period based on the timestamp of the mutation not when the mutation is processed
2541
+ var inactive = timestamp > activePeriod;
2542
+ var target = get(m.target);
2543
+ var element = target && target.selector ? target.selector.join() : m.target.nodeName;
2544
+ var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
2545
+ // We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
2546
+ // repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
2547
+ // In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
2548
+ var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
2549
+ // Initialize an entry if it doesn't already exist
2550
+ history$4[key] = key in history$4 ? history$4[key] : [0, instance];
2551
+ var h = history$4[key];
2552
+ // Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
2553
+ if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
2554
+ processNodeList(h[2], 2 /* Source.ChildListRemove */, timer, timestamp);
2555
+ }
2556
+ // Update the counter
2557
+ h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
2558
+ h[1] = instance;
2559
+ // Return updated mutation type based on if we have already hit the threshold or not
2560
+ if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
2561
+ // Store a reference to removedNodes so we can process them later
2562
+ // when we resume mutations again on user interactions
2563
+ h[2] = m.removedNodes;
2564
+ return "suspend" /* Constant.Suspend */;
2565
+ }
2566
+ else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
2567
+ return "" /* Constant.Empty */;
2568
+ }
2569
+ }
2570
+ return m.type;
2571
+ }
2572
+ function names(nodes) {
2573
+ var output = [];
2574
+ for (var i = 0; nodes && i < nodes.length; i++) {
2575
+ output.push(nodes[i].nodeName);
2576
+ }
2577
+ return output.join();
2578
+ }
2579
+ function processNodeList(list, source, timer, timestamp) {
2580
+ return __awaiter(this, void 0, void 0, function () {
2581
+ var length, i, state;
2582
+ return __generator(this, function (_a) {
2583
+ switch (_a.label) {
2584
+ case 0:
2585
+ length = list ? list.length : 0;
2586
+ i = 0;
2587
+ _a.label = 1;
2588
+ case 1:
2589
+ if (!(i < length)) return [3 /*break*/, 6];
2590
+ if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
2591
+ traverse(list[i], timer, source, timestamp);
2592
+ return [3 /*break*/, 5];
2593
+ case 2:
2594
+ state = state$a(timer);
2595
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2596
+ return [4 /*yield*/, suspend$1(timer)];
2597
+ case 3:
2598
+ state = _a.sent();
2599
+ _a.label = 4;
2600
+ case 4:
2601
+ if (state === 2 /* Task.Stop */) {
2602
+ return [3 /*break*/, 6];
2603
+ }
2604
+ processNode(list[i], source, timestamp);
2605
+ _a.label = 5;
2606
+ case 5:
2607
+ i++;
2608
+ return [3 /*break*/, 1];
2609
+ case 6: return [2 /*return*/];
2610
+ }
2611
+ });
2612
+ });
2613
+ }
2614
+ function schedule(node) {
2615
+ // Only schedule manual trigger for this node if it's not already in the queue
2616
+ if (queue$2.indexOf(node) < 0) {
2617
+ queue$2.push(node);
2618
+ }
2619
+ // Cancel any previous trigger before scheduling a new one.
2620
+ // It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
2621
+ // And in those cases we do not wish to monitor changes multiple times for the same node.
2622
+ if (timeout$1) {
2623
+ clearTimeout(timeout$1);
2624
+ }
2625
+ timeout$1 = setTimeout(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
2626
+ return node;
2627
+ }
2628
+ function trigger$2() {
2629
+ for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
2630
+ var node = queue_1[_i];
2631
+ // Generate a mutation for this node only if it still exists
2632
+ if (node) {
2633
+ var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
2634
+ // Skip re-processing shadowRoot if it was already discovered
2635
+ if (shadowRoot && has(node)) {
2636
+ continue;
2637
+ }
2638
+ generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
2639
+ }
2744
2640
  }
2641
+ queue$2 = [];
2642
+ }
2643
+ function generate(target, type) {
2644
+ measure(handle$1)([{
2645
+ addedNodes: [target],
2646
+ attributeName: null,
2647
+ attributeNamespace: null,
2648
+ nextSibling: null,
2649
+ oldValue: null,
2650
+ previousSibling: null,
2651
+ removedNodes: [],
2652
+ target: target,
2653
+ type: type
2654
+ }]);
2745
2655
  }
2746
2656
 
2747
- var interaction = /*#__PURE__*/Object.freeze({
2748
- __proto__: null,
2749
- observe: observe$3,
2750
- start: start$i,
2751
- stop: stop$g
2752
- });
2753
-
2754
2657
  var digitsRegex = /[^0-9\.]/g;
2755
2658
  /* JSON+LD (Linked Data) Recursive Parser */
2756
2659
  function ld(json) {
@@ -2851,7 +2754,7 @@ function processNode (node, source, timestamp) {
2851
2754
  // later whenever there are new additions or modifications to DOM (mutations)
2852
2755
  if (node === document)
2853
2756
  parse$1(document);
2854
- checkDocumentStyles(node);
2757
+ checkDocumentStyles(node, timestamp);
2855
2758
  observe$2(node);
2856
2759
  break;
2857
2760
  case Node.DOCUMENT_FRAGMENT_NODE:
@@ -2875,7 +2778,7 @@ function processNode (node, source, timestamp) {
2875
2778
  // the same way we observe real shadow DOM nodes (encapsulation provided by the browser).
2876
2779
  dom[call](node, shadowRoot.host, { tag: "*P" /* Constant.PolyfillShadowDomTag */, attributes: {} }, source);
2877
2780
  }
2878
- checkDocumentStyles(node);
2781
+ checkDocumentStyles(node, timestamp);
2879
2782
  }
2880
2783
  break;
2881
2784
  case Node.TEXT_NODE:
@@ -3018,8 +2921,8 @@ function observe$2(root) {
3018
2921
  if (has(root)) {
3019
2922
  return;
3020
2923
  }
3021
- observe$1(root); // Observe mutations for this root node
3022
- observe$3(root); // Observe interactions for this root node
2924
+ observe$3(root); // Observe mutations for this root node
2925
+ observe$4(root); // Observe interactions for this root node
3023
2926
  }
3024
2927
  function getStyleValue(style) {
3025
2928
  // Call trim on the text content to ensure we do not process white spaces ( , \n, \r\n, \t, etc.)
@@ -3071,360 +2974,542 @@ function getAttributes(element) {
3071
2974
  return output;
3072
2975
  }
3073
2976
 
3074
- function traverse (root, timer, source, timestamp) {
3075
- return __awaiter(this, void 0, void 0, function () {
3076
- var queue, entry, next, state, subnode;
3077
- return __generator(this, function (_a) {
3078
- switch (_a.label) {
3079
- case 0:
3080
- queue = [root];
3081
- _a.label = 1;
3082
- case 1:
3083
- if (!(queue.length > 0)) return [3 /*break*/, 4];
3084
- entry = queue.shift();
3085
- next = entry.firstChild;
3086
- while (next) {
3087
- queue.push(next);
3088
- next = next.nextSibling;
3089
- }
3090
- state = state$a(timer);
3091
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
3092
- return [4 /*yield*/, suspend$1(timer)];
3093
- case 2:
3094
- state = _a.sent();
3095
- _a.label = 3;
3096
- case 3:
3097
- if (state === 2 /* Task.Stop */) {
3098
- return [3 /*break*/, 4];
3099
- }
3100
- subnode = processNode(entry, source);
3101
- if (subnode) {
3102
- queue.push(subnode);
3103
- }
3104
- return [3 /*break*/, 1];
3105
- case 4: return [2 /*return*/];
3106
- }
3107
- });
3108
- });
3109
- }
3110
-
3111
- var observers = [];
3112
- var mutations = [];
3113
- var insertRule = null;
3114
- var deleteRule = null;
3115
- var attachShadow = null;
3116
- var mediaInsertRule = null;
3117
- var mediaDeleteRule = null;
3118
- var queue$1 = [];
3119
- var timeout$1 = null;
3120
- var activePeriod = null;
3121
- var history$4 = {};
3122
- function start$h() {
3123
- observers = [];
3124
- queue$1 = [];
3125
- timeout$1 = null;
3126
- activePeriod = 0;
3127
- history$4 = {};
3128
- // Some popular open source libraries, like styled-components, optimize performance
3129
- // by injecting CSS using insertRule API vs. appending text node. A side effect of
3130
- // using javascript API is that it doesn't trigger DOM mutation and therefore we
3131
- // need to override the insertRule API and listen for changes manually.
3132
- if (insertRule === null) {
3133
- insertRule = CSSStyleSheet.prototype.insertRule;
3134
- CSSStyleSheet.prototype.insertRule = function () {
2977
+ var sheetUpdateState = [];
2978
+ var sheetAdoptionState = [];
2979
+ var replace = null;
2980
+ var replaceSync = null;
2981
+ var styleSheetId = 'claritySheetId';
2982
+ var styleSheetPageNum = 'claritySheetNum';
2983
+ var styleSheetMap = {};
2984
+ var styleTimeMap = {};
2985
+ var documentNodes = [];
2986
+ function start$j() {
2987
+ if (replace === null) {
2988
+ replace = CSSStyleSheet.prototype.replace;
2989
+ CSSStyleSheet.prototype.replace = function () {
3135
2990
  if (active()) {
3136
- schedule(this.ownerNode);
2991
+ max(36 /* Metric.ConstructedStyles */, 1);
2992
+ // if we haven't seen this stylesheet on this page yet, wait until the checkDocumentStyles has found it
2993
+ // and attached the sheet to a document. This way the timestamp of the style sheet creation will align
2994
+ // to when it is used in the document rather than potentially being misaligned during the traverse process.
2995
+ if (this[styleSheetPageNum] === data$2.pageNum) {
2996
+ trackStyleChange(time(), this[styleSheetId], 1 /* StyleSheetOperation.Replace */, arguments[0]);
2997
+ }
3137
2998
  }
3138
- return insertRule.apply(this, arguments);
2999
+ return replace.apply(this, arguments);
3139
3000
  };
3140
3001
  }
3141
- if (mediaInsertRule === null) {
3142
- mediaInsertRule = CSSMediaRule.prototype.insertRule;
3143
- CSSMediaRule.prototype.insertRule = function () {
3002
+ if (replaceSync === null) {
3003
+ replaceSync = CSSStyleSheet.prototype.replaceSync;
3004
+ CSSStyleSheet.prototype.replaceSync = function () {
3144
3005
  if (active()) {
3145
- schedule(this.parentStyleSheet.ownerNode);
3006
+ max(36 /* Metric.ConstructedStyles */, 1);
3007
+ // if we haven't seen this stylesheet on this page yet, wait until the checkDocumentStyles has found it
3008
+ // and attached the sheet to a document. This way the timestamp of the style sheet creation will align
3009
+ // to when it is used in the document rather than potentially being misaligned during the traverse process.
3010
+ if (this[styleSheetPageNum] === data$2.pageNum) {
3011
+ trackStyleChange(time(), this[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, arguments[0]);
3012
+ }
3146
3013
  }
3147
- return mediaInsertRule.apply(this, arguments);
3014
+ return replaceSync.apply(this, arguments);
3148
3015
  };
3149
3016
  }
3150
- if (deleteRule === null) {
3151
- deleteRule = CSSStyleSheet.prototype.deleteRule;
3152
- CSSStyleSheet.prototype.deleteRule = function () {
3153
- if (active()) {
3154
- schedule(this.ownerNode);
3155
- }
3156
- return deleteRule.apply(this, arguments);
3157
- };
3017
+ }
3018
+ function checkDocumentStyles(documentNode, timestamp) {
3019
+ if (documentNodes.indexOf(documentNode) === -1) {
3020
+ documentNodes.push(documentNode);
3158
3021
  }
3159
- if (mediaDeleteRule === null) {
3160
- mediaDeleteRule = CSSMediaRule.prototype.deleteRule;
3161
- CSSMediaRule.prototype.deleteRule = function () {
3162
- if (active()) {
3163
- schedule(this.parentStyleSheet.ownerNode);
3164
- }
3165
- return mediaDeleteRule.apply(this, arguments);
3166
- };
3022
+ timestamp = timestamp || time();
3023
+ if (!(documentNode === null || documentNode === void 0 ? void 0 : documentNode.adoptedStyleSheets)) {
3024
+ // if we don't have adoptedStyledSheets on the Node passed to us, we can short circuit.
3025
+ return;
3167
3026
  }
3168
- // Add a hook to attachShadow API calls
3169
- // In case we are unable to add a hook and browser throws an exception,
3170
- // reset attachShadow variable and resume processing like before
3171
- if (attachShadow === null) {
3172
- attachShadow = Element.prototype.attachShadow;
3173
- try {
3174
- Element.prototype.attachShadow = function () {
3175
- if (active()) {
3176
- return schedule(attachShadow.apply(this, arguments));
3177
- }
3178
- else {
3179
- return attachShadow.apply(this, arguments);
3180
- }
3181
- };
3182
- }
3183
- catch (_a) {
3184
- attachShadow = null;
3027
+ max(36 /* Metric.ConstructedStyles */, 1);
3028
+ var currentStyleSheets = [];
3029
+ for (var _i = 0, _a = documentNode.adoptedStyleSheets; _i < _a.length; _i++) {
3030
+ var styleSheet = _a[_i];
3031
+ var pageNum = data$2.pageNum;
3032
+ // If we haven't seen this style sheet on this page yet, we create a reference to it for the visualizer.
3033
+ // For SPA or times in which Clarity restarts on a given page, our visualizer would lose context
3034
+ // on the previously created style sheet for page N-1.
3035
+ // Then we synthetically call replaceSync with its contents to bootstrap it
3036
+ if (styleSheet[styleSheetPageNum] !== pageNum) {
3037
+ styleSheet[styleSheetPageNum] = pageNum;
3038
+ styleSheet[styleSheetId] = shortid();
3039
+ trackStyleChange(timestamp, styleSheet[styleSheetId], 0 /* StyleSheetOperation.Create */);
3040
+ trackStyleChange(timestamp, styleSheet[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, getCssRules(styleSheet));
3185
3041
  }
3042
+ currentStyleSheets.push(styleSheet[styleSheetId]);
3043
+ }
3044
+ var documentId = getId(documentNode, true);
3045
+ if (!styleSheetMap[documentId]) {
3046
+ styleSheetMap[documentId] = [];
3047
+ }
3048
+ if (!arraysEqual(currentStyleSheets, styleSheetMap[documentId])) {
3049
+ // Using -1 to signify the root document node as we don't track that as part of our nodeMap
3050
+ trackStyleAdoption(timestamp, documentNode == document ? -1 : getId(documentNode), 3 /* StyleSheetOperation.SetAdoptedStyles */, currentStyleSheets);
3051
+ styleSheetMap[documentId] = currentStyleSheets;
3052
+ styleTimeMap[documentId] = timestamp;
3186
3053
  }
3187
3054
  }
3188
- function observe$1(node) {
3189
- // Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
3190
- // In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
3191
- // For this reason, we need to wire up mutations every time we see a new shadow dom.
3192
- // Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
3193
- try {
3194
- var m = api("MutationObserver" /* Constant.MutationObserver */);
3195
- var observer = m in window ? new window[m](measure(handle$1)) : null;
3196
- if (observer) {
3197
- observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
3198
- observers.push(observer);
3055
+ function compute$7() {
3056
+ for (var _i = 0, documentNodes_1 = documentNodes; _i < documentNodes_1.length; _i++) {
3057
+ var documentNode = documentNodes_1[_i];
3058
+ var docId = documentNode == document ? -1 : getId(documentNode);
3059
+ var ts = docId in styleTimeMap ? styleTimeMap[docId] : null;
3060
+ checkDocumentStyles(document, ts);
3061
+ }
3062
+ }
3063
+ function reset$8() {
3064
+ sheetAdoptionState = [];
3065
+ sheetUpdateState = [];
3066
+ }
3067
+ function stop$h() {
3068
+ styleSheetMap = {};
3069
+ styleTimeMap = {};
3070
+ documentNodes = [];
3071
+ reset$8();
3072
+ }
3073
+ function trackStyleChange(time, id, operation, cssRules) {
3074
+ sheetUpdateState.push({
3075
+ time: time,
3076
+ event: 46 /* Event.StyleSheetUpdate */,
3077
+ data: {
3078
+ id: id,
3079
+ operation: operation,
3080
+ cssRules: cssRules
3081
+ }
3082
+ });
3083
+ encode$4(46 /* Event.StyleSheetUpdate */);
3084
+ }
3085
+ function trackStyleAdoption(time, id, operation, newIds) {
3086
+ sheetAdoptionState.push({
3087
+ time: time,
3088
+ event: 45 /* Event.StyleSheetAdoption */,
3089
+ data: {
3090
+ id: id,
3091
+ operation: operation,
3092
+ newIds: newIds
3199
3093
  }
3094
+ });
3095
+ encode$4(45 /* Event.StyleSheetAdoption */);
3096
+ }
3097
+ function arraysEqual(a, b) {
3098
+ if (a.length !== b.length) {
3099
+ return false;
3200
3100
  }
3201
- catch (e) {
3202
- log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
3101
+ return a.every(function (value, index) { return value === b[index]; });
3102
+ }
3103
+
3104
+ var state$2 = [];
3105
+ var elementAnimate = null;
3106
+ var animationPlay = null;
3107
+ var animationPause = null;
3108
+ var animationCancel = null;
3109
+ var animationFinish = null;
3110
+ var animationId = 'clarityAnimationId';
3111
+ var operationCount = 'clarityOperationCount';
3112
+ var maxOperations = 20;
3113
+ function start$i() {
3114
+ if (window["Animation"] &&
3115
+ window["KeyframeEffect"] &&
3116
+ window["KeyframeEffect"].prototype.getKeyframes &&
3117
+ window["KeyframeEffect"].prototype.getTiming) {
3118
+ reset$7();
3119
+ overrideAnimationHelper(animationPlay, "play");
3120
+ overrideAnimationHelper(animationPause, "pause");
3121
+ overrideAnimationHelper(animationCancel, "cancel");
3122
+ overrideAnimationHelper(animationFinish, "finish");
3123
+ if (elementAnimate === null) {
3124
+ elementAnimate = Element.prototype.animate;
3125
+ Element.prototype.animate = function () {
3126
+ var createdAnimation = elementAnimate.apply(this, arguments);
3127
+ trackAnimationOperation(createdAnimation, "play");
3128
+ return createdAnimation;
3129
+ };
3130
+ }
3203
3131
  }
3204
3132
  }
3205
- function monitor(frame) {
3206
- // Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
3207
- // This includes cases where iframe location is updated without explicitly updating src attribute
3208
- // E.g. iframe.contentWindow.location.href = "new-location";
3209
- if (has(frame) === false) {
3210
- bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
3133
+ function reset$7() {
3134
+ state$2 = [];
3135
+ }
3136
+ function track$4(time, id, operation, keyFrames, timing, targetId, timeline) {
3137
+ state$2.push({
3138
+ time: time,
3139
+ event: 44 /* Event.Animation */,
3140
+ data: {
3141
+ id: id,
3142
+ operation: operation,
3143
+ keyFrames: keyFrames,
3144
+ timing: timing,
3145
+ targetId: targetId,
3146
+ timeline: timeline
3147
+ }
3148
+ });
3149
+ encode$4(44 /* Event.Animation */);
3150
+ }
3151
+ function stop$g() {
3152
+ reset$7();
3153
+ }
3154
+ function overrideAnimationHelper(functionToOverride, name) {
3155
+ if (functionToOverride === null) {
3156
+ functionToOverride = Animation.prototype[name];
3157
+ Animation.prototype[name] = function () {
3158
+ trackAnimationOperation(this, name);
3159
+ return functionToOverride.apply(this, arguments);
3160
+ };
3211
3161
  }
3212
3162
  }
3213
- function stop$f() {
3214
- for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
3215
- var observer = observers_1[_i];
3216
- if (observer) {
3217
- observer.disconnect();
3163
+ function trackAnimationOperation(animation, name) {
3164
+ if (active()) {
3165
+ var effect = animation.effect;
3166
+ var target = getId(effect.target);
3167
+ if (target !== null && effect.getKeyframes && effect.getTiming) {
3168
+ if (!animation[animationId]) {
3169
+ animation[animationId] = shortid();
3170
+ animation[operationCount] = 0;
3171
+ var keyframes = effect.getKeyframes();
3172
+ var timing = effect.getTiming();
3173
+ track$4(time(), animation[animationId], 0 /* AnimationOperation.Create */, JSON.stringify(keyframes), JSON.stringify(timing), target);
3174
+ }
3175
+ if (animation[operationCount]++ < maxOperations) {
3176
+ var operation = null;
3177
+ switch (name) {
3178
+ case "play":
3179
+ operation = 1 /* AnimationOperation.Play */;
3180
+ break;
3181
+ case "pause":
3182
+ operation = 2 /* AnimationOperation.Pause */;
3183
+ break;
3184
+ case "cancel":
3185
+ operation = 3 /* AnimationOperation.Cancel */;
3186
+ break;
3187
+ case "finish":
3188
+ operation = 4 /* AnimationOperation.Finish */;
3189
+ break;
3190
+ }
3191
+ if (operation) {
3192
+ track$4(time(), animation[animationId], operation);
3193
+ }
3194
+ }
3218
3195
  }
3219
3196
  }
3220
- observers = [];
3221
- history$4 = {};
3222
- mutations = [];
3223
- queue$1 = [];
3224
- activePeriod = 0;
3225
- timeout$1 = null;
3226
- }
3227
- function active$2() {
3228
- activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
3229
- }
3230
- function handle$1(m) {
3231
- // Queue up mutation records for asynchronous processing
3232
- var now = time();
3233
- track$7(6 /* Event.Mutation */, now);
3234
- mutations.push({ time: now, mutations: m });
3235
- schedule$1(process$1, 1 /* Priority.High */).then(function () {
3236
- setTimeout(compute$9);
3237
- measure(compute$7)();
3238
- });
3239
- }
3240
- function process$1() {
3197
+ }
3198
+
3199
+ function encode$4 (type, timer, ts) {
3200
+ if (timer === void 0) { timer = null; }
3201
+ if (ts === void 0) { ts = null; }
3241
3202
  return __awaiter(this, void 0, void 0, function () {
3242
- var timer, record, instance, _i, _a, mutation, state, target, type, value;
3243
- return __generator(this, function (_b) {
3244
- switch (_b.label) {
3203
+ 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;
3204
+ return __generator(this, function (_l) {
3205
+ switch (_l.label) {
3245
3206
  case 0:
3246
- timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
3247
- start$y(timer);
3248
- _b.label = 1;
3207
+ eventTime = ts || time();
3208
+ tokens = [eventTime, type];
3209
+ _a = type;
3210
+ switch (_a) {
3211
+ case 8 /* Event.Document */: return [3 /*break*/, 1];
3212
+ case 7 /* Event.Region */: return [3 /*break*/, 2];
3213
+ case 45 /* Event.StyleSheetAdoption */: return [3 /*break*/, 3];
3214
+ case 46 /* Event.StyleSheetUpdate */: return [3 /*break*/, 3];
3215
+ case 44 /* Event.Animation */: return [3 /*break*/, 4];
3216
+ case 5 /* Event.Discover */: return [3 /*break*/, 5];
3217
+ case 6 /* Event.Mutation */: return [3 /*break*/, 5];
3218
+ }
3219
+ return [3 /*break*/, 12];
3249
3220
  case 1:
3250
- if (!(mutations.length > 0)) return [3 /*break*/, 8];
3251
- record = mutations.shift();
3252
- instance = time();
3253
- _i = 0, _a = record.mutations;
3254
- _b.label = 2;
3221
+ d = data$c;
3222
+ tokens.push(d.width);
3223
+ tokens.push(d.height);
3224
+ track$8(type, d.width, d.height);
3225
+ queue(tokens);
3226
+ return [3 /*break*/, 12];
3255
3227
  case 2:
3256
- if (!(_i < _a.length)) return [3 /*break*/, 6];
3257
- mutation = _a[_i];
3258
- state = state$a(timer);
3259
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
3260
- return [4 /*yield*/, suspend$1(timer)];
3261
- case 3:
3262
- state = _b.sent();
3263
- _b.label = 4;
3264
- case 4:
3265
- if (state === 2 /* Task.Stop */) {
3266
- return [3 /*break*/, 6];
3228
+ for (_i = 0, _b = state$1; _i < _b.length; _i++) {
3229
+ r = _b[_i];
3230
+ tokens = [r.time, 7 /* Event.Region */];
3231
+ tokens.push(r.data.id);
3232
+ tokens.push(r.data.interaction);
3233
+ tokens.push(r.data.visibility);
3234
+ tokens.push(r.data.name);
3235
+ queue(tokens);
3267
3236
  }
3268
- target = mutation.target;
3269
- type = config$1.throttleDom ? track$3(mutation, timer, instance, record.time) : mutation.type;
3270
- if (type && target && target.ownerDocument) {
3271
- parse$1(target.ownerDocument);
3237
+ reset$6();
3238
+ return [3 /*break*/, 12];
3239
+ case 3:
3240
+ for (_c = 0, _d = sheetAdoptionState; _c < _d.length; _c++) {
3241
+ entry = _d[_c];
3242
+ tokens = [entry.time, entry.event];
3243
+ tokens.push(entry.data.id);
3244
+ tokens.push(entry.data.operation);
3245
+ tokens.push(entry.data.newIds);
3246
+ queue(tokens);
3272
3247
  }
3273
- if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
3274
- parse$1(target);
3248
+ for (_e = 0, _f = sheetUpdateState; _e < _f.length; _e++) {
3249
+ entry = _f[_e];
3250
+ tokens = [entry.time, entry.event];
3251
+ tokens.push(entry.data.id);
3252
+ tokens.push(entry.data.operation);
3253
+ tokens.push(entry.data.cssRules);
3254
+ queue(tokens);
3275
3255
  }
3276
- switch (type) {
3277
- case "attributes" /* Constant.Attributes */:
3278
- processNode(target, 3 /* Source.Attributes */, record.time);
3279
- break;
3280
- case "characterData" /* Constant.CharacterData */:
3281
- processNode(target, 4 /* Source.CharacterData */, record.time);
3282
- break;
3283
- case "childList" /* Constant.ChildList */:
3284
- processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer, record.time);
3285
- processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer, record.time);
3286
- break;
3287
- case "suspend" /* Constant.Suspend */:
3288
- value = get(target);
3289
- if (value) {
3290
- value.metadata.suspend = true;
3291
- }
3292
- break;
3256
+ reset$8();
3257
+ return [3 /*break*/, 12];
3258
+ case 4:
3259
+ for (_g = 0, _h = state$2; _g < _h.length; _g++) {
3260
+ entry = _h[_g];
3261
+ tokens = [entry.time, entry.event];
3262
+ tokens.push(entry.data.id);
3263
+ tokens.push(entry.data.operation);
3264
+ tokens.push(entry.data.keyFrames);
3265
+ tokens.push(entry.data.timing);
3266
+ tokens.push(entry.data.timeline);
3267
+ tokens.push(entry.data.targetId);
3268
+ queue(tokens);
3293
3269
  }
3294
- _b.label = 5;
3270
+ reset$7();
3271
+ return [3 /*break*/, 12];
3295
3272
  case 5:
3296
- _i++;
3297
- return [3 /*break*/, 2];
3298
- case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
3273
+ // Check if we are operating within the context of the current page
3274
+ if (state$a(timer) === 2 /* Task.Stop */) {
3275
+ return [3 /*break*/, 12];
3276
+ }
3277
+ values = updates$2();
3278
+ if (!(values.length > 0)) return [3 /*break*/, 11];
3279
+ _j = 0, values_1 = values;
3280
+ _l.label = 6;
3281
+ case 6:
3282
+ if (!(_j < values_1.length)) return [3 /*break*/, 10];
3283
+ value = values_1[_j];
3284
+ state = state$a(timer);
3285
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 8];
3286
+ return [4 /*yield*/, suspend$1(timer)];
3299
3287
  case 7:
3300
- _b.sent();
3301
- return [3 /*break*/, 1];
3288
+ state = _l.sent();
3289
+ _l.label = 8;
3302
3290
  case 8:
3303
- stop$w(timer);
3304
- return [2 /*return*/];
3291
+ if (state === 2 /* Task.Stop */) {
3292
+ return [3 /*break*/, 10];
3293
+ }
3294
+ data = value.data;
3295
+ active = value.metadata.active;
3296
+ suspend = value.metadata.suspend;
3297
+ privacy = value.metadata.privacy;
3298
+ mangle = shouldMangle(value);
3299
+ keys = active ? ["tag", "attributes", "value"] : ["tag"];
3300
+ for (_k = 0, keys_1 = keys; _k < keys_1.length; _k++) {
3301
+ key = keys_1[_k];
3302
+ if (data[key]) {
3303
+ switch (key) {
3304
+ case "tag":
3305
+ box = size(value);
3306
+ factor = mangle ? -1 : 1;
3307
+ tokens.push(value.id * factor);
3308
+ if (value.parent && active) {
3309
+ tokens.push(value.parent);
3310
+ if (value.previous) {
3311
+ tokens.push(value.previous);
3312
+ }
3313
+ }
3314
+ tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
3315
+ if (box && box.length === 2) {
3316
+ tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
3317
+ }
3318
+ break;
3319
+ case "attributes":
3320
+ for (attr in data[key]) {
3321
+ if (data[key][attr] !== undefined) {
3322
+ tokens.push(attribute(attr, data[key][attr], privacy));
3323
+ }
3324
+ }
3325
+ break;
3326
+ case "value":
3327
+ check$4(value.metadata.fraud, value.id, data[key]);
3328
+ tokens.push(text$1(data[key], data.tag, privacy, mangle));
3329
+ break;
3330
+ }
3331
+ }
3332
+ }
3333
+ _l.label = 9;
3334
+ case 9:
3335
+ _j++;
3336
+ return [3 /*break*/, 6];
3337
+ case 10:
3338
+ if (type === 6 /* Event.Mutation */) {
3339
+ activity(eventTime);
3340
+ }
3341
+ queue(tokenize(tokens), !config$1.lean);
3342
+ _l.label = 11;
3343
+ case 11: return [3 /*break*/, 12];
3344
+ case 12: return [2 /*return*/];
3305
3345
  }
3306
3346
  });
3307
3347
  });
3308
3348
  }
3309
- function track$3(m, timer, instance, timestamp) {
3310
- var value = m.target ? get(m.target.parentNode) : null;
3311
- // Check if the parent is already discovered and that the parent is not the document root
3312
- if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
3313
- // calculate inactive period based on the timestamp of the mutation not when the mutation is processed
3314
- var inactive = timestamp > activePeriod;
3315
- var target = get(m.target);
3316
- var element = target && target.selector ? target.selector.join() : m.target.nodeName;
3317
- var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
3318
- // We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
3319
- // repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
3320
- // In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
3321
- var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
3322
- // Initialize an entry if it doesn't already exist
3323
- history$4[key] = key in history$4 ? history$4[key] : [0, instance];
3324
- var h = history$4[key];
3325
- // Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
3326
- if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
3327
- processNodeList(h[2], 2 /* Source.ChildListRemove */, timer);
3349
+ function shouldMangle(value) {
3350
+ var privacy = value.metadata.privacy;
3351
+ return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
3352
+ }
3353
+ function size(value) {
3354
+ if (value.metadata.size !== null && value.metadata.size.length === 0) {
3355
+ var img = getNode(value.id);
3356
+ if (img) {
3357
+ return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
3358
+ }
3359
+ }
3360
+ return value.metadata.size;
3361
+ }
3362
+ function str$1(input) {
3363
+ return input.toString(36);
3364
+ }
3365
+ function attribute(key, value, privacy) {
3366
+ return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
3367
+ }
3368
+
3369
+ var state$1 = [];
3370
+ var regionMap = null; // Maps region nodes => region name
3371
+ var regions = {};
3372
+ var queue$1 = [];
3373
+ var watch = false;
3374
+ var observer$1 = null;
3375
+ function start$h() {
3376
+ reset$6();
3377
+ observer$1 = null;
3378
+ regionMap = new WeakMap();
3379
+ regions = {};
3380
+ queue$1 = [];
3381
+ watch = window["IntersectionObserver"] ? true : false;
3382
+ }
3383
+ function observe$1(node, name) {
3384
+ if (regionMap.has(node) === false) {
3385
+ regionMap.set(node, name);
3386
+ observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$1, {
3387
+ // Get notified as intersection continues to change
3388
+ // This allows us to process regions that get partially hidden during the lifetime of the page
3389
+ // See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
3390
+ // By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
3391
+ threshold: [0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
3392
+ }) : observer$1;
3393
+ if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
3394
+ observer$1.observe(node);
3328
3395
  }
3329
- // Update the counter
3330
- h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
3331
- h[1] = instance;
3332
- // Return updated mutation type based on if we have already hit the threshold or not
3333
- if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
3334
- // Store a reference to removedNodes so we can process them later
3335
- // when we resume mutations again on user interactions
3336
- h[2] = m.removedNodes;
3337
- return "suspend" /* Constant.Suspend */;
3396
+ }
3397
+ }
3398
+ function exists(node) {
3399
+ // Check if regionMap is not null before looking up a node
3400
+ // Since, dom module stops after region module, it's possible that we may set regionMap to be null
3401
+ // and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
3402
+ return regionMap && regionMap.has(node);
3403
+ }
3404
+ function track$3(id, event) {
3405
+ var node = getNode(id);
3406
+ var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
3407
+ // Determine the interaction state based on incoming event
3408
+ var interaction = 16 /* InteractionState.None */;
3409
+ switch (event) {
3410
+ case 9 /* Event.Click */:
3411
+ interaction = 20 /* InteractionState.Clicked */;
3412
+ break;
3413
+ case 27 /* Event.Input */:
3414
+ interaction = 30 /* InteractionState.Input */;
3415
+ break;
3416
+ }
3417
+ // Process updates to this region, if applicable
3418
+ process$1(node, data, interaction, data.visibility);
3419
+ }
3420
+ function compute$6() {
3421
+ // Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
3422
+ // This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
3423
+ // For those cases we add them to the queue and re-process them below
3424
+ var q = [];
3425
+ for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
3426
+ var r = queue_1[_i];
3427
+ var id = getId(r.node);
3428
+ if (id) {
3429
+ r.state.data.id = id;
3430
+ regions[id] = r.state.data;
3431
+ state$1.push(r.state);
3338
3432
  }
3339
- else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
3340
- return "" /* Constant.Empty */;
3433
+ else {
3434
+ q.push(r);
3341
3435
  }
3342
3436
  }
3343
- return m.type;
3344
- }
3345
- function names(nodes) {
3346
- var output = [];
3347
- for (var i = 0; nodes && i < nodes.length; i++) {
3348
- output.push(nodes[i].nodeName);
3437
+ queue$1 = q;
3438
+ // Schedule encode only when we have at least one valid data entry
3439
+ if (state$1.length > 0) {
3440
+ encode$4(7 /* Event.Region */);
3349
3441
  }
3350
- return output.join();
3351
3442
  }
3352
- function processNodeList(list, source, timer, timestamp) {
3353
- return __awaiter(this, void 0, void 0, function () {
3354
- var length, i, state;
3355
- return __generator(this, function (_a) {
3356
- switch (_a.label) {
3357
- case 0:
3358
- length = list ? list.length : 0;
3359
- i = 0;
3360
- _a.label = 1;
3361
- case 1:
3362
- if (!(i < length)) return [3 /*break*/, 6];
3363
- if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
3364
- traverse(list[i], timer, source);
3365
- return [3 /*break*/, 5];
3366
- case 2:
3367
- state = state$a(timer);
3368
- if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
3369
- return [4 /*yield*/, suspend$1(timer)];
3370
- case 3:
3371
- state = _a.sent();
3372
- _a.label = 4;
3373
- case 4:
3374
- if (state === 2 /* Task.Stop */) {
3375
- return [3 /*break*/, 6];
3376
- }
3377
- processNode(list[i], source);
3378
- _a.label = 5;
3379
- case 5:
3380
- i++;
3381
- return [3 /*break*/, 1];
3382
- case 6: return [2 /*return*/];
3443
+ function handler$1(entries) {
3444
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
3445
+ var entry = entries_1[_i];
3446
+ var target = entry.target;
3447
+ var rect = entry.boundingClientRect;
3448
+ var overlap = entry.intersectionRect;
3449
+ var viewport = entry.rootBounds;
3450
+ // Only capture regions that have non-zero width or height to avoid tracking and sending regions
3451
+ // that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
3452
+ // like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
3453
+ // 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
3454
+ if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
3455
+ var id = target ? getId(target) : null;
3456
+ var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
3457
+ // For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
3458
+ // However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
3459
+ var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
3460
+ var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
3461
+ // If an element is either visible or was visible and has been scrolled to the end
3462
+ // 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.
3463
+ // 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
3464
+ var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
3465
+ // Process updates to this region, if applicable
3466
+ process$1(target, data, data.interaction, (scrolledToEnd ?
3467
+ 13 /* RegionVisibility.ScrolledToEnd */ :
3468
+ (visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
3469
+ // Stop observing this element now that we have already received scrolled signal
3470
+ if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
3471
+ observer$1.unobserve(target);
3383
3472
  }
3384
- });
3385
- });
3386
- }
3387
- function schedule(node) {
3388
- // Only schedule manual trigger for this node if it's not already in the queue
3389
- if (queue$1.indexOf(node) < 0) {
3390
- queue$1.push(node);
3473
+ }
3391
3474
  }
3392
- // Cancel any previous trigger before scheduling a new one.
3393
- // It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
3394
- // And in those cases we do not wish to monitor changes multiple times for the same node.
3395
- if (timeout$1) {
3396
- clearTimeout(timeout$1);
3475
+ if (state$1.length > 0) {
3476
+ encode$4(7 /* Event.Region */);
3397
3477
  }
3398
- timeout$1 = setTimeout(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
3399
- return node;
3400
3478
  }
3401
- function trigger$2() {
3402
- for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
3403
- var node = queue_1[_i];
3404
- // Generate a mutation for this node only if it still exists
3405
- if (node) {
3406
- var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
3407
- // Skip re-processing shadowRoot if it was already discovered
3408
- if (shadowRoot && has(node)) {
3409
- continue;
3410
- }
3411
- generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
3479
+ function process$1(n, d, s, v) {
3480
+ // Check if received a state that supersedes existing state
3481
+ var updated = s > d.interaction || v > d.visibility;
3482
+ d.interaction = s > d.interaction ? s : d.interaction;
3483
+ d.visibility = v > d.visibility ? v : d.visibility;
3484
+ // If the corresponding node is already discovered, update the internal state
3485
+ // Otherwise, track it in a queue to reprocess later.
3486
+ if (d.id) {
3487
+ if ((d.id in regions && updated) || !(d.id in regions)) {
3488
+ regions[d.id] = d;
3489
+ state$1.push(clone$1(d));
3412
3490
  }
3413
3491
  }
3414
- queue$1 = [];
3492
+ else {
3493
+ // Get the time before adding to queue to ensure accurate event time
3494
+ queue$1.push({ node: n, state: clone$1(d) });
3495
+ }
3415
3496
  }
3416
- function generate(target, type) {
3417
- measure(handle$1)([{
3418
- addedNodes: [target],
3419
- attributeName: null,
3420
- attributeNamespace: null,
3421
- nextSibling: null,
3422
- oldValue: null,
3423
- previousSibling: null,
3424
- removedNodes: [],
3425
- target: target,
3426
- type: type
3427
- }]);
3497
+ function clone$1(r) {
3498
+ return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
3499
+ }
3500
+ function reset$6() {
3501
+ state$1 = [];
3502
+ }
3503
+ function stop$f() {
3504
+ reset$6();
3505
+ regionMap = null;
3506
+ regions = {};
3507
+ queue$1 = [];
3508
+ if (observer$1) {
3509
+ observer$1.disconnect();
3510
+ observer$1 = null;
3511
+ }
3512
+ watch = false;
3428
3513
  }
3429
3514
 
3430
3515
  function target(evt) {
@@ -3445,7 +3530,7 @@ function metadata$2(node, event, text) {
3445
3530
  output.hash = value.hash;
3446
3531
  output.privacy = metadata_1.privacy;
3447
3532
  if (value.region) {
3448
- track$4(value.region, event);
3533
+ track$3(value.region, event);
3449
3534
  }
3450
3535
  if (metadata_1.fraud) {
3451
3536
  check$4(metadata_1.fraud, value.id, text || value.data.value);
@@ -3472,7 +3557,7 @@ function encode$3 (type, ts) {
3472
3557
  case 18 /* Event.TouchEnd */:
3473
3558
  case 19 /* Event.TouchMove */:
3474
3559
  case 20 /* Event.TouchCancel */:
3475
- for (_i = 0, _a = state$3; _i < _a.length; _i++) {
3560
+ for (_i = 0, _a = state$5; _i < _a.length; _i++) {
3476
3561
  entry = _a[_i];
3477
3562
  pTarget = metadata$2(entry.data.target, entry.event);
3478
3563
  if (pTarget.id > 0) {
@@ -3484,10 +3569,10 @@ function encode$3 (type, ts) {
3484
3569
  track$8(entry.event, entry.data.x, entry.data.y);
3485
3570
  }
3486
3571
  }
3487
- reset$c();
3572
+ reset$f();
3488
3573
  break;
3489
3574
  case 9 /* Event.Click */:
3490
- for (_b = 0, _c = state$6; _b < _c.length; _b++) {
3575
+ for (_b = 0, _c = state$8; _b < _c.length; _b++) {
3491
3576
  entry = _c[_b];
3492
3577
  cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
3493
3578
  tokens = [entry.time, entry.event];
@@ -3507,10 +3592,10 @@ function encode$3 (type, ts) {
3507
3592
  queue(tokens);
3508
3593
  track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
3509
3594
  }
3510
- reset$f();
3595
+ reset$i();
3511
3596
  break;
3512
3597
  case 38 /* Event.Clipboard */:
3513
- for (_d = 0, _e = state$5; _d < _e.length; _d++) {
3598
+ for (_d = 0, _e = state$7; _d < _e.length; _d++) {
3514
3599
  entry = _e[_d];
3515
3600
  tokens = [entry.time, entry.event];
3516
3601
  target = metadata$2(entry.data.target, entry.event);
@@ -3520,24 +3605,24 @@ function encode$3 (type, ts) {
3520
3605
  queue(tokens);
3521
3606
  }
3522
3607
  }
3523
- reset$e();
3608
+ reset$h();
3524
3609
  break;
3525
3610
  case 11 /* Event.Resize */:
3526
3611
  r = data$b;
3527
3612
  tokens.push(r.width);
3528
3613
  tokens.push(r.height);
3529
3614
  track$8(type, r.width, r.height);
3530
- reset$b();
3615
+ reset$e();
3531
3616
  queue(tokens);
3532
3617
  break;
3533
3618
  case 26 /* Event.Unload */:
3534
3619
  u = data$9;
3535
3620
  tokens.push(u.name);
3536
- reset$7();
3621
+ reset$a();
3537
3622
  queue(tokens);
3538
3623
  break;
3539
3624
  case 27 /* Event.Input */:
3540
- for (_f = 0, _g = state$4; _f < _g.length; _f++) {
3625
+ for (_f = 0, _g = state$6; _f < _g.length; _f++) {
3541
3626
  entry = _g[_f];
3542
3627
  iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
3543
3628
  tokens = [entry.time, entry.event];
@@ -3545,7 +3630,7 @@ function encode$3 (type, ts) {
3545
3630
  tokens.push(text$1(entry.data.value, "input", iTarget.privacy));
3546
3631
  queue(tokens);
3547
3632
  }
3548
- reset$d();
3633
+ reset$g();
3549
3634
  break;
3550
3635
  case 21 /* Event.Selection */:
3551
3636
  s = data$a;
@@ -3556,12 +3641,12 @@ function encode$3 (type, ts) {
3556
3641
  tokens.push(s.startOffset);
3557
3642
  tokens.push(endTarget.id);
3558
3643
  tokens.push(s.endOffset);
3559
- reset$9();
3644
+ reset$c();
3560
3645
  queue(tokens);
3561
3646
  }
3562
3647
  break;
3563
3648
  case 10 /* Event.Scroll */:
3564
- for (_h = 0, _j = state$2; _h < _j.length; _h++) {
3649
+ for (_h = 0, _j = state$4; _h < _j.length; _h++) {
3565
3650
  entry = _j[_h];
3566
3651
  sTarget = metadata$2(entry.data.target, entry.event);
3567
3652
  top_1 = metadata$2(entry.data.top, entry.event);
@@ -3579,10 +3664,10 @@ function encode$3 (type, ts) {
3579
3664
  track$8(entry.event, entry.data.x, entry.data.y, entry.time);
3580
3665
  }
3581
3666
  }
3582
- reset$a();
3667
+ reset$d();
3583
3668
  break;
3584
3669
  case 42 /* Event.Change */:
3585
- for (_k = 0, _l = state$7; _k < _l.length; _k++) {
3670
+ for (_k = 0, _l = state$9; _k < _l.length; _k++) {
3586
3671
  entry = _l[_k];
3587
3672
  tokens = [entry.time, entry.event];
3588
3673
  target = metadata$2(entry.data.target, entry.event);
@@ -3595,10 +3680,10 @@ function encode$3 (type, ts) {
3595
3680
  queue(tokens);
3596
3681
  }
3597
3682
  }
3598
- reset$g();
3683
+ reset$j();
3599
3684
  break;
3600
3685
  case 39 /* Event.Submit */:
3601
- for (_m = 0, _o = state$1; _m < _o.length; _m++) {
3686
+ for (_m = 0, _o = state$3; _m < _o.length; _m++) {
3602
3687
  entry = _o[_m];
3603
3688
  tokens = [entry.time, entry.event];
3604
3689
  target = metadata$2(entry.data.target, entry.event);
@@ -3607,7 +3692,7 @@ function encode$3 (type, ts) {
3607
3692
  queue(tokens);
3608
3693
  }
3609
3694
  }
3610
- reset$8();
3695
+ reset$b();
3611
3696
  break;
3612
3697
  case 22 /* Event.Timeline */:
3613
3698
  for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
@@ -3628,7 +3713,7 @@ function encode$3 (type, ts) {
3628
3713
  tokens.push(v.visible);
3629
3714
  queue(tokens);
3630
3715
  visibility(t, v.visible);
3631
- reset$6();
3716
+ reset$9();
3632
3717
  break;
3633
3718
  }
3634
3719
  return [2 /*return*/];
@@ -3776,10 +3861,10 @@ function upload(final) {
3776
3861
  }
3777
3862
  // CAUTION: Ensure "transmit" is set to false in the queue function for following events
3778
3863
  // Otherwise you run a risk of infinite loop.
3779
- compute$7();
3864
+ compute$6();
3780
3865
  compute$5();
3781
3866
  compute$a();
3782
- compute$8();
3867
+ compute$7();
3783
3868
  last = final === true;
3784
3869
  e = JSON.stringify(envelope(last));
3785
3870
  a = "[".concat(analysis.join(), "]");
@@ -5006,8 +5091,8 @@ var diagnostic = /*#__PURE__*/Object.freeze({
5006
5091
  function start$4() {
5007
5092
  schedule$1(discover, 1 /* Priority.High */).then(function () {
5008
5093
  measure(compute$9)();
5009
- measure(compute$7)();
5010
5094
  measure(compute$6)();
5095
+ measure(compute$8)();
5011
5096
  });
5012
5097
  }
5013
5098
  function discover() {
@@ -5019,10 +5104,10 @@ function discover() {
5019
5104
  ts = time();
5020
5105
  timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
5021
5106
  start$y(timer);
5022
- return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */)];
5107
+ return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */, ts)];
5023
5108
  case 1:
5024
5109
  _a.sent();
5025
- checkDocumentStyles(document);
5110
+ checkDocumentStyles(document, ts);
5026
5111
  return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
5027
5112
  case 2:
5028
5113
  _a.sent();
@@ -5037,28 +5122,28 @@ function start$3() {
5037
5122
  // The order below is important
5038
5123
  // and is determined by interdependencies of modules
5039
5124
  start$x();
5040
- start$u();
5125
+ start$h();
5041
5126
  start$z();
5042
5127
  if (config$1.delayDom) {
5043
5128
  // Lazy load layout module as part of page load time performance improvements experiment
5044
5129
  bind(window, 'load', function () {
5045
- start$h();
5130
+ start$k();
5046
5131
  });
5047
5132
  }
5048
5133
  else {
5049
- start$h();
5134
+ start$k();
5050
5135
  }
5051
5136
  start$4();
5052
- start$w();
5053
- start$v();
5137
+ start$j();
5138
+ start$i();
5054
5139
  }
5055
5140
  function stop$3() {
5056
- stop$s();
5057
- stop$x();
5058
5141
  stop$f();
5142
+ stop$x();
5143
+ stop$i();
5059
5144
  stop$v();
5060
- stop$u();
5061
- stop$t();
5145
+ stop$h();
5146
+ stop$g();
5062
5147
  }
5063
5148
 
5064
5149
  var layout = /*#__PURE__*/Object.freeze({