clarity-js 0.7.43 → 0.7.45

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