clarity-js 0.8.41 → 0.8.42

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.
Files changed (113) hide show
  1. package/README.md +26 -26
  2. package/build/clarity.extended.js +1 -1
  3. package/build/clarity.insight.js +1 -1
  4. package/build/clarity.js +6027 -6027
  5. package/build/clarity.min.js +1 -1
  6. package/build/clarity.module.js +6027 -6027
  7. package/build/clarity.performance.js +1 -1
  8. package/package.json +70 -70
  9. package/rollup.config.ts +161 -161
  10. package/src/clarity.ts +65 -65
  11. package/src/core/api.ts +8 -8
  12. package/src/core/config.ts +29 -29
  13. package/src/core/copy.ts +3 -3
  14. package/src/core/event.ts +53 -53
  15. package/src/core/hash.ts +19 -19
  16. package/src/core/history.ts +71 -71
  17. package/src/core/index.ts +81 -81
  18. package/src/core/measure.ts +19 -19
  19. package/src/core/report.ts +28 -28
  20. package/src/core/scrub.ts +202 -202
  21. package/src/core/task.ts +181 -181
  22. package/src/core/throttle.ts +46 -46
  23. package/src/core/time.ts +26 -26
  24. package/src/core/timeout.ts +10 -10
  25. package/src/core/version.ts +2 -2
  26. package/src/data/baseline.ts +162 -162
  27. package/src/data/compress.ts +31 -31
  28. package/src/data/consent.ts +77 -77
  29. package/src/data/custom.ts +23 -23
  30. package/src/data/dimension.ts +53 -53
  31. package/src/data/encode.ts +155 -155
  32. package/src/data/envelope.ts +53 -53
  33. package/src/data/extract.ts +211 -211
  34. package/src/data/index.ts +50 -50
  35. package/src/data/limit.ts +44 -44
  36. package/src/data/metadata.ts +408 -408
  37. package/src/data/metric.ts +51 -51
  38. package/src/data/ping.ts +36 -36
  39. package/src/data/signal.ts +30 -30
  40. package/src/data/summary.ts +34 -34
  41. package/src/data/token.ts +39 -39
  42. package/src/data/upgrade.ts +44 -44
  43. package/src/data/upload.ts +333 -333
  44. package/src/data/variable.ts +83 -83
  45. package/src/diagnostic/encode.ts +40 -40
  46. package/src/diagnostic/fraud.ts +36 -36
  47. package/src/diagnostic/index.ts +13 -13
  48. package/src/diagnostic/internal.ts +28 -28
  49. package/src/diagnostic/script.ts +35 -35
  50. package/src/dynamic/agent/blank.ts +2 -2
  51. package/src/dynamic/agent/crisp.ts +40 -40
  52. package/src/dynamic/agent/encode.ts +25 -25
  53. package/src/dynamic/agent/index.ts +8 -8
  54. package/src/dynamic/agent/livechat.ts +58 -58
  55. package/src/dynamic/agent/tidio.ts +44 -44
  56. package/src/global.ts +6 -6
  57. package/src/index.ts +9 -9
  58. package/src/insight/blank.ts +14 -14
  59. package/src/insight/encode.ts +60 -60
  60. package/src/insight/snapshot.ts +114 -114
  61. package/src/interaction/change.ts +38 -38
  62. package/src/interaction/click.ts +173 -173
  63. package/src/interaction/clipboard.ts +32 -32
  64. package/src/interaction/encode.ts +210 -210
  65. package/src/interaction/index.ts +60 -60
  66. package/src/interaction/input.ts +57 -57
  67. package/src/interaction/pointer.ts +137 -137
  68. package/src/interaction/resize.ts +50 -50
  69. package/src/interaction/scroll.ts +129 -129
  70. package/src/interaction/selection.ts +66 -66
  71. package/src/interaction/submit.ts +30 -30
  72. package/src/interaction/timeline.ts +69 -69
  73. package/src/interaction/unload.ts +26 -26
  74. package/src/interaction/visibility.ts +27 -27
  75. package/src/layout/animation.ts +133 -133
  76. package/src/layout/custom.ts +42 -42
  77. package/src/layout/discover.ts +31 -31
  78. package/src/layout/document.ts +46 -46
  79. package/src/layout/dom.ts +439 -439
  80. package/src/layout/encode.ts +154 -154
  81. package/src/layout/index.ts +42 -42
  82. package/src/layout/mutation.ts +411 -411
  83. package/src/layout/node.ts +294 -294
  84. package/src/layout/offset.ts +19 -19
  85. package/src/layout/region.ts +151 -151
  86. package/src/layout/schema.ts +63 -63
  87. package/src/layout/selector.ts +82 -82
  88. package/src/layout/style.ts +159 -159
  89. package/src/layout/target.ts +32 -32
  90. package/src/layout/traverse.ts +27 -27
  91. package/src/performance/blank.ts +9 -9
  92. package/src/performance/encode.ts +31 -31
  93. package/src/performance/index.ts +12 -12
  94. package/src/performance/interaction.ts +125 -125
  95. package/src/performance/navigation.ts +31 -31
  96. package/src/performance/observer.ts +112 -112
  97. package/src/queue.ts +33 -33
  98. package/test/core.test.ts +139 -139
  99. package/test/helper.ts +162 -162
  100. package/test/html/core.html +27 -27
  101. package/test/stub.test.ts +7 -7
  102. package/test/tsconfig.test.json +5 -5
  103. package/tsconfig.json +21 -21
  104. package/tslint.json +32 -32
  105. package/types/agent.d.ts +39 -39
  106. package/types/core.d.ts +150 -150
  107. package/types/data.d.ts +571 -571
  108. package/types/diagnostic.d.ts +24 -24
  109. package/types/global.d.ts +30 -30
  110. package/types/index.d.ts +40 -40
  111. package/types/interaction.d.ts +177 -177
  112. package/types/layout.d.ts +276 -276
  113. package/types/performance.d.ts +31 -31
package/src/clarity.ts CHANGED
@@ -1,66 +1,66 @@
1
- import { Config, Module } from "@clarity-types/core";
2
- import { Constant } from "@clarity-types/data";
3
- import * as queue from "@src/queue";
4
- import * as core from "@src/core";
5
- import measure from "@src/core/measure";
6
- import * as task from "@src/core/task";
7
- import version from "@src/core/version";
8
- import * as data from "@src/data";
9
- import * as diagnostic from "@src/diagnostic";
10
- import * as interaction from "@src/interaction";
11
- import * as layout from "@src/layout";
12
- import * as performance from "@src/performance";
13
- import * as dynamic from "@src/core/dynamic";
14
- export { version };
15
- export { consent, consentv2, event, identify, set, upgrade, metadata, signal, maxMetric, dlog } from "@src/data";
16
- export { queue } from "@src/data/upload";
17
- export { register } from "@src/core/dynamic";
18
- export { schedule } from "@src/core/task";
19
- export { time } from "@src/core/time";
20
- export { hashText } from "@src/layout";
21
- export { measure };
22
- const modules: Module[] = [diagnostic, layout, interaction, performance, dynamic];
23
-
24
- export function start(config: Config = null): void {
25
- // Check that browser supports required APIs and we do not attempt to start Clarity multiple times
26
- if (core.check()) {
27
- core.config(config);
28
- core.start();
29
- data.start();
30
- modules.forEach(x => measure(x.start)());
31
-
32
- // If it's an internal call to start, without explicit configuration,
33
- // re-process any newly accumulated items in the queue
34
- if (config === null) { queue.process(); }
35
- }
36
- }
37
-
38
- // By default Clarity is asynchronous and will yield by looking for requestIdleCallback.
39
- // However, there can still be situations with single page apps where a user action can result
40
- // in the whole DOM being destroyed and reconstructed. While Clarity will perform favorably out of the box,
41
- // we do allow external clients to manually pause Clarity for that short burst of time and minimize
42
- // performance impact even further. For reference, we are talking single digit milliseconds optimization here, not seconds.
43
- export function pause(): void {
44
- if (core.active()) {
45
- data.event(Constant.Clarity, Constant.Pause);
46
- task.pause();
47
- }
48
- }
49
-
50
- // This is how external clients can get out of pause state, and resume Clarity to continue monitoring the page
51
- export function resume(): void {
52
- if (core.active()) {
53
- task.resume();
54
- data.event(Constant.Clarity, Constant.Resume);
55
- }
56
- }
57
-
58
- export function stop(): void {
59
- if (core.active()) {
60
- // Stop modules in the reverse order of their initialization and start queuing up items again
61
- modules.slice().reverse().forEach(x => measure(x.stop)());
62
- data.stop();
63
- core.stop();
64
- queue.setup();
65
- }
1
+ import { Config, Module } from "@clarity-types/core";
2
+ import { Constant } from "@clarity-types/data";
3
+ import * as queue from "@src/queue";
4
+ import * as core from "@src/core";
5
+ import measure from "@src/core/measure";
6
+ import * as task from "@src/core/task";
7
+ import version from "@src/core/version";
8
+ import * as data from "@src/data";
9
+ import * as diagnostic from "@src/diagnostic";
10
+ import * as interaction from "@src/interaction";
11
+ import * as layout from "@src/layout";
12
+ import * as performance from "@src/performance";
13
+ import * as dynamic from "@src/core/dynamic";
14
+ export { version };
15
+ export { consent, consentv2, event, identify, set, upgrade, metadata, signal, maxMetric, dlog } from "@src/data";
16
+ export { queue } from "@src/data/upload";
17
+ export { register } from "@src/core/dynamic";
18
+ export { schedule } from "@src/core/task";
19
+ export { time } from "@src/core/time";
20
+ export { hashText } from "@src/layout";
21
+ export { measure };
22
+ const modules: Module[] = [diagnostic, layout, interaction, performance, dynamic];
23
+
24
+ export function start(config: Config = null): void {
25
+ // Check that browser supports required APIs and we do not attempt to start Clarity multiple times
26
+ if (core.check()) {
27
+ core.config(config);
28
+ core.start();
29
+ data.start();
30
+ modules.forEach(x => measure(x.start)());
31
+
32
+ // If it's an internal call to start, without explicit configuration,
33
+ // re-process any newly accumulated items in the queue
34
+ if (config === null) { queue.process(); }
35
+ }
36
+ }
37
+
38
+ // By default Clarity is asynchronous and will yield by looking for requestIdleCallback.
39
+ // However, there can still be situations with single page apps where a user action can result
40
+ // in the whole DOM being destroyed and reconstructed. While Clarity will perform favorably out of the box,
41
+ // we do allow external clients to manually pause Clarity for that short burst of time and minimize
42
+ // performance impact even further. For reference, we are talking single digit milliseconds optimization here, not seconds.
43
+ export function pause(): void {
44
+ if (core.active()) {
45
+ data.event(Constant.Clarity, Constant.Pause);
46
+ task.pause();
47
+ }
48
+ }
49
+
50
+ // This is how external clients can get out of pause state, and resume Clarity to continue monitoring the page
51
+ export function resume(): void {
52
+ if (core.active()) {
53
+ task.resume();
54
+ data.event(Constant.Clarity, Constant.Resume);
55
+ }
56
+ }
57
+
58
+ export function stop(): void {
59
+ if (core.active()) {
60
+ // Stop modules in the reverse order of their initialization and start queuing up items again
61
+ modules.slice().reverse().forEach(x => measure(x.stop)());
62
+ data.stop();
63
+ core.stop();
64
+ queue.setup();
65
+ }
66
66
  }
package/src/core/api.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Constant } from "@clarity-types/core";
2
-
3
- export default function api(method: string): string {
4
- // Zone.js, a popular package for Angular, overrides native browser APIs which can lead to inconsistent state for single page applications.
5
- // Example issue: https://github.com/angular/angular/issues/31712
6
- // As a work around, we ensuring Clarity access APIs outside of Zone (and use native implementation instead)
7
- return window[Constant.Zone] && Constant.Symbol in window[Constant.Zone] ? window[Constant.Zone][Constant.Symbol](method) : method;
8
- }
1
+ import { Constant } from "@clarity-types/core";
2
+
3
+ export default function api(method: string): string {
4
+ // Zone.js, a popular package for Angular, overrides native browser APIs which can lead to inconsistent state for single page applications.
5
+ // Example issue: https://github.com/angular/angular/issues/31712
6
+ // As a work around, we ensuring Clarity access APIs outside of Zone (and use native implementation instead)
7
+ return window[Constant.Zone] && Constant.Symbol in window[Constant.Zone] ? window[Constant.Zone][Constant.Symbol](method) : method;
8
+ }
@@ -1,29 +1,29 @@
1
- import { Config, Time } from "@clarity-types/core";
2
-
3
- let config: Config = {
4
- projectId: null,
5
- delay: 1 * Time.Second,
6
- lean: false,
7
- lite: false,
8
- track: true,
9
- content: true,
10
- drop: [],
11
- mask: [],
12
- unmask: [],
13
- regions: [],
14
- cookies: [],
15
- fraud: true,
16
- checksum: [],
17
- report: null,
18
- upload: null,
19
- fallback: null,
20
- upgrade: null,
21
- action: null,
22
- dob: null,
23
- delayDom: false,
24
- throttleDom: true,
25
- conversions: false,
26
- includeSubdomains: true,
27
- };
28
-
29
- export default config;
1
+ import { Config, Time } from "@clarity-types/core";
2
+
3
+ let config: Config = {
4
+ projectId: null,
5
+ delay: 1 * Time.Second,
6
+ lean: false,
7
+ lite: false,
8
+ track: true,
9
+ content: true,
10
+ drop: [],
11
+ mask: [],
12
+ unmask: [],
13
+ regions: [],
14
+ cookies: [],
15
+ fraud: true,
16
+ checksum: [],
17
+ report: null,
18
+ upload: null,
19
+ fallback: null,
20
+ upgrade: null,
21
+ action: null,
22
+ dob: null,
23
+ delayDom: false,
24
+ throttleDom: true,
25
+ conversions: false,
26
+ includeSubdomains: true,
27
+ };
28
+
29
+ export default config;
package/src/core/copy.ts CHANGED
@@ -1,3 +1,3 @@
1
- export default function<T>(input: T): T {
2
- return JSON.parse(JSON.stringify(input));
3
- }
1
+ export default function<T>(input: T): T {
2
+ return JSON.parse(JSON.stringify(input));
3
+ }
package/src/core/event.ts CHANGED
@@ -1,53 +1,53 @@
1
- import { BrowserEvent, Constant } from "@clarity-types/core";
2
- import api from "./api";
3
- import measure from "./measure";
4
-
5
- let bindings: Map<EventTarget, BrowserEvent[]> = new Map();
6
-
7
- export function bind(target: EventTarget, event: string, listener: EventListener, capture: boolean = false, passive: boolean = true): void {
8
- listener = measure(listener) as EventListener;
9
- // Wrapping following lines inside try / catch to cover edge cases where we might try to access an inaccessible element.
10
- // E.g. Iframe may start off as same-origin but later turn into cross-origin, and the following lines will throw an exception.
11
- try {
12
- target[api(Constant.AddEventListener)](event, listener, { capture, passive });
13
- if (!has(target)) {
14
- bindings.set(target, []);
15
- }
16
-
17
- bindings.get(target).push({ event, listener, options: { capture, passive } });
18
- } catch {
19
- /* do nothing */
20
- }
21
- }
22
-
23
- export function reset(): void {
24
- // Walk through existing list of bindings and remove them all
25
- bindings.forEach((bindingsPerTarget: BrowserEvent[], target: EventTarget) => {
26
- resetByTarget(bindingsPerTarget, target);
27
- });
28
-
29
- bindings = new Map();
30
- }
31
-
32
- export function unbind(target: EventTarget) {
33
- if (!has(target)) {
34
- return;
35
- }
36
- resetByTarget(bindings.get(target), target);
37
- }
38
-
39
- export function has(target: EventTarget): boolean {
40
- return bindings.has(target);
41
- }
42
-
43
- function resetByTarget(bindingsPerTarget: BrowserEvent[], target: EventTarget): void {
44
- bindingsPerTarget.forEach((binding) => {
45
- // Wrapping inside try / catch to avoid situations where the element may be destroyed before we get a chance to unbind
46
- try {
47
- target[api(Constant.RemoveEventListener)](binding.event, binding.listener, { capture: binding.options.capture, passive: binding.options.passive });
48
- } catch {
49
- /* do nothing */
50
- }
51
- });
52
- bindings.delete(target);
53
- }
1
+ import { BrowserEvent, Constant } from "@clarity-types/core";
2
+ import api from "./api";
3
+ import measure from "./measure";
4
+
5
+ let bindings: Map<EventTarget, BrowserEvent[]> = new Map();
6
+
7
+ export function bind(target: EventTarget, event: string, listener: EventListener, capture: boolean = false, passive: boolean = true): void {
8
+ listener = measure(listener) as EventListener;
9
+ // Wrapping following lines inside try / catch to cover edge cases where we might try to access an inaccessible element.
10
+ // E.g. Iframe may start off as same-origin but later turn into cross-origin, and the following lines will throw an exception.
11
+ try {
12
+ target[api(Constant.AddEventListener)](event, listener, { capture, passive });
13
+ if (!has(target)) {
14
+ bindings.set(target, []);
15
+ }
16
+
17
+ bindings.get(target).push({ event, listener, options: { capture, passive } });
18
+ } catch {
19
+ /* do nothing */
20
+ }
21
+ }
22
+
23
+ export function reset(): void {
24
+ // Walk through existing list of bindings and remove them all
25
+ bindings.forEach((bindingsPerTarget: BrowserEvent[], target: EventTarget) => {
26
+ resetByTarget(bindingsPerTarget, target);
27
+ });
28
+
29
+ bindings = new Map();
30
+ }
31
+
32
+ export function unbind(target: EventTarget) {
33
+ if (!has(target)) {
34
+ return;
35
+ }
36
+ resetByTarget(bindings.get(target), target);
37
+ }
38
+
39
+ export function has(target: EventTarget): boolean {
40
+ return bindings.has(target);
41
+ }
42
+
43
+ function resetByTarget(bindingsPerTarget: BrowserEvent[], target: EventTarget): void {
44
+ bindingsPerTarget.forEach((binding) => {
45
+ // Wrapping inside try / catch to avoid situations where the element may be destroyed before we get a chance to unbind
46
+ try {
47
+ target[api(Constant.RemoveEventListener)](binding.event, binding.listener, { capture: binding.options.capture, passive: binding.options.passive });
48
+ } catch {
49
+ /* do nothing */
50
+ }
51
+ });
52
+ bindings.delete(target);
53
+ }
package/src/core/hash.ts CHANGED
@@ -1,19 +1,19 @@
1
- // tslint:disable: no-bitwise
2
- export default function(input: string, precision: number = null): string {
3
- // Code inspired from C# GetHashCode: https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/string.cs
4
- let hash = 0;
5
- let hashOne = 5381;
6
- let hashTwo = hashOne;
7
- for (let i = 0; i < input.length; i += 2) {
8
- let charOne = input.charCodeAt(i);
9
- hashOne = ((hashOne << 5) + hashOne) ^ charOne;
10
- if (i + 1 < input.length) {
11
- let charTwo = input.charCodeAt(i + 1);
12
- hashTwo = ((hashTwo << 5) + hashTwo) ^ charTwo;
13
- }
14
- }
15
- // Replace the magic number from C# implementation (1566083941) with a smaller prime number (11579)
16
- // This ensures we don't hit integer overflow and prevent collisions
17
- hash = Math.abs(hashOne + (hashTwo * 11579));
18
- return (precision ? hash % Math.pow(2, precision) : hash).toString(36);
19
- }
1
+ // tslint:disable: no-bitwise
2
+ export default function(input: string, precision: number = null): string {
3
+ // Code inspired from C# GetHashCode: https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/string.cs
4
+ let hash = 0;
5
+ let hashOne = 5381;
6
+ let hashTwo = hashOne;
7
+ for (let i = 0; i < input.length; i += 2) {
8
+ let charOne = input.charCodeAt(i);
9
+ hashOne = ((hashOne << 5) + hashOne) ^ charOne;
10
+ if (i + 1 < input.length) {
11
+ let charTwo = input.charCodeAt(i + 1);
12
+ hashTwo = ((hashTwo << 5) + hashTwo) ^ charTwo;
13
+ }
14
+ }
15
+ // Replace the magic number from C# implementation (1566083941) with a smaller prime number (11579)
16
+ // This ensures we don't hit integer overflow and prevent collisions
17
+ hash = Math.abs(hashOne + (hashTwo * 11579));
18
+ return (precision ? hash % Math.pow(2, precision) : hash).toString(36);
19
+ }
@@ -1,71 +1,71 @@
1
- import { BooleanFlag, Code, Constant, Metric, Setting, Severity } from "@clarity-types/data";
2
- import * as clarity from "@src/clarity";
3
- import * as core from "@src/core"
4
- import { bind } from "@src/core/event";
5
- import * as internal from "@src/diagnostic/internal";
6
- import * as metric from "@src/data/metric";
7
-
8
- let pushState = null;
9
- let replaceState = null;
10
- let url = null;
11
- let count = 0;
12
-
13
- export function start(): void {
14
- url = getCurrentUrl();
15
- count = 0;
16
- bind(window, "popstate", compute);
17
-
18
- // Add a proxy to history.pushState function
19
- if (pushState === null) {
20
- pushState = history.pushState;
21
- history.pushState = function(): void {
22
- pushState.apply(this, arguments);
23
- if (core.active() && check()) {
24
- compute();
25
- }
26
- };
27
- }
28
-
29
- // Add a proxy to history.replaceState function
30
- if (replaceState === null)
31
- {
32
- replaceState = history.replaceState;
33
- history.replaceState = function(): void {
34
- replaceState.apply(this, arguments);
35
- if (core.active() && check()) {
36
- compute();
37
- }
38
- };
39
- }
40
- }
41
-
42
- function check(): boolean {
43
- if (count++ > Setting.CallStackDepth) {
44
- internal.log(Code.CallStackDepth, Severity.Info);
45
- return false;
46
- }
47
- return true;
48
- }
49
-
50
- function compute(): void {
51
- count = 0; // Reset the counter
52
- if (url !== getCurrentUrl()) {
53
- // If the url changed, start tracking it as a new page
54
- clarity.stop();
55
- window.setTimeout(restart, Setting.RestartDelay);
56
- }
57
- }
58
-
59
- function restart(): void {
60
- clarity.start();
61
- metric.max(Metric.SinglePage, BooleanFlag.True);
62
- }
63
-
64
- function getCurrentUrl(): string {
65
- return location.href ? location.href.replace(location.hash, Constant.Empty) : location.href;
66
- }
67
-
68
- export function stop(): void {
69
- url = null;
70
- count = 0;
71
- }
1
+ import { BooleanFlag, Code, Constant, Metric, Setting, Severity } from "@clarity-types/data";
2
+ import * as clarity from "@src/clarity";
3
+ import * as core from "@src/core"
4
+ import { bind } from "@src/core/event";
5
+ import * as internal from "@src/diagnostic/internal";
6
+ import * as metric from "@src/data/metric";
7
+
8
+ let pushState = null;
9
+ let replaceState = null;
10
+ let url = null;
11
+ let count = 0;
12
+
13
+ export function start(): void {
14
+ url = getCurrentUrl();
15
+ count = 0;
16
+ bind(window, "popstate", compute);
17
+
18
+ // Add a proxy to history.pushState function
19
+ if (pushState === null) {
20
+ pushState = history.pushState;
21
+ history.pushState = function(): void {
22
+ pushState.apply(this, arguments);
23
+ if (core.active() && check()) {
24
+ compute();
25
+ }
26
+ };
27
+ }
28
+
29
+ // Add a proxy to history.replaceState function
30
+ if (replaceState === null)
31
+ {
32
+ replaceState = history.replaceState;
33
+ history.replaceState = function(): void {
34
+ replaceState.apply(this, arguments);
35
+ if (core.active() && check()) {
36
+ compute();
37
+ }
38
+ };
39
+ }
40
+ }
41
+
42
+ function check(): boolean {
43
+ if (count++ > Setting.CallStackDepth) {
44
+ internal.log(Code.CallStackDepth, Severity.Info);
45
+ return false;
46
+ }
47
+ return true;
48
+ }
49
+
50
+ function compute(): void {
51
+ count = 0; // Reset the counter
52
+ if (url !== getCurrentUrl()) {
53
+ // If the url changed, start tracking it as a new page
54
+ clarity.stop();
55
+ window.setTimeout(restart, Setting.RestartDelay);
56
+ }
57
+ }
58
+
59
+ function restart(): void {
60
+ clarity.start();
61
+ metric.max(Metric.SinglePage, BooleanFlag.True);
62
+ }
63
+
64
+ function getCurrentUrl(): string {
65
+ return location.href ? location.href.replace(location.hash, Constant.Empty) : location.href;
66
+ }
67
+
68
+ export function stop(): void {
69
+ url = null;
70
+ count = 0;
71
+ }