clarity-visualize 0.7.57 → 0.7.59
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.visualize.js +3552 -12
- package/build/clarity.visualize.min.js +1 -1
- package/build/clarity.visualize.module.js +3552 -12
- package/package.json +2 -2
|
@@ -15,7 +15,7 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
15
15
|
PERFORMANCE OF THIS SOFTWARE.
|
|
16
16
|
***************************************************************************** */
|
|
17
17
|
|
|
18
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
18
|
+
function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
19
19
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
20
20
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
21
21
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
@@ -25,7 +25,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function __generator(thisArg, body) {
|
|
28
|
+
function __generator$1(thisArg, body) {
|
|
29
29
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
30
30
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
31
31
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
@@ -152,6 +152,51 @@ var DataHelper = /** @class */ (function () {
|
|
|
152
152
|
return DataHelper;
|
|
153
153
|
}());
|
|
154
154
|
|
|
155
|
+
var config$2 = {
|
|
156
|
+
projectId: null,
|
|
157
|
+
delay: 1 * 1000 /* Time.Second */,
|
|
158
|
+
lean: false,
|
|
159
|
+
track: true,
|
|
160
|
+
content: true,
|
|
161
|
+
drop: [],
|
|
162
|
+
mask: [],
|
|
163
|
+
unmask: [],
|
|
164
|
+
regions: [],
|
|
165
|
+
cookies: [],
|
|
166
|
+
fraud: true,
|
|
167
|
+
checksum: [],
|
|
168
|
+
report: null,
|
|
169
|
+
upload: null,
|
|
170
|
+
fallback: null,
|
|
171
|
+
upgrade: null,
|
|
172
|
+
action: null,
|
|
173
|
+
dob: null,
|
|
174
|
+
delayDom: false,
|
|
175
|
+
throttleDom: true,
|
|
176
|
+
conversions: false,
|
|
177
|
+
longTask: 30,
|
|
178
|
+
includeSubdomains: true,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
function api(method) {
|
|
182
|
+
// Zone.js, a popular package for Angular, overrides native browser APIs which can lead to inconsistent state for single page applications.
|
|
183
|
+
// Example issue: https://github.com/angular/angular/issues/31712
|
|
184
|
+
// As a work around, we ensuring Clarity access APIs outside of Zone (and use native implementation instead)
|
|
185
|
+
return window["Zone" /* Constant.Zone */] && "__symbol__" /* Constant.Symbol */ in window["Zone" /* Constant.Zone */] ? window["Zone" /* Constant.Zone */]["__symbol__" /* Constant.Symbol */](method) : method;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var startTime = 0;
|
|
189
|
+
// event.timestamp is number of milliseconds elapsed since the document was loaded
|
|
190
|
+
// since iframes can be loaded later the event timestamp is not the same as performance.now()
|
|
191
|
+
// converting everything to absolute time by adding timeorigin of the event view
|
|
192
|
+
// to synchronize times before calculating the difference with start time
|
|
193
|
+
function time$1(event) {
|
|
194
|
+
if (event === void 0) { event = null; }
|
|
195
|
+
var ts = event && event.timeStamp > 0 ? event.timeStamp : performance.now();
|
|
196
|
+
var origin = event && event.view ? event.view.performance.timeOrigin : performance.timeOrigin;
|
|
197
|
+
return Math.max(Math.round(ts + origin - startTime), 0);
|
|
198
|
+
}
|
|
199
|
+
|
|
155
200
|
// tslint:disable: no-bitwise
|
|
156
201
|
function hash (input, precision) {
|
|
157
202
|
if (precision === void 0) { precision = null; }
|
|
@@ -173,6 +218,359 @@ function hash (input, precision) {
|
|
|
173
218
|
return (precision ? hash % Math.pow(2, precision) : hash).toString(36);
|
|
174
219
|
}
|
|
175
220
|
|
|
221
|
+
var catchallRegex = /\S/gi;
|
|
222
|
+
var unicodeRegex = true;
|
|
223
|
+
var digitRegex = null;
|
|
224
|
+
var letterRegex = null;
|
|
225
|
+
var currencyRegex = null;
|
|
226
|
+
function text$1(value, hint, privacy, mangle, type) {
|
|
227
|
+
if (mangle === void 0) { mangle = false; }
|
|
228
|
+
if (value) {
|
|
229
|
+
if (hint == "input" && (type === "checkbox" || type === "radio")) {
|
|
230
|
+
return value;
|
|
231
|
+
}
|
|
232
|
+
switch (privacy) {
|
|
233
|
+
case 0 /* Privacy.None */:
|
|
234
|
+
return value;
|
|
235
|
+
case 1 /* Privacy.Sensitive */:
|
|
236
|
+
switch (hint) {
|
|
237
|
+
case "*T" /* Layout.Constant.TextTag */:
|
|
238
|
+
case "value":
|
|
239
|
+
case "placeholder":
|
|
240
|
+
case "click":
|
|
241
|
+
return redact$1(value);
|
|
242
|
+
case "input":
|
|
243
|
+
case "change":
|
|
244
|
+
return mangleToken(value);
|
|
245
|
+
}
|
|
246
|
+
return value;
|
|
247
|
+
case 2 /* Privacy.Text */:
|
|
248
|
+
case 3 /* Privacy.TextImage */:
|
|
249
|
+
switch (hint) {
|
|
250
|
+
case "*T" /* Layout.Constant.TextTag */:
|
|
251
|
+
case "data-" /* Layout.Constant.DataAttribute */:
|
|
252
|
+
return mangle ? mangleText(value) : mask(value);
|
|
253
|
+
case "src":
|
|
254
|
+
case "srcset":
|
|
255
|
+
case "title":
|
|
256
|
+
case "alt":
|
|
257
|
+
return privacy === 3 /* Privacy.TextImage */ ? "" /* Data.Constant.Empty */ : value;
|
|
258
|
+
case "value":
|
|
259
|
+
case "click":
|
|
260
|
+
case "input":
|
|
261
|
+
case "change":
|
|
262
|
+
return mangleToken(value);
|
|
263
|
+
case "placeholder":
|
|
264
|
+
return mask(value);
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
267
|
+
case 4 /* Privacy.Exclude */:
|
|
268
|
+
switch (hint) {
|
|
269
|
+
case "*T" /* Layout.Constant.TextTag */:
|
|
270
|
+
case "data-" /* Layout.Constant.DataAttribute */:
|
|
271
|
+
return mangle ? mangleText(value) : mask(value);
|
|
272
|
+
case "value":
|
|
273
|
+
case "input":
|
|
274
|
+
case "click":
|
|
275
|
+
case "change":
|
|
276
|
+
return Array(5 /* Data.Setting.WordLength */).join("\u2022" /* Data.Constant.Mask */);
|
|
277
|
+
case "checksum":
|
|
278
|
+
return "" /* Data.Constant.Empty */;
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
case 5 /* Privacy.Snapshot */:
|
|
282
|
+
switch (hint) {
|
|
283
|
+
case "*T" /* Layout.Constant.TextTag */:
|
|
284
|
+
case "data-" /* Layout.Constant.DataAttribute */:
|
|
285
|
+
return scrub(value, "\u25AA" /* Data.Constant.Letter */, "\u25AB" /* Data.Constant.Digit */);
|
|
286
|
+
case "value":
|
|
287
|
+
case "input":
|
|
288
|
+
case "click":
|
|
289
|
+
case "change":
|
|
290
|
+
return Array(5 /* Data.Setting.WordLength */).join("\u2022" /* Data.Constant.Mask */);
|
|
291
|
+
case "checksum":
|
|
292
|
+
case "src":
|
|
293
|
+
case "srcset":
|
|
294
|
+
case "alt":
|
|
295
|
+
case "title":
|
|
296
|
+
return "" /* Data.Constant.Empty */;
|
|
297
|
+
}
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return value;
|
|
302
|
+
}
|
|
303
|
+
function url$1(input, electron) {
|
|
304
|
+
if (electron === void 0) { electron = false; }
|
|
305
|
+
// Replace the URL for Electron apps so we don't send back file:/// URL
|
|
306
|
+
if (electron) {
|
|
307
|
+
return "".concat("https://" /* Data.Constant.HTTPS */).concat("Electron" /* Data.Constant.Electron */);
|
|
308
|
+
}
|
|
309
|
+
var drop = config$2.drop;
|
|
310
|
+
if (drop && drop.length > 0 && input && input.indexOf("?") > 0) {
|
|
311
|
+
var _a = input.split("?"), path = _a[0], query = _a[1];
|
|
312
|
+
var swap_1 = "*na*" /* Data.Constant.Dropped */;
|
|
313
|
+
return path + "?" + query.split("&").map(function (p) { return drop.some(function (x) { return p.indexOf("".concat(x, "=")) === 0; }) ? "".concat(p.split("=")[0], "=").concat(swap_1) : p; }).join("&");
|
|
314
|
+
}
|
|
315
|
+
return input;
|
|
316
|
+
}
|
|
317
|
+
function mangleText(value) {
|
|
318
|
+
var trimmed = value.trim();
|
|
319
|
+
if (trimmed.length > 0) {
|
|
320
|
+
var first = trimmed[0];
|
|
321
|
+
var index = value.indexOf(first);
|
|
322
|
+
var prefix = value.substr(0, index);
|
|
323
|
+
var suffix = value.substr(index + trimmed.length);
|
|
324
|
+
return "".concat(prefix).concat(trimmed.length.toString(36)).concat(suffix);
|
|
325
|
+
}
|
|
326
|
+
return value;
|
|
327
|
+
}
|
|
328
|
+
function mask(value) {
|
|
329
|
+
return value.replace(catchallRegex, "\u2022" /* Data.Constant.Mask */);
|
|
330
|
+
}
|
|
331
|
+
function scrub(value, letter, digit) {
|
|
332
|
+
regex(); // Initialize regular expressions
|
|
333
|
+
return value ? value.replace(letterRegex, letter).replace(digitRegex, digit) : value;
|
|
334
|
+
}
|
|
335
|
+
function mangleToken(value) {
|
|
336
|
+
var length = ((Math.floor(value.length / 5 /* Data.Setting.WordLength */) + 1) * 5 /* Data.Setting.WordLength */);
|
|
337
|
+
var output = "" /* Layout.Constant.Empty */;
|
|
338
|
+
for (var i = 0; i < length; i++) {
|
|
339
|
+
output += i > 0 && i % 5 /* Data.Setting.WordLength */ === 0 ? " " /* Data.Constant.Space */ : "\u2022" /* Data.Constant.Mask */;
|
|
340
|
+
}
|
|
341
|
+
return output;
|
|
342
|
+
}
|
|
343
|
+
function regex() {
|
|
344
|
+
// Initialize unicode regex, if supported by the browser
|
|
345
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
|
|
346
|
+
if (unicodeRegex && digitRegex === null) {
|
|
347
|
+
try {
|
|
348
|
+
digitRegex = new RegExp("\\p{N}", "gu");
|
|
349
|
+
letterRegex = new RegExp("\\p{L}", "gu");
|
|
350
|
+
currencyRegex = new RegExp("\\p{Sc}", "gu");
|
|
351
|
+
}
|
|
352
|
+
catch (_a) {
|
|
353
|
+
unicodeRegex = false;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function redact$1(value) {
|
|
358
|
+
var spaceIndex = -1;
|
|
359
|
+
var gap = 0;
|
|
360
|
+
var hasDigit = false;
|
|
361
|
+
var hasEmail = false;
|
|
362
|
+
var hasWhitespace = false;
|
|
363
|
+
var array = null;
|
|
364
|
+
regex(); // Initialize regular expressions
|
|
365
|
+
for (var i = 0; i < value.length; i++) {
|
|
366
|
+
var c = value.charCodeAt(i);
|
|
367
|
+
hasDigit = hasDigit || (c >= 48 /* Data.Character.Zero */ && c <= 57 /* Data.Character.Nine */); // Check for digits in the current word
|
|
368
|
+
hasEmail = hasEmail || c === 64 /* Data.Character.At */; // Check for @ sign anywhere within the current word
|
|
369
|
+
hasWhitespace = c === 9 /* Data.Character.Tab */ || c === 10 /* Data.Character.NewLine */ || c === 13 /* Data.Character.Return */ || c === 32 /* Data.Character.Blank */;
|
|
370
|
+
// Process each word as an individual token to redact any sensitive information
|
|
371
|
+
if (i === 0 || i === value.length - 1 || hasWhitespace) {
|
|
372
|
+
// Performance optimization: Lazy load string -> array conversion only when required
|
|
373
|
+
if (hasDigit || hasEmail) {
|
|
374
|
+
if (array === null) {
|
|
375
|
+
array = value.split("" /* Data.Constant.Empty */);
|
|
376
|
+
}
|
|
377
|
+
// Work on a token at a time so we don't have to apply regex to a larger string
|
|
378
|
+
var token = value.substring(spaceIndex + 1, hasWhitespace ? i : i + 1);
|
|
379
|
+
// Check if unicode regex is supported, otherwise fallback to calling mask function on this token
|
|
380
|
+
if (unicodeRegex && currencyRegex !== null) {
|
|
381
|
+
// Do not redact information if the token contains a currency symbol
|
|
382
|
+
token = token.match(currencyRegex) ? token : scrub(token, "\u25AA" /* Data.Constant.Letter */, "\u25AB" /* Data.Constant.Digit */);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
token = mask(token);
|
|
386
|
+
}
|
|
387
|
+
// Merge token back into array at the right place
|
|
388
|
+
array.splice(spaceIndex + 1 - gap, token.length, token);
|
|
389
|
+
gap += token.length - 1;
|
|
390
|
+
}
|
|
391
|
+
// Reset digit and email flags after every word boundary, except the beginning of string
|
|
392
|
+
if (hasWhitespace) {
|
|
393
|
+
hasDigit = false;
|
|
394
|
+
hasEmail = false;
|
|
395
|
+
spaceIndex = i;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return array ? array.join("" /* Data.Constant.Empty */) : value;
|
|
400
|
+
}
|
|
401
|
+
var buffer = null;
|
|
402
|
+
function track$8(event, x, y, time) {
|
|
403
|
+
switch (event) {
|
|
404
|
+
case 8 /* Event.Document */:
|
|
405
|
+
buffer.docWidth = x;
|
|
406
|
+
buffer.docHeight = y;
|
|
407
|
+
break;
|
|
408
|
+
case 11 /* Event.Resize */:
|
|
409
|
+
buffer.screenWidth = x;
|
|
410
|
+
buffer.screenHeight = y;
|
|
411
|
+
break;
|
|
412
|
+
case 10 /* Event.Scroll */:
|
|
413
|
+
buffer.scrollX = x;
|
|
414
|
+
buffer.scrollY = y;
|
|
415
|
+
buffer.scrollTime = time;
|
|
416
|
+
break;
|
|
417
|
+
default:
|
|
418
|
+
buffer.pointerX = x;
|
|
419
|
+
buffer.pointerY = y;
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function activity(t) {
|
|
424
|
+
buffer.activityTime = t;
|
|
425
|
+
}
|
|
426
|
+
function visibility(t, visible) {
|
|
427
|
+
buffer.visible = visible === "visible" ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */;
|
|
428
|
+
if (!buffer.visible) {
|
|
429
|
+
activity(t);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
var data$i = null;
|
|
434
|
+
var updates$3 = null;
|
|
435
|
+
function count$1(metric) {
|
|
436
|
+
if (!(metric in data$i)) {
|
|
437
|
+
data$i[metric] = 0;
|
|
438
|
+
}
|
|
439
|
+
if (!(metric in updates$3)) {
|
|
440
|
+
updates$3[metric] = 0;
|
|
441
|
+
}
|
|
442
|
+
data$i[metric]++;
|
|
443
|
+
updates$3[metric]++;
|
|
444
|
+
}
|
|
445
|
+
function sum(metric, value) {
|
|
446
|
+
if (value !== null) {
|
|
447
|
+
if (!(metric in data$i)) {
|
|
448
|
+
data$i[metric] = 0;
|
|
449
|
+
}
|
|
450
|
+
if (!(metric in updates$3)) {
|
|
451
|
+
updates$3[metric] = 0;
|
|
452
|
+
}
|
|
453
|
+
data$i[metric] += value;
|
|
454
|
+
updates$3[metric] += value;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function max(metric, value) {
|
|
458
|
+
// Ensure that we do not process null or NaN values
|
|
459
|
+
if (value !== null && isNaN(value) === false) {
|
|
460
|
+
if (!(metric in data$i)) {
|
|
461
|
+
data$i[metric] = 0;
|
|
462
|
+
}
|
|
463
|
+
if (value > data$i[metric] || data$i[metric] === 0) {
|
|
464
|
+
updates$3[metric] = value;
|
|
465
|
+
data$i[metric] = value;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function setTimeout$1(handler, timeout, event) {
|
|
471
|
+
return window.setTimeout(measure(handler), timeout, event);
|
|
472
|
+
}
|
|
473
|
+
function clearTimeout$1(handle) {
|
|
474
|
+
return window.clearTimeout(handle);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
var data$g = null;
|
|
478
|
+
function track$7(event, time) {
|
|
479
|
+
if (!(event in data$g)) {
|
|
480
|
+
data$g[event] = [[time, 0]];
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
var e = data$g[event];
|
|
484
|
+
var last = e[e.length - 1];
|
|
485
|
+
// Add a new entry only if the new event occurs after configured interval
|
|
486
|
+
// Otherwise, extend the duration of the previous entry
|
|
487
|
+
if (time - last[0] > 100 /* Setting.SummaryInterval */) {
|
|
488
|
+
data$g[event].push([time, 0]);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
last[1] = time - last[0];
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/******************************************************************************
|
|
497
|
+
Copyright (c) Microsoft Corporation.
|
|
498
|
+
|
|
499
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
500
|
+
purpose with or without fee is hereby granted.
|
|
501
|
+
|
|
502
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
503
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
504
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
505
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
506
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
507
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
508
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
509
|
+
***************************************************************************** */
|
|
510
|
+
|
|
511
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
512
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
513
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
514
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
515
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
516
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
517
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function __generator(thisArg, body) {
|
|
522
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
523
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
524
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
525
|
+
function step(op) {
|
|
526
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
527
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
528
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
529
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
530
|
+
switch (op[0]) {
|
|
531
|
+
case 0: case 1: t = op; break;
|
|
532
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
533
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
534
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
535
|
+
default:
|
|
536
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
537
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
538
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
539
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
540
|
+
if (t[2]) _.ops.pop();
|
|
541
|
+
_.trys.pop(); continue;
|
|
542
|
+
}
|
|
543
|
+
op = body.call(thisArg, _);
|
|
544
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
545
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
var history$5 = [];
|
|
550
|
+
var data$d;
|
|
551
|
+
function start$A() {
|
|
552
|
+
history$5 = [];
|
|
553
|
+
max(26 /* Metric.Automation */, navigator.webdriver ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */);
|
|
554
|
+
try {
|
|
555
|
+
// some sites (unintentionally) overwrite the window.self property, so we also check for the main window object
|
|
556
|
+
max(31 /* Metric.Iframed */, window.top == window.self || window.top == window ? 1 /* IframeStatus.TopFrame */ : 2 /* IframeStatus.Iframe */);
|
|
557
|
+
}
|
|
558
|
+
catch (ex) {
|
|
559
|
+
max(31 /* Metric.Iframed */, 0 /* IframeStatus.Unknown */);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
function check$4(id, target, input) {
|
|
563
|
+
// Compute hash for fraud detection, if enabled. Hash is computed only if input meets the minimum length criteria
|
|
564
|
+
if (id !== null && input && input.length >= 5 /* Setting.WordLength */) {
|
|
565
|
+
data$d = { id: id, target: target, checksum: hash(input, 28 /* Setting.ChecksumPrecision */) };
|
|
566
|
+
// Only encode this event if we haven't already reported this hash
|
|
567
|
+
if (history$5.indexOf(data$d.checksum) < 0) {
|
|
568
|
+
history$5.push(data$d.checksum);
|
|
569
|
+
encode$2(41 /* Event.Fraud */);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
176
574
|
var excludeClassNames = "load,active,fixed,visible,focus,show,collaps,animat" /* Constant.ExcludeClassNames */.split("," /* Constant.Comma */);
|
|
177
575
|
var selectorMap = {};
|
|
178
576
|
function reset$n() {
|
|
@@ -270,9 +668,68 @@ var selector = /*#__PURE__*/Object.freeze({
|
|
|
270
668
|
var index = 1;
|
|
271
669
|
var nodesMap = null; // Maps id => node to retrieve further node details using id.
|
|
272
670
|
var values = [];
|
|
671
|
+
var updateMap = [];
|
|
273
672
|
var hashMap = {};
|
|
673
|
+
var override = [];
|
|
674
|
+
var unmask = [];
|
|
675
|
+
var maskText = [];
|
|
676
|
+
var maskExclude = [];
|
|
677
|
+
var maskDisable = [];
|
|
678
|
+
var maskTags = [];
|
|
274
679
|
// The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
|
|
275
680
|
var idMap = null; // Maps node => id.
|
|
681
|
+
var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
|
|
682
|
+
var privacyMap = null; // Maps node => Privacy (enum)
|
|
683
|
+
var fraudMap = null; // Maps node => FraudId (number)
|
|
684
|
+
function start$z() {
|
|
685
|
+
reset$m();
|
|
686
|
+
parse$1(document, true);
|
|
687
|
+
}
|
|
688
|
+
function stop$x() {
|
|
689
|
+
reset$m();
|
|
690
|
+
}
|
|
691
|
+
function reset$m() {
|
|
692
|
+
index = 1;
|
|
693
|
+
values = [];
|
|
694
|
+
updateMap = [];
|
|
695
|
+
hashMap = {};
|
|
696
|
+
override = [];
|
|
697
|
+
unmask = [];
|
|
698
|
+
maskText = "address,password,contact" /* Mask.Text */.split("," /* Constant.Comma */);
|
|
699
|
+
maskExclude = "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.split("," /* Constant.Comma */);
|
|
700
|
+
maskDisable = "radio,checkbox,range,button,reset,submit" /* Mask.Disable */.split("," /* Constant.Comma */);
|
|
701
|
+
maskTags = "INPUT,SELECT,TEXTAREA" /* Mask.Tags */.split("," /* Constant.Comma */);
|
|
702
|
+
nodesMap = new Map();
|
|
703
|
+
idMap = new WeakMap();
|
|
704
|
+
iframeMap = new WeakMap();
|
|
705
|
+
privacyMap = new WeakMap();
|
|
706
|
+
fraudMap = new WeakMap();
|
|
707
|
+
reset$n();
|
|
708
|
+
}
|
|
709
|
+
// We parse new root nodes for any regions or masked nodes in the beginning (document) and
|
|
710
|
+
// later whenever there are new additions or modifications to DOM (mutations)
|
|
711
|
+
function parse$1(root, init) {
|
|
712
|
+
if (init === void 0) { init = false; }
|
|
713
|
+
// Wrap selectors in a try / catch block.
|
|
714
|
+
// It's possible for script to receive invalid selectors, e.g. "'#id'" with extra quotes, and cause the code below to fail
|
|
715
|
+
try {
|
|
716
|
+
// Parse unmask configuration into separate query selectors and override tokens as part of initialization
|
|
717
|
+
if (init) {
|
|
718
|
+
config$2.unmask.forEach(function (x) { return x.indexOf("!" /* Constant.Bang */) < 0 ? unmask.push(x) : override.push(x.substr(1)); });
|
|
719
|
+
}
|
|
720
|
+
// Since mutations may happen on leaf nodes too, e.g. text nodes, which may not support all selector APIs.
|
|
721
|
+
// We ensure that the root note supports querySelectorAll API before executing the code below to identify new regions.
|
|
722
|
+
if ("querySelectorAll" in root) {
|
|
723
|
+
config$2.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
|
|
724
|
+
config$2.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
|
|
725
|
+
config$2.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
|
|
726
|
+
unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
catch (e) {
|
|
730
|
+
log$1(5 /* Code.Selector */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
276
733
|
function getId(node, autogen) {
|
|
277
734
|
if (autogen === void 0) { autogen = false; }
|
|
278
735
|
if (node === null) {
|
|
@@ -285,9 +742,228 @@ function getId(node, autogen) {
|
|
|
285
742
|
}
|
|
286
743
|
return id ? id : null;
|
|
287
744
|
}
|
|
745
|
+
function add(node, parent, data, source) {
|
|
746
|
+
var id = getId(node, true);
|
|
747
|
+
var parentId = parent ? getId(parent) : null;
|
|
748
|
+
var previousId = getPreviousId(node);
|
|
749
|
+
var parentValue = null;
|
|
750
|
+
var regionId = exists(node) ? id : null;
|
|
751
|
+
var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
|
|
752
|
+
var privacyId = 1 /* Privacy.Sensitive */ /* Privacy.TextImage */;
|
|
753
|
+
if (parentId >= 0 && values[parentId]) {
|
|
754
|
+
parentValue = values[parentId];
|
|
755
|
+
parentValue.children.push(id);
|
|
756
|
+
regionId = regionId === null ? parentValue.region : regionId;
|
|
757
|
+
fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
|
|
758
|
+
privacyId = parentValue.metadata.privacy;
|
|
759
|
+
}
|
|
760
|
+
// If there's an explicit region attribute set on the element, use it to mark a region on the page
|
|
761
|
+
if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
|
|
762
|
+
observe$1(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
|
|
763
|
+
regionId = id;
|
|
764
|
+
}
|
|
765
|
+
nodesMap.set(id, node);
|
|
766
|
+
values[id] = {
|
|
767
|
+
id: id,
|
|
768
|
+
parent: parentId,
|
|
769
|
+
previous: previousId,
|
|
770
|
+
children: [],
|
|
771
|
+
data: data,
|
|
772
|
+
selector: null,
|
|
773
|
+
hash: null,
|
|
774
|
+
region: regionId,
|
|
775
|
+
metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
|
|
776
|
+
};
|
|
777
|
+
privacy(node, values[id], parentValue);
|
|
778
|
+
updateSelector(values[id]);
|
|
779
|
+
updateImageSize(values[id]);
|
|
780
|
+
track$6(id, source);
|
|
781
|
+
}
|
|
782
|
+
function update$1(node, parent, data, source) {
|
|
783
|
+
var id = getId(node);
|
|
784
|
+
var parentId = parent ? getId(parent) : null;
|
|
785
|
+
var previousId = getPreviousId(node);
|
|
786
|
+
var changed = false;
|
|
787
|
+
var parentChanged = false;
|
|
788
|
+
if (id in values) {
|
|
789
|
+
var value = values[id];
|
|
790
|
+
value.metadata.active = true;
|
|
791
|
+
// Handle case where internal ordering may have changed
|
|
792
|
+
if (value.previous !== previousId) {
|
|
793
|
+
changed = true;
|
|
794
|
+
value.previous = previousId;
|
|
795
|
+
}
|
|
796
|
+
// Handle case where parent might have been updated
|
|
797
|
+
if (value.parent !== parentId) {
|
|
798
|
+
changed = true;
|
|
799
|
+
var oldParentId = value.parent;
|
|
800
|
+
value.parent = parentId;
|
|
801
|
+
// Move this node to the right location under new parent
|
|
802
|
+
if (parentId !== null && parentId >= 0) {
|
|
803
|
+
var childIndex = previousId === null ? 0 : values[parentId].children.indexOf(previousId) + 1;
|
|
804
|
+
values[parentId].children.splice(childIndex, 0, id);
|
|
805
|
+
// Update region after the move
|
|
806
|
+
value.region = exists(node) ? id : values[parentId].region;
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
// Mark this element as deleted if the parent has been updated to null
|
|
810
|
+
remove(id, source);
|
|
811
|
+
}
|
|
812
|
+
// Remove reference to this node from the old parent
|
|
813
|
+
if (oldParentId !== null && oldParentId >= 0) {
|
|
814
|
+
var nodeIndex = values[oldParentId].children.indexOf(id);
|
|
815
|
+
if (nodeIndex >= 0) {
|
|
816
|
+
values[oldParentId].children.splice(nodeIndex, 1);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
parentChanged = true;
|
|
820
|
+
}
|
|
821
|
+
// Update data
|
|
822
|
+
for (var key in data) {
|
|
823
|
+
if (diff(value["data"], data, key)) {
|
|
824
|
+
changed = true;
|
|
825
|
+
value["data"][key] = data[key];
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
// Update selector
|
|
829
|
+
updateSelector(value);
|
|
830
|
+
track$6(id, source, changed, parentChanged);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
function sameorigin(node) {
|
|
834
|
+
var output = false;
|
|
835
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.tagName === "IFRAME" /* Constant.IFrameTag */) {
|
|
836
|
+
var frame = node;
|
|
837
|
+
// To determine if the iframe is same-origin or not, we try accessing it's contentDocument.
|
|
838
|
+
// If the browser throws an exception, we assume it's cross-origin and move on.
|
|
839
|
+
// However, if we do a get a valid document object back, we assume the contents are accessible and iframe is same-origin.
|
|
840
|
+
try {
|
|
841
|
+
var doc = frame.contentDocument;
|
|
842
|
+
if (doc) {
|
|
843
|
+
iframeMap.set(frame.contentDocument, frame);
|
|
844
|
+
output = true;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
848
|
+
}
|
|
849
|
+
return output;
|
|
850
|
+
}
|
|
851
|
+
function iframe(node) {
|
|
852
|
+
var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
|
|
853
|
+
return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
|
|
854
|
+
}
|
|
855
|
+
function privacy(node, value, parent) {
|
|
856
|
+
var _a;
|
|
857
|
+
var data = value.data;
|
|
858
|
+
var metadata = value.metadata;
|
|
859
|
+
var current = metadata.privacy;
|
|
860
|
+
var attributes = data.attributes || {};
|
|
861
|
+
var tag = data.tag.toUpperCase();
|
|
862
|
+
switch (true) {
|
|
863
|
+
case maskTags.indexOf(tag) >= 0:
|
|
864
|
+
var type = attributes["type" /* Constant.Type */];
|
|
865
|
+
var meta_1 = "" /* Constant.Empty */;
|
|
866
|
+
var excludedPrivacyAttributes_1 = ["class" /* Constant.Class */, "style" /* Constant.Style */];
|
|
867
|
+
Object.keys(attributes)
|
|
868
|
+
.filter(function (x) { return !excludedPrivacyAttributes_1.includes(x); })
|
|
869
|
+
.forEach(function (x) { return (meta_1 += attributes[x].toLowerCase()); });
|
|
870
|
+
var exclude = maskExclude.some(function (x) { return meta_1.indexOf(x) >= 0; });
|
|
871
|
+
// Regardless of privacy mode, always mask off user input from input boxes or drop downs with two exceptions:
|
|
872
|
+
// (1) The node is detected to be one of the excluded fields, in which case we drop everything
|
|
873
|
+
// (2) The node's type is one of the allowed types (like checkboxes)
|
|
874
|
+
metadata.privacy = tag === "INPUT" /* Constant.InputTag */ && maskDisable.indexOf(type) >= 0 ? current : (exclude ? 4 /* Privacy.Exclude */ : 2 /* Privacy.Text */);
|
|
875
|
+
break;
|
|
876
|
+
case "data-clarity-mask" /* Constant.MaskData */ in attributes:
|
|
877
|
+
metadata.privacy = 3 /* Privacy.TextImage */;
|
|
878
|
+
break;
|
|
879
|
+
case "data-clarity-unmask" /* Constant.UnmaskData */ in attributes:
|
|
880
|
+
metadata.privacy = 0 /* Privacy.None */;
|
|
881
|
+
break;
|
|
882
|
+
case privacyMap.has(node):
|
|
883
|
+
// If this node was explicitly configured to contain sensitive content, honor that privacy setting
|
|
884
|
+
metadata.privacy = privacyMap.get(node);
|
|
885
|
+
break;
|
|
886
|
+
case fraudMap.has(node):
|
|
887
|
+
// If this node was explicitly configured to be evaluated for fraud, then also mask content
|
|
888
|
+
metadata.privacy = 2 /* Privacy.Text */;
|
|
889
|
+
break;
|
|
890
|
+
case tag === "*T" /* Constant.TextTag */:
|
|
891
|
+
// If it's a text node belonging to a STYLE or TITLE tag or one of scrub exceptions, then capture content
|
|
892
|
+
var pTag = parent && parent.data ? parent.data.tag : "" /* Constant.Empty */;
|
|
893
|
+
var pSelector_1 = parent && parent.selector ? parent.selector[1 /* Selector.Default */] : "" /* Constant.Empty */;
|
|
894
|
+
var tags = ["STYLE" /* Constant.StyleTag */, "TITLE" /* Constant.TitleTag */, "svg:style" /* Constant.SvgStyle */];
|
|
895
|
+
metadata.privacy = tags.includes(pTag) || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* Privacy.None */ : current;
|
|
896
|
+
break;
|
|
897
|
+
case current === 1 /* Privacy.Sensitive */:
|
|
898
|
+
// In a mode where we mask sensitive information by default, look through class names to aggressively mask content
|
|
899
|
+
metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
|
|
900
|
+
break;
|
|
901
|
+
case tag === "IMG" /* Constant.ImageTag */:
|
|
902
|
+
// Mask images with blob src as it is not publicly available anyway.
|
|
903
|
+
if ((_a = attributes.src) === null || _a === void 0 ? void 0 : _a.startsWith('blob:')) {
|
|
904
|
+
metadata.privacy = 3 /* Privacy.TextImage */;
|
|
905
|
+
}
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
function inspect(input, lookup, metadata) {
|
|
910
|
+
if (input && lookup.some(function (x) { return input.indexOf(x) >= 0; })) {
|
|
911
|
+
return 2 /* Privacy.Text */;
|
|
912
|
+
}
|
|
913
|
+
return metadata.privacy;
|
|
914
|
+
}
|
|
915
|
+
function diff(a, b, field) {
|
|
916
|
+
if (typeof a[field] === "object" && typeof b[field] === "object") {
|
|
917
|
+
for (var key in a[field]) {
|
|
918
|
+
if (a[field][key] !== b[field][key]) {
|
|
919
|
+
return true;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
for (var key in b[field]) {
|
|
923
|
+
if (b[field][key] !== a[field][key]) {
|
|
924
|
+
return true;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
return a[field] !== b[field];
|
|
930
|
+
}
|
|
931
|
+
function position(parent, child) {
|
|
932
|
+
child.metadata.position = 1;
|
|
933
|
+
var idx = parent ? parent.children.indexOf(child.id) : -1;
|
|
934
|
+
while (idx-- > 0) {
|
|
935
|
+
var sibling = values[parent.children[idx]];
|
|
936
|
+
if (child.data.tag === sibling.data.tag) {
|
|
937
|
+
child.metadata.position = sibling.metadata.position + 1;
|
|
938
|
+
break;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return child.metadata.position;
|
|
942
|
+
}
|
|
943
|
+
function updateSelector(value) {
|
|
944
|
+
var parent = value.parent && value.parent in values ? values[value.parent] : null;
|
|
945
|
+
var prefix = parent ? parent.selector : null;
|
|
946
|
+
var d = value.data;
|
|
947
|
+
var p = position(parent, value);
|
|
948
|
+
var s = { id: value.id, tag: d.tag, prefix: prefix, position: p, attributes: d.attributes };
|
|
949
|
+
value.selector = [get$1(s, 0 /* Selector.Alpha */), get$1(s, 1 /* Selector.Beta */)];
|
|
950
|
+
value.hash = value.selector.map(function (x) { return x ? hash(x) : null; });
|
|
951
|
+
value.hash.forEach(function (h) { return hashMap[h] = value.id; });
|
|
952
|
+
}
|
|
953
|
+
function hashText(hash) {
|
|
954
|
+
var id = lookup(hash);
|
|
955
|
+
var node = getNode(id);
|
|
956
|
+
return node !== null && node.textContent !== null ? node.textContent.substr(0, 25 /* Setting.ClickText */) : '';
|
|
957
|
+
}
|
|
288
958
|
function getNode(id) {
|
|
289
959
|
return nodesMap.has(id) ? nodesMap.get(id) : null;
|
|
290
960
|
}
|
|
961
|
+
function getValue(id) {
|
|
962
|
+
if (id in values) {
|
|
963
|
+
return values[id];
|
|
964
|
+
}
|
|
965
|
+
return null;
|
|
966
|
+
}
|
|
291
967
|
function get$2(node) {
|
|
292
968
|
var id = getId(node);
|
|
293
969
|
return id in values ? values[id] : null;
|
|
@@ -295,6 +971,2870 @@ function get$2(node) {
|
|
|
295
971
|
function lookup(hash) {
|
|
296
972
|
return hash in hashMap ? hashMap[hash] : null;
|
|
297
973
|
}
|
|
974
|
+
function has(node) {
|
|
975
|
+
return nodesMap.has(getId(node));
|
|
976
|
+
}
|
|
977
|
+
function updates$2() {
|
|
978
|
+
var output = [];
|
|
979
|
+
for (var _i = 0, updateMap_1 = updateMap; _i < updateMap_1.length; _i++) {
|
|
980
|
+
var id = updateMap_1[_i];
|
|
981
|
+
if (id in values) {
|
|
982
|
+
output.push(values[id]);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
updateMap = [];
|
|
986
|
+
return output;
|
|
987
|
+
}
|
|
988
|
+
function remove(id, source) {
|
|
989
|
+
if (id in values) {
|
|
990
|
+
var value = values[id];
|
|
991
|
+
value.metadata.active = false;
|
|
992
|
+
value.parent = null;
|
|
993
|
+
track$6(id, source);
|
|
994
|
+
// Clean up node references for removed nodes
|
|
995
|
+
removeNodeFromNodesMap(id);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
function removeNodeFromNodesMap(id) {
|
|
999
|
+
// Shadow dom roots shouldn't be deleted,
|
|
1000
|
+
// we should keep listening to the mutations there even they're not rendered in the DOM.
|
|
1001
|
+
if (nodesMap.get(id).nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
nodesMap.delete(id);
|
|
1005
|
+
var value = id in values ? values[id] : null;
|
|
1006
|
+
if (value && value.children) {
|
|
1007
|
+
for (var _i = 0, _a = value.children; _i < _a.length; _i++) {
|
|
1008
|
+
var childId = _a[_i];
|
|
1009
|
+
removeNodeFromNodesMap(childId);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
function updateImageSize(value) {
|
|
1014
|
+
// If this element is a image node, and is masked, then track box model for the current element
|
|
1015
|
+
if (value.data.tag === "IMG" /* Constant.ImageTag */ && value.metadata.privacy === 3 /* Privacy.TextImage */) {
|
|
1016
|
+
var img_1 = getNode(value.id);
|
|
1017
|
+
// We will not capture the natural image dimensions until it loads.
|
|
1018
|
+
if (img_1 && (!img_1.complete || img_1.naturalWidth === 0)) {
|
|
1019
|
+
// This will trigger mutation to update the original width and height after image loads.
|
|
1020
|
+
bind(img_1, 'load', function () {
|
|
1021
|
+
img_1.setAttribute('data-clarity-loaded', "".concat(shortid()));
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
value.metadata.size = [];
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function getPreviousId(node) {
|
|
1028
|
+
var id = null;
|
|
1029
|
+
// Some nodes may not have an ID by design since Clarity skips over tags like SCRIPT, NOSCRIPT, META, COMMENTS, etc..
|
|
1030
|
+
// In that case, we keep going back and check for their sibling until we find a sibling with ID or no more sibling nodes are left.
|
|
1031
|
+
while (id === null && node.previousSibling) {
|
|
1032
|
+
id = getId(node.previousSibling);
|
|
1033
|
+
node = node.previousSibling;
|
|
1034
|
+
}
|
|
1035
|
+
return id;
|
|
1036
|
+
}
|
|
1037
|
+
function track$6(id, source, changed, parentChanged) {
|
|
1038
|
+
if (changed === void 0) { changed = true; }
|
|
1039
|
+
if (parentChanged === void 0) { parentChanged = false; }
|
|
1040
|
+
// Keep track of the order in which mutations happened, they may not be sequential
|
|
1041
|
+
// Edge case: If an element is added later on, and pre-discovered element is moved as a child.
|
|
1042
|
+
// In that case, we need to reorder the pre-discovered element in the update list to keep visualization consistent.
|
|
1043
|
+
var uIndex = updateMap.indexOf(id);
|
|
1044
|
+
if (uIndex >= 0 && source === 1 /* Source.ChildListAdd */ && parentChanged) {
|
|
1045
|
+
updateMap.splice(uIndex, 1);
|
|
1046
|
+
updateMap.push(id);
|
|
1047
|
+
}
|
|
1048
|
+
else if (uIndex === -1 && changed) {
|
|
1049
|
+
updateMap.push(id);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
var dom$1 = /*#__PURE__*/Object.freeze({
|
|
1054
|
+
__proto__: null,
|
|
1055
|
+
add: add,
|
|
1056
|
+
get: get$2,
|
|
1057
|
+
getId: getId,
|
|
1058
|
+
getNode: getNode,
|
|
1059
|
+
getValue: getValue,
|
|
1060
|
+
has: has,
|
|
1061
|
+
hashText: hashText,
|
|
1062
|
+
iframe: iframe,
|
|
1063
|
+
lookup: lookup,
|
|
1064
|
+
parse: parse$1,
|
|
1065
|
+
sameorigin: sameorigin,
|
|
1066
|
+
start: start$z,
|
|
1067
|
+
stop: stop$x,
|
|
1068
|
+
update: update$1,
|
|
1069
|
+
updates: updates$2
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
// Track the start time to be able to compute duration at the end of the task
|
|
1073
|
+
var idleTimeout = 5000;
|
|
1074
|
+
var tracker = {};
|
|
1075
|
+
var queuedTasks = [];
|
|
1076
|
+
var activeTask = null;
|
|
1077
|
+
var pauseTask = null;
|
|
1078
|
+
function schedule$1(task, priority) {
|
|
1079
|
+
if (priority === void 0) { priority = 0 /* Priority.Normal */; }
|
|
1080
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1081
|
+
var _i, queuedTasks_1, q, promise;
|
|
1082
|
+
return __generator(this, function (_a) {
|
|
1083
|
+
// If this task is already scheduled, skip it
|
|
1084
|
+
for (_i = 0, queuedTasks_1 = queuedTasks; _i < queuedTasks_1.length; _i++) {
|
|
1085
|
+
q = queuedTasks_1[_i];
|
|
1086
|
+
if (q.task === task) {
|
|
1087
|
+
return [2 /*return*/];
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
promise = new Promise(function (resolve) {
|
|
1091
|
+
var insert = priority === 1 /* Priority.High */ ? "unshift" : "push";
|
|
1092
|
+
// Queue this task for asynchronous execution later
|
|
1093
|
+
// We also store a unique page identifier (id) along with the task to ensure
|
|
1094
|
+
// ensure that we do not accidentally execute this task in context of a different page
|
|
1095
|
+
queuedTasks[insert]({ task: task, resolve: resolve, id: id() });
|
|
1096
|
+
});
|
|
1097
|
+
// If there is no active task running, and Clarity is not in pause state,
|
|
1098
|
+
// invoke the first task in the queue synchronously. This ensures that we don't yield the thread during unload event
|
|
1099
|
+
if (activeTask === null && pauseTask === null) {
|
|
1100
|
+
run();
|
|
1101
|
+
}
|
|
1102
|
+
return [2 /*return*/, promise];
|
|
1103
|
+
});
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
function run() {
|
|
1107
|
+
var entry = queuedTasks.shift();
|
|
1108
|
+
if (entry) {
|
|
1109
|
+
activeTask = entry;
|
|
1110
|
+
entry.task().then(function () {
|
|
1111
|
+
// Bail out if the context in which this task was operating is different from the current page
|
|
1112
|
+
// An example scenario where task could span across pages is Single Page Applications (SPA)
|
|
1113
|
+
// A task that started on page #1, but completes on page #2
|
|
1114
|
+
if (entry.id !== id()) {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
entry.resolve();
|
|
1118
|
+
activeTask = null; // Reset active task back to null now that the promise is resolved
|
|
1119
|
+
run();
|
|
1120
|
+
}).catch(function (error) {
|
|
1121
|
+
// If one of the scheduled tasks failed, log, recover and continue processing rest of the tasks
|
|
1122
|
+
if (entry.id !== id()) {
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
if (error) {
|
|
1126
|
+
log$1(0 /* Code.RunTask */, 1 /* Severity.Warning */, error.name, error.message, error.stack);
|
|
1127
|
+
}
|
|
1128
|
+
activeTask = null;
|
|
1129
|
+
run();
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
function state$a(timer) {
|
|
1134
|
+
var id = key(timer);
|
|
1135
|
+
if (id in tracker) {
|
|
1136
|
+
var elapsed = performance.now() - tracker[id].start;
|
|
1137
|
+
return (elapsed > tracker[id].yield) ? 0 /* Task.Wait */ : 1 /* Task.Run */;
|
|
1138
|
+
}
|
|
1139
|
+
// If this task is no longer being tracked, send stop message to the caller
|
|
1140
|
+
return 2 /* Task.Stop */;
|
|
1141
|
+
}
|
|
1142
|
+
function start$y(timer) {
|
|
1143
|
+
tracker[key(timer)] = { start: performance.now(), calls: 0, yield: config$2.longTask };
|
|
1144
|
+
}
|
|
1145
|
+
function restart$2(timer) {
|
|
1146
|
+
var id = key(timer);
|
|
1147
|
+
if (tracker && tracker[id]) {
|
|
1148
|
+
var c = tracker[id].calls;
|
|
1149
|
+
var y = tracker[id].yield;
|
|
1150
|
+
start$y(timer);
|
|
1151
|
+
tracker[id].calls = c + 1;
|
|
1152
|
+
tracker[id].yield = y;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
function stop$w(timer) {
|
|
1156
|
+
var end = performance.now();
|
|
1157
|
+
var id = key(timer);
|
|
1158
|
+
var duration = end - tracker[id].start;
|
|
1159
|
+
sum(timer.cost, duration);
|
|
1160
|
+
count$1(5 /* Metric.InvokeCount */);
|
|
1161
|
+
// For the first execution, which is synchronous, time is automatically counted towards TotalDuration.
|
|
1162
|
+
// However, for subsequent asynchronous runs, we need to manually update TotalDuration metric.
|
|
1163
|
+
if (tracker[id].calls > 0) {
|
|
1164
|
+
sum(4 /* Metric.TotalCost */, duration);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
function suspend$1(timer) {
|
|
1168
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1169
|
+
var id, _a;
|
|
1170
|
+
return __generator(this, function (_b) {
|
|
1171
|
+
switch (_b.label) {
|
|
1172
|
+
case 0:
|
|
1173
|
+
id = key(timer);
|
|
1174
|
+
if (!(id in tracker)) return [3 /*break*/, 2];
|
|
1175
|
+
stop$w(timer);
|
|
1176
|
+
_a = tracker[id];
|
|
1177
|
+
return [4 /*yield*/, wait()];
|
|
1178
|
+
case 1:
|
|
1179
|
+
_a.yield = (_b.sent()).timeRemaining();
|
|
1180
|
+
restart$2(timer);
|
|
1181
|
+
_b.label = 2;
|
|
1182
|
+
case 2:
|
|
1183
|
+
// After we are done with suspending task, ensure that we are still operating in the right context
|
|
1184
|
+
// If the task is still being tracked, continue running the task, otherwise ask caller to stop execution
|
|
1185
|
+
return [2 /*return*/, id in tracker ? 1 /* Task.Run */ : 2 /* Task.Stop */];
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
function key(timer) {
|
|
1191
|
+
return "".concat(timer.id, ".").concat(timer.cost);
|
|
1192
|
+
}
|
|
1193
|
+
function wait() {
|
|
1194
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1195
|
+
return __generator(this, function (_a) {
|
|
1196
|
+
switch (_a.label) {
|
|
1197
|
+
case 0:
|
|
1198
|
+
return [3 /*break*/, 2];
|
|
1199
|
+
case 1:
|
|
1200
|
+
_a.sent();
|
|
1201
|
+
_a.label = 2;
|
|
1202
|
+
case 2: return [2 /*return*/, new Promise(function (resolve) {
|
|
1203
|
+
requestIdleCallback(resolve, { timeout: idleTimeout });
|
|
1204
|
+
})];
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
// Use native implementation of requestIdleCallback if it exists.
|
|
1210
|
+
// Otherwise, fall back to a custom implementation using requestAnimationFrame & MessageChannel.
|
|
1211
|
+
// While it's not possible to build a perfect polyfill given the nature of this API, the following code attempts to get close.
|
|
1212
|
+
// Background context: requestAnimationFrame invokes the js code right before: style, layout and paint computation within the frame.
|
|
1213
|
+
// This means, that any code that runs as part of requestAnimationFrame will by default be blocking in nature. Not what we want.
|
|
1214
|
+
// For non-blocking behavior, We need to know when browser has finished painting. This can be accomplished in two different ways (hacks):
|
|
1215
|
+
// (1) Use MessageChannel to pass the message, and browser will receive the message right after paint event has occured.
|
|
1216
|
+
// (2) Use setTimeout call within requestAnimationFrame. This also works, but there's a risk that browser may throttle setTimeout calls.
|
|
1217
|
+
// Given this information, we are currently using (1) from above. More information on (2) as well as some additional context is below:
|
|
1218
|
+
// https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Performance_best_practices_for_Firefox_fe_engineers
|
|
1219
|
+
function requestIdleCallbackPolyfill(callback, options) {
|
|
1220
|
+
var startTime = performance.now();
|
|
1221
|
+
var channel = new MessageChannel();
|
|
1222
|
+
var incoming = channel.port1;
|
|
1223
|
+
var outgoing = channel.port2;
|
|
1224
|
+
incoming.onmessage = function (event) {
|
|
1225
|
+
var currentTime = performance.now();
|
|
1226
|
+
var elapsed = currentTime - startTime;
|
|
1227
|
+
var duration = currentTime - event.data;
|
|
1228
|
+
if (duration > config$2.longTask && elapsed < options.timeout) {
|
|
1229
|
+
requestAnimationFrame(function () { outgoing.postMessage(currentTime); });
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
var didTimeout_1 = elapsed > options.timeout;
|
|
1233
|
+
callback({
|
|
1234
|
+
didTimeout: didTimeout_1,
|
|
1235
|
+
timeRemaining: function () { return didTimeout_1 ? config$2.longTask : Math.max(0, config$2.longTask - duration); }
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
};
|
|
1239
|
+
requestAnimationFrame(function () { outgoing.postMessage(performance.now()); });
|
|
1240
|
+
}
|
|
1241
|
+
var requestIdleCallback = window["requestIdleCallback"] || requestIdleCallbackPolyfill;
|
|
1242
|
+
|
|
1243
|
+
// Following code takes an array of tokens and transforms it to optimize for repeating tokens and make it efficient to send over the wire
|
|
1244
|
+
// The way it works is that it iterate over all tokens and checks if the current token was already seen in the tokens array so far
|
|
1245
|
+
// If so, it replaces the token with its reference (index). This helps us save bytes by not repeating the same value twice.
|
|
1246
|
+
// E.g. If tokens array is: ["hello", "world", "coding", "language", "world", "language", "example"]
|
|
1247
|
+
// Then the resulting tokens array after following code execution would be: ["hello", "world", "coding", "language", [1, 3], "example"]
|
|
1248
|
+
// Where [1,3] points to tokens[1] => "world" and tokens[3] => "language"
|
|
1249
|
+
function tokenize (tokens) {
|
|
1250
|
+
var output = [];
|
|
1251
|
+
var lookup = {};
|
|
1252
|
+
var pointer = 0;
|
|
1253
|
+
var reference = null;
|
|
1254
|
+
for (var i = 0; i < tokens.length; i++) {
|
|
1255
|
+
// Only optimize for string values
|
|
1256
|
+
if (typeof tokens[i] === "string" /* Constant.String */) {
|
|
1257
|
+
var token = tokens[i];
|
|
1258
|
+
var index = lookup[token] || -1;
|
|
1259
|
+
if (index >= 0) {
|
|
1260
|
+
if (reference) {
|
|
1261
|
+
reference.push(index);
|
|
1262
|
+
}
|
|
1263
|
+
else {
|
|
1264
|
+
reference = [index];
|
|
1265
|
+
output.push(reference);
|
|
1266
|
+
pointer++;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
reference = null;
|
|
1271
|
+
output.push(token);
|
|
1272
|
+
lookup[token] = pointer++;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
else {
|
|
1276
|
+
// If the value is anything other than string, append it as it is to the output array
|
|
1277
|
+
// And, also increment the pointer to stay in sync with output array
|
|
1278
|
+
reference = null;
|
|
1279
|
+
output.push(tokens[i]);
|
|
1280
|
+
pointer++;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
return output;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
var data$c;
|
|
1287
|
+
function reset$k() {
|
|
1288
|
+
data$c = null;
|
|
1289
|
+
}
|
|
1290
|
+
function start$x() {
|
|
1291
|
+
reset$k();
|
|
1292
|
+
compute$9();
|
|
1293
|
+
}
|
|
1294
|
+
function compute$9() {
|
|
1295
|
+
var body = document.body;
|
|
1296
|
+
var d = document.documentElement;
|
|
1297
|
+
var bodyClientWidth = body ? body.clientWidth : null;
|
|
1298
|
+
var bodyScrollWidth = body ? body.scrollWidth : null;
|
|
1299
|
+
var bodyOffsetWidth = body ? body.offsetWidth : null;
|
|
1300
|
+
var documentClientWidth = d ? d.clientWidth : null;
|
|
1301
|
+
var documentScrollWidth = d ? d.scrollWidth : null;
|
|
1302
|
+
var documentOffsetWidth = d ? d.offsetWidth : null;
|
|
1303
|
+
var width = Math.max(bodyClientWidth, bodyScrollWidth, bodyOffsetWidth, documentClientWidth, documentScrollWidth, documentOffsetWidth);
|
|
1304
|
+
var bodyClientHeight = body ? body.clientHeight : null;
|
|
1305
|
+
var bodyScrollHeight = body ? body.scrollHeight : null;
|
|
1306
|
+
var bodyOffsetHeight = body ? body.offsetHeight : null;
|
|
1307
|
+
var documentClientHeight = d ? d.clientHeight : null;
|
|
1308
|
+
var documentScrollHeight = d ? d.scrollHeight : null;
|
|
1309
|
+
var documentOffsetHeight = d ? d.offsetHeight : null;
|
|
1310
|
+
var height = Math.max(bodyClientHeight, bodyScrollHeight, bodyOffsetHeight, documentClientHeight, documentScrollHeight, documentOffsetHeight);
|
|
1311
|
+
// Check that width or height has changed from before, and also that width & height are not null values
|
|
1312
|
+
if ((data$c === null || width !== data$c.width || height !== data$c.height) && width !== null && height !== null) {
|
|
1313
|
+
data$c = { width: width, height: height };
|
|
1314
|
+
encode$4(8 /* Event.Document */);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
compute$9.dn = 19 /* FunctionNames.DocumentCompute */;
|
|
1318
|
+
|
|
1319
|
+
var state$9 = [];
|
|
1320
|
+
function start$w() {
|
|
1321
|
+
reset$j();
|
|
1322
|
+
}
|
|
1323
|
+
function observe$c(root) {
|
|
1324
|
+
bind(root, "change", recompute$8, true);
|
|
1325
|
+
}
|
|
1326
|
+
function recompute$8(evt) {
|
|
1327
|
+
var element = target(evt);
|
|
1328
|
+
if (element) {
|
|
1329
|
+
var value = element.value;
|
|
1330
|
+
var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$2.fraud && "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.indexOf(element.type) === -1 ? hash(value, 28 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
|
|
1331
|
+
state$9.push({ time: time$1(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
|
|
1332
|
+
schedule$1(encode$3.bind(this, 42 /* Event.Change */));
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
recompute$8.dn = 5 /* FunctionNames.ChangeRecompute */;
|
|
1336
|
+
function reset$j() {
|
|
1337
|
+
state$9 = [];
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
function offset(element) {
|
|
1341
|
+
var output = { x: 0, y: 0 };
|
|
1342
|
+
// Walk up the chain to ensure we compute offset distance correctly
|
|
1343
|
+
// In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
|
|
1344
|
+
if (element && element.offsetParent) {
|
|
1345
|
+
do {
|
|
1346
|
+
var parent_1 = element.offsetParent;
|
|
1347
|
+
var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
|
|
1348
|
+
output.x += element.offsetLeft;
|
|
1349
|
+
output.y += element.offsetTop;
|
|
1350
|
+
element = frame ? frame : parent_1;
|
|
1351
|
+
} while (element);
|
|
1352
|
+
}
|
|
1353
|
+
return output;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
|
|
1357
|
+
var state$8 = [];
|
|
1358
|
+
function start$v() {
|
|
1359
|
+
reset$i();
|
|
1360
|
+
}
|
|
1361
|
+
function observe$b(root) {
|
|
1362
|
+
bind(root, "click", handler$3.bind(this, 9 /* Event.Click */, root), true);
|
|
1363
|
+
}
|
|
1364
|
+
function handler$3(event, root, evt) {
|
|
1365
|
+
var frame = iframe(root);
|
|
1366
|
+
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
1367
|
+
var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
|
|
1368
|
+
var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
|
|
1369
|
+
// In case of iframe, we adjust (x,y) to be relative to top parent's origin
|
|
1370
|
+
if (frame) {
|
|
1371
|
+
var distance = offset(frame);
|
|
1372
|
+
x = x ? x + Math.round(distance.x) : x;
|
|
1373
|
+
y = y ? y + Math.round(distance.y) : y;
|
|
1374
|
+
}
|
|
1375
|
+
var t = target(evt);
|
|
1376
|
+
// Find nearest anchor tag (<a/>) parent if current target node is part of one
|
|
1377
|
+
// If present, we use the returned link element to populate text and link properties below
|
|
1378
|
+
var a = link(t);
|
|
1379
|
+
// Get layout rectangle for the target element
|
|
1380
|
+
var l = layout$1(t);
|
|
1381
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
|
|
1382
|
+
// This property helps differentiate between a keyboard navigation vs. pointer click
|
|
1383
|
+
// In case of a keyboard navigation, we use center of target element as (x,y)
|
|
1384
|
+
if (evt.detail === 0 && l) {
|
|
1385
|
+
x = Math.round(l.x + (l.w / 2));
|
|
1386
|
+
y = Math.round(l.y + (l.h / 2));
|
|
1387
|
+
}
|
|
1388
|
+
var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1389
|
+
var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1390
|
+
// Check for null values before processing this event
|
|
1391
|
+
if (x !== null && y !== null) {
|
|
1392
|
+
state$8.push({
|
|
1393
|
+
time: time$1(evt),
|
|
1394
|
+
event: event,
|
|
1395
|
+
data: {
|
|
1396
|
+
target: t,
|
|
1397
|
+
x: x,
|
|
1398
|
+
y: y,
|
|
1399
|
+
eX: eX,
|
|
1400
|
+
eY: eY,
|
|
1401
|
+
button: evt.button,
|
|
1402
|
+
reaction: reaction(t),
|
|
1403
|
+
context: context(a),
|
|
1404
|
+
text: text(t),
|
|
1405
|
+
link: a ? a.href : null,
|
|
1406
|
+
hash: null,
|
|
1407
|
+
trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
|
|
1408
|
+
}
|
|
1409
|
+
});
|
|
1410
|
+
schedule$1(encode$3.bind(this, event));
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
handler$3.dn = 6 /* FunctionNames.ClickHandler */;
|
|
1414
|
+
function link(node) {
|
|
1415
|
+
while (node && node !== document) {
|
|
1416
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
1417
|
+
var element = node;
|
|
1418
|
+
if (element.tagName === "A") {
|
|
1419
|
+
return element;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
node = node.parentNode;
|
|
1423
|
+
}
|
|
1424
|
+
return null;
|
|
1425
|
+
}
|
|
1426
|
+
function text(element) {
|
|
1427
|
+
var output = null;
|
|
1428
|
+
if (element) {
|
|
1429
|
+
// Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
|
|
1430
|
+
var t = element.textContent || String(element.value || '') || element.alt;
|
|
1431
|
+
if (t) {
|
|
1432
|
+
// Replace multiple occurrence of space characters with a single white space
|
|
1433
|
+
// Also, trim any spaces at the beginning or at the end of string
|
|
1434
|
+
// Finally, send only first few characters as specified by the Setting
|
|
1435
|
+
output = t.replace(/\s+/g, " " /* Constant.Space */).trim().substr(0, 25 /* Setting.ClickText */);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
return output;
|
|
1439
|
+
}
|
|
1440
|
+
function reaction(element) {
|
|
1441
|
+
if (element.nodeType === Node.ELEMENT_NODE) {
|
|
1442
|
+
var tag = element.tagName.toLowerCase();
|
|
1443
|
+
if (UserInputTags.indexOf(tag) >= 0) {
|
|
1444
|
+
return 0 /* BooleanFlag.False */;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
return 1 /* BooleanFlag.True */;
|
|
1448
|
+
}
|
|
1449
|
+
function layout$1(element) {
|
|
1450
|
+
var box = null;
|
|
1451
|
+
var de = document.documentElement;
|
|
1452
|
+
if (typeof element.getBoundingClientRect === "function") {
|
|
1453
|
+
// getBoundingClientRect returns rectangle relative positioning to viewport
|
|
1454
|
+
var rect = element.getBoundingClientRect();
|
|
1455
|
+
if (rect && rect.width > 0 && rect.height > 0) {
|
|
1456
|
+
// Add viewport's scroll position to rectangle to get position relative to document origin
|
|
1457
|
+
// Also: using Math.floor() instead of Math.round() because in Edge,
|
|
1458
|
+
// getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
|
|
1459
|
+
// floors the value (e.g. 162px). This keeps consistent behavior across browsers.
|
|
1460
|
+
box = {
|
|
1461
|
+
x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
|
|
1462
|
+
y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
|
|
1463
|
+
w: Math.floor(rect.width),
|
|
1464
|
+
h: Math.floor(rect.height)
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
return box;
|
|
1469
|
+
}
|
|
1470
|
+
function context(a) {
|
|
1471
|
+
if (a && a.hasAttribute("target" /* Constant.Target */)) {
|
|
1472
|
+
switch (a.getAttribute("target" /* Constant.Target */)) {
|
|
1473
|
+
case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
|
|
1474
|
+
case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
|
|
1475
|
+
case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
return 0 /* BrowsingContext.Self */;
|
|
1479
|
+
}
|
|
1480
|
+
function reset$i() {
|
|
1481
|
+
state$8 = [];
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
var state$7 = [];
|
|
1485
|
+
function start$u() {
|
|
1486
|
+
reset$h();
|
|
1487
|
+
}
|
|
1488
|
+
function observe$a(root) {
|
|
1489
|
+
bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
|
|
1490
|
+
bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
|
|
1491
|
+
bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
|
|
1492
|
+
}
|
|
1493
|
+
function recompute$7(action, evt) {
|
|
1494
|
+
state$7.push({ time: time$1(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
|
|
1495
|
+
schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
|
|
1496
|
+
}
|
|
1497
|
+
recompute$7.dn = 7 /* FunctionNames.ClipboardRecompute */;
|
|
1498
|
+
function reset$h() {
|
|
1499
|
+
state$7 = [];
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
var timeout$6 = null;
|
|
1503
|
+
var state$6 = [];
|
|
1504
|
+
function start$t() {
|
|
1505
|
+
reset$g();
|
|
1506
|
+
}
|
|
1507
|
+
function observe$9(root) {
|
|
1508
|
+
bind(root, "input", recompute$6, true);
|
|
1509
|
+
}
|
|
1510
|
+
function recompute$6(evt) {
|
|
1511
|
+
var input = target(evt);
|
|
1512
|
+
var value = get$2(input);
|
|
1513
|
+
if (input && input.type && value) {
|
|
1514
|
+
var v = input.value;
|
|
1515
|
+
var t = input.type;
|
|
1516
|
+
switch (input.type) {
|
|
1517
|
+
case "radio":
|
|
1518
|
+
case "checkbox":
|
|
1519
|
+
v = input.checked ? "true" : "false";
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
var data = { target: input, value: v, type: t };
|
|
1523
|
+
// 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.
|
|
1524
|
+
if (state$6.length > 0 && (state$6[state$6.length - 1].data.target === data.target)) {
|
|
1525
|
+
state$6.pop();
|
|
1526
|
+
}
|
|
1527
|
+
state$6.push({ time: time$1(evt), event: 27 /* Event.Input */, data: data });
|
|
1528
|
+
clearTimeout$1(timeout$6);
|
|
1529
|
+
timeout$6 = setTimeout$1(process$7, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
recompute$6.dn = 9 /* FunctionNames.InputRecompute */;
|
|
1533
|
+
function process$7(event) {
|
|
1534
|
+
schedule$1(encode$3.bind(this, event));
|
|
1535
|
+
}
|
|
1536
|
+
function reset$g() {
|
|
1537
|
+
state$6 = [];
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
var state$5 = [];
|
|
1541
|
+
var timeout$5 = null;
|
|
1542
|
+
var hasPrimaryTouch = false;
|
|
1543
|
+
var primaryTouchId = 0;
|
|
1544
|
+
var activeTouchPointIds = new Set();
|
|
1545
|
+
function start$s() {
|
|
1546
|
+
reset$f();
|
|
1547
|
+
}
|
|
1548
|
+
function observe$8(root) {
|
|
1549
|
+
bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
|
|
1550
|
+
bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
|
|
1551
|
+
bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
|
|
1552
|
+
bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
|
|
1553
|
+
bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
|
|
1554
|
+
bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
|
|
1555
|
+
bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
|
|
1556
|
+
bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
|
|
1557
|
+
bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
|
|
1558
|
+
}
|
|
1559
|
+
function mouse(event, root, evt) {
|
|
1560
|
+
var frame = iframe(root);
|
|
1561
|
+
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
1562
|
+
var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
|
|
1563
|
+
var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
|
|
1564
|
+
// In case of iframe, we adjust (x,y) to be relative to top parent's origin
|
|
1565
|
+
if (frame) {
|
|
1566
|
+
var distance = offset(frame);
|
|
1567
|
+
x = x ? x + Math.round(distance.x) : x;
|
|
1568
|
+
y = y ? y + Math.round(distance.y) : y;
|
|
1569
|
+
}
|
|
1570
|
+
// Check for null values before processing this event
|
|
1571
|
+
if (x !== null && y !== null) {
|
|
1572
|
+
handler$2({ time: time$1(evt), event: event, data: { target: target(evt), x: x, y: y } });
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
mouse.dn = 10 /* FunctionNames.PointerMouse */;
|
|
1576
|
+
function touch(event, root, evt) {
|
|
1577
|
+
var frame = iframe(root);
|
|
1578
|
+
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
1579
|
+
var touches = evt.changedTouches;
|
|
1580
|
+
var t = time$1(evt);
|
|
1581
|
+
if (touches) {
|
|
1582
|
+
for (var i = 0; i < touches.length; i++) {
|
|
1583
|
+
var entry = touches[i];
|
|
1584
|
+
var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
|
|
1585
|
+
var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
|
|
1586
|
+
x = x && frame ? x + Math.round(frame.offsetLeft) : x;
|
|
1587
|
+
y = y && frame ? y + Math.round(frame.offsetTop) : y;
|
|
1588
|
+
// We cannot rely on identifier to determine primary touch as its value doesn't always start with 0.
|
|
1589
|
+
// Safari/Webkit uses the address of the UITouch object as the identifier value for each touch point.
|
|
1590
|
+
var id = "identifier" in entry ? entry["identifier"] : undefined;
|
|
1591
|
+
switch (event) {
|
|
1592
|
+
case 17 /* Event.TouchStart */:
|
|
1593
|
+
if (activeTouchPointIds.size === 0) {
|
|
1594
|
+
// Track presence of primary touch separately to handle scenarios when same id is repeated
|
|
1595
|
+
hasPrimaryTouch = true;
|
|
1596
|
+
primaryTouchId = id;
|
|
1597
|
+
}
|
|
1598
|
+
activeTouchPointIds.add(id);
|
|
1599
|
+
break;
|
|
1600
|
+
case 18 /* Event.TouchEnd */:
|
|
1601
|
+
case 20 /* Event.TouchCancel */:
|
|
1602
|
+
activeTouchPointIds.delete(id);
|
|
1603
|
+
break;
|
|
1604
|
+
}
|
|
1605
|
+
var isPrimary = hasPrimaryTouch && primaryTouchId === id;
|
|
1606
|
+
// Check for null values before processing this event
|
|
1607
|
+
if (x !== null && y !== null) {
|
|
1608
|
+
handler$2({ time: t, event: event, data: { target: target(evt), x: x, y: y, id: id, isPrimary: isPrimary } });
|
|
1609
|
+
}
|
|
1610
|
+
// Reset primary touch point id once touch event ends
|
|
1611
|
+
if (event === 20 /* Event.TouchCancel */ || event === 18 /* Event.TouchEnd */) {
|
|
1612
|
+
if (primaryTouchId === id) {
|
|
1613
|
+
hasPrimaryTouch = false;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
touch.dn = 11 /* FunctionNames.PointerTouch */;
|
|
1620
|
+
function handler$2(current) {
|
|
1621
|
+
switch (current.event) {
|
|
1622
|
+
case 12 /* Event.MouseMove */:
|
|
1623
|
+
case 15 /* Event.MouseWheel */:
|
|
1624
|
+
case 19 /* Event.TouchMove */:
|
|
1625
|
+
var length_1 = state$5.length;
|
|
1626
|
+
var last = length_1 > 1 ? state$5[length_1 - 2] : null;
|
|
1627
|
+
if (last && similar$1(last, current)) {
|
|
1628
|
+
state$5.pop();
|
|
1629
|
+
}
|
|
1630
|
+
state$5.push(current);
|
|
1631
|
+
clearTimeout$1(timeout$5);
|
|
1632
|
+
timeout$5 = setTimeout$1(process$6, 500 /* Setting.LookAhead */, current.event);
|
|
1633
|
+
break;
|
|
1634
|
+
default:
|
|
1635
|
+
state$5.push(current);
|
|
1636
|
+
process$6(current.event);
|
|
1637
|
+
break;
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
function process$6(event) {
|
|
1641
|
+
schedule$1(encode$3.bind(this, event));
|
|
1642
|
+
}
|
|
1643
|
+
function reset$f() {
|
|
1644
|
+
state$5 = [];
|
|
1645
|
+
}
|
|
1646
|
+
function similar$1(last, current) {
|
|
1647
|
+
var dx = last.data.x - current.data.x;
|
|
1648
|
+
var dy = last.data.y - current.data.y;
|
|
1649
|
+
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
1650
|
+
var gap = current.time - last.time;
|
|
1651
|
+
var match = current.data.target === last.data.target;
|
|
1652
|
+
return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
var data$b;
|
|
1656
|
+
var timeout$4 = null;
|
|
1657
|
+
var initialStateLogged = false;
|
|
1658
|
+
function start$r() {
|
|
1659
|
+
initialStateLogged = false;
|
|
1660
|
+
bind(window, "resize", recompute$5);
|
|
1661
|
+
recompute$5();
|
|
1662
|
+
}
|
|
1663
|
+
function recompute$5() {
|
|
1664
|
+
var de = document.documentElement;
|
|
1665
|
+
// window.innerWidth includes width of the scrollbar and is not a true representation of the viewport width.
|
|
1666
|
+
// Therefore, when possible, use documentElement's clientWidth property.
|
|
1667
|
+
data$b = {
|
|
1668
|
+
width: de && "clientWidth" in de ? Math.min(de.clientWidth, window.innerWidth) : window.innerWidth,
|
|
1669
|
+
height: de && "clientHeight" in de ? Math.min(de.clientHeight, window.innerHeight) : window.innerHeight,
|
|
1670
|
+
};
|
|
1671
|
+
if (initialStateLogged) {
|
|
1672
|
+
clearTimeout$1(timeout$4);
|
|
1673
|
+
timeout$4 = setTimeout$1(process$5, 500 /* Setting.LookAhead */, 11 /* Event.Resize */);
|
|
1674
|
+
}
|
|
1675
|
+
else {
|
|
1676
|
+
encode$3(11 /* Event.Resize */);
|
|
1677
|
+
initialStateLogged = true;
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
recompute$5.dn = 12 /* FunctionNames.ResizeRecompute */;
|
|
1681
|
+
function process$5(event) {
|
|
1682
|
+
schedule$1(encode$3.bind(this, event));
|
|
1683
|
+
}
|
|
1684
|
+
function reset$e() {
|
|
1685
|
+
data$b = null;
|
|
1686
|
+
clearTimeout$1(timeout$4);
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
var state$4 = [];
|
|
1690
|
+
var initialTop = null;
|
|
1691
|
+
var initialBottom = null;
|
|
1692
|
+
var timeout$3 = null;
|
|
1693
|
+
function start$q() {
|
|
1694
|
+
state$4 = [];
|
|
1695
|
+
recompute$4();
|
|
1696
|
+
}
|
|
1697
|
+
function observe$7(root) {
|
|
1698
|
+
var frame = iframe(root);
|
|
1699
|
+
var node = frame ? frame.contentWindow : (root === document ? window : root);
|
|
1700
|
+
bind(node, "scroll", recompute$4, true);
|
|
1701
|
+
}
|
|
1702
|
+
function recompute$4(event) {
|
|
1703
|
+
if (event === void 0) { event = null; }
|
|
1704
|
+
var w = window;
|
|
1705
|
+
var de = document.documentElement;
|
|
1706
|
+
var element = event ? target(event) : de;
|
|
1707
|
+
// If the target is a Document node, then identify corresponding documentElement and window for this document
|
|
1708
|
+
if (element && element.nodeType === Node.DOCUMENT_NODE) {
|
|
1709
|
+
var frame = iframe(element);
|
|
1710
|
+
w = frame ? frame.contentWindow : w;
|
|
1711
|
+
element = de = element.documentElement;
|
|
1712
|
+
}
|
|
1713
|
+
// Edge doesn't support scrollTop position on document.documentElement.
|
|
1714
|
+
// For cross browser compatibility, looking up pageYOffset on window if the scroll is on document.
|
|
1715
|
+
// And, if for some reason that is not available, fall back to looking up scrollTop on document.documentElement.
|
|
1716
|
+
var x = element === de && "pageXOffset" in w ? Math.round(w.pageXOffset) : Math.round(element.scrollLeft);
|
|
1717
|
+
var y = element === de && "pageYOffset" in w ? Math.round(w.pageYOffset) : Math.round(element.scrollTop);
|
|
1718
|
+
var width = window.innerWidth;
|
|
1719
|
+
var height = window.innerHeight;
|
|
1720
|
+
var xPosition = width / 3;
|
|
1721
|
+
var yOffset = width > height ? height * 0.15 : height * 0.2;
|
|
1722
|
+
var startYPosition = yOffset;
|
|
1723
|
+
var endYPosition = height - yOffset;
|
|
1724
|
+
var top = getPositionNode(xPosition, startYPosition);
|
|
1725
|
+
var bottom = getPositionNode(xPosition, endYPosition);
|
|
1726
|
+
var current = { time: time$1(event), event: 10 /* Event.Scroll */, data: { target: element, x: x, y: y, top: top, bottom: bottom } };
|
|
1727
|
+
// We don't send any scroll events if this is the first event and the current position is top (0,0)
|
|
1728
|
+
if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
|
|
1729
|
+
initialTop = top;
|
|
1730
|
+
initialBottom = bottom;
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1733
|
+
var length = state$4.length;
|
|
1734
|
+
var last = length > 1 ? state$4[length - 2] : null;
|
|
1735
|
+
if (last && similar(last, current)) {
|
|
1736
|
+
state$4.pop();
|
|
1737
|
+
}
|
|
1738
|
+
state$4.push(current);
|
|
1739
|
+
clearTimeout$1(timeout$3);
|
|
1740
|
+
timeout$3 = setTimeout$1(process$4, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
|
|
1741
|
+
}
|
|
1742
|
+
recompute$4.dn = 13 /* FunctionNames.ScrollRecompute */;
|
|
1743
|
+
function getPositionNode(x, y) {
|
|
1744
|
+
var _a, _b;
|
|
1745
|
+
var node;
|
|
1746
|
+
if ("caretPositionFromPoint" in document) {
|
|
1747
|
+
node = (_a = document.caretPositionFromPoint(x, y)) === null || _a === void 0 ? void 0 : _a.offsetNode;
|
|
1748
|
+
}
|
|
1749
|
+
else if ("caretRangeFromPoint" in document) {
|
|
1750
|
+
node = (_b = document.caretRangeFromPoint(x, y)) === null || _b === void 0 ? void 0 : _b.startContainer;
|
|
1751
|
+
}
|
|
1752
|
+
if (!node) {
|
|
1753
|
+
node = document.elementFromPoint(x, y);
|
|
1754
|
+
}
|
|
1755
|
+
if (node && node.nodeType === Node.TEXT_NODE) {
|
|
1756
|
+
node = node.parentNode;
|
|
1757
|
+
}
|
|
1758
|
+
return node;
|
|
1759
|
+
}
|
|
1760
|
+
function reset$d() {
|
|
1761
|
+
state$4 = [];
|
|
1762
|
+
initialTop = null;
|
|
1763
|
+
initialBottom = null;
|
|
1764
|
+
}
|
|
1765
|
+
function process$4(event) {
|
|
1766
|
+
schedule$1(encode$3.bind(this, event));
|
|
1767
|
+
}
|
|
1768
|
+
function similar(last, current) {
|
|
1769
|
+
var dx = last.data.x - current.data.x;
|
|
1770
|
+
var dy = last.data.y - current.data.y;
|
|
1771
|
+
return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
|
|
1772
|
+
}
|
|
1773
|
+
function compute$8() {
|
|
1774
|
+
var _a, _b;
|
|
1775
|
+
if (initialTop) {
|
|
1776
|
+
var top_1 = metadata$2(initialTop, null);
|
|
1777
|
+
log(31 /* Dimension.InitialScrollTop */, (_a = top_1 === null || top_1 === void 0 ? void 0 : top_1.hash) === null || _a === void 0 ? void 0 : _a.join("." /* Constant.Dot */));
|
|
1778
|
+
}
|
|
1779
|
+
if (initialBottom) {
|
|
1780
|
+
var bottom = metadata$2(initialBottom, null);
|
|
1781
|
+
log(32 /* Dimension.InitialScrollBottom */, (_b = bottom === null || bottom === void 0 ? void 0 : bottom.hash) === null || _b === void 0 ? void 0 : _b.join("." /* Constant.Dot */));
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
compute$8.dn = 14 /* FunctionNames.ScrollCompute */;
|
|
1785
|
+
|
|
1786
|
+
var data$a = null;
|
|
1787
|
+
var previous = null;
|
|
1788
|
+
var timeout$2 = null;
|
|
1789
|
+
function start$p() {
|
|
1790
|
+
reset$c();
|
|
1791
|
+
}
|
|
1792
|
+
function observe$6(root) {
|
|
1793
|
+
bind(root, "selectstart", recompute$3.bind(this, root), true);
|
|
1794
|
+
bind(root, "selectionchange", recompute$3.bind(this, root), true);
|
|
1795
|
+
}
|
|
1796
|
+
function recompute$3(root) {
|
|
1797
|
+
var doc = root.nodeType === Node.DOCUMENT_NODE ? root : document;
|
|
1798
|
+
var current = doc.getSelection();
|
|
1799
|
+
// Bail out if we don't have a valid selection
|
|
1800
|
+
if (current === null) {
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
// Bail out if we got a valid selection but not valid nodes
|
|
1804
|
+
// In Edge, selectionchange gets fired even on interactions like right clicks and
|
|
1805
|
+
// can result in null anchorNode and focusNode if there was no previous selection on page
|
|
1806
|
+
// Also, ignore any selections that start and end at the exact same point
|
|
1807
|
+
if ((current.anchorNode === null && current.focusNode === null) ||
|
|
1808
|
+
(current.anchorNode === current.focusNode && current.anchorOffset === current.focusOffset)) {
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
var startNode = data$a.start ? data$a.start : null;
|
|
1812
|
+
if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
|
|
1813
|
+
clearTimeout$1(timeout$2);
|
|
1814
|
+
process$3(21 /* Event.Selection */);
|
|
1815
|
+
}
|
|
1816
|
+
data$a = {
|
|
1817
|
+
start: current.anchorNode,
|
|
1818
|
+
startOffset: current.anchorOffset,
|
|
1819
|
+
end: current.focusNode,
|
|
1820
|
+
endOffset: current.focusOffset
|
|
1821
|
+
};
|
|
1822
|
+
previous = current;
|
|
1823
|
+
clearTimeout$1(timeout$2);
|
|
1824
|
+
timeout$2 = setTimeout$1(process$3, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
|
|
1825
|
+
}
|
|
1826
|
+
recompute$3.dn = 15 /* FunctionNames.SelectionRecompute */;
|
|
1827
|
+
function process$3(event) {
|
|
1828
|
+
schedule$1(encode$3.bind(this, event));
|
|
1829
|
+
}
|
|
1830
|
+
function reset$c() {
|
|
1831
|
+
previous = null;
|
|
1832
|
+
data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
var state$3 = [];
|
|
1836
|
+
function start$o() {
|
|
1837
|
+
reset$b();
|
|
1838
|
+
}
|
|
1839
|
+
function observe$5(root) {
|
|
1840
|
+
bind(root, "submit", recompute$2, true);
|
|
1841
|
+
}
|
|
1842
|
+
function recompute$2(evt) {
|
|
1843
|
+
state$3.push({ time: time$1(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
|
|
1844
|
+
schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
|
|
1845
|
+
}
|
|
1846
|
+
recompute$2.dn = 16 /* FunctionNames.SubmitRecompute */;
|
|
1847
|
+
function reset$b() {
|
|
1848
|
+
state$3 = [];
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
var data$9;
|
|
1852
|
+
function start$n() {
|
|
1853
|
+
bind(window, "pagehide", recompute$1);
|
|
1854
|
+
}
|
|
1855
|
+
function recompute$1(evt) {
|
|
1856
|
+
data$9 = { name: evt.type };
|
|
1857
|
+
encode$3(26 /* Event.Unload */, time$1(evt));
|
|
1858
|
+
}
|
|
1859
|
+
recompute$1.dn = 17 /* FunctionNames.UnloadRecompute */;
|
|
1860
|
+
function reset$a() {
|
|
1861
|
+
data$9 = null;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
var data$8;
|
|
1865
|
+
function start$m() {
|
|
1866
|
+
bind(document, "visibilitychange", recompute);
|
|
1867
|
+
recompute();
|
|
1868
|
+
}
|
|
1869
|
+
function recompute(evt) {
|
|
1870
|
+
if (evt === void 0) { evt = null; }
|
|
1871
|
+
data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
|
|
1872
|
+
encode$3(28 /* Event.Visibility */, time$1(evt));
|
|
1873
|
+
}
|
|
1874
|
+
recompute.dn = 18 /* FunctionNames.VisibilityRecompute */;
|
|
1875
|
+
function reset$9() {
|
|
1876
|
+
data$8 = null;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
function start$l() {
|
|
1880
|
+
start$g();
|
|
1881
|
+
start$v();
|
|
1882
|
+
start$u();
|
|
1883
|
+
start$s();
|
|
1884
|
+
start$t();
|
|
1885
|
+
start$r();
|
|
1886
|
+
start$m();
|
|
1887
|
+
start$q();
|
|
1888
|
+
start$p();
|
|
1889
|
+
start$w();
|
|
1890
|
+
start$o();
|
|
1891
|
+
start$n();
|
|
1892
|
+
}
|
|
1893
|
+
start$l.dn = 8 /* FunctionNames.InteractionStart */;
|
|
1894
|
+
function observe$4(root) {
|
|
1895
|
+
observe$7(root);
|
|
1896
|
+
// Only monitor following interactions if the root node is a document
|
|
1897
|
+
// In case of shadow DOM, following events automatically bubble up to the parent document.
|
|
1898
|
+
if (root.nodeType === Node.DOCUMENT_NODE) {
|
|
1899
|
+
observe$b(root);
|
|
1900
|
+
observe$a(root);
|
|
1901
|
+
observe$8(root);
|
|
1902
|
+
observe$9(root);
|
|
1903
|
+
observe$6(root);
|
|
1904
|
+
observe$c(root);
|
|
1905
|
+
observe$5(root);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
function traverse (root, timer, source, timestamp) {
|
|
1910
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1911
|
+
var queue, entry, next, state, subnode;
|
|
1912
|
+
return __generator(this, function (_a) {
|
|
1913
|
+
switch (_a.label) {
|
|
1914
|
+
case 0:
|
|
1915
|
+
queue = [root];
|
|
1916
|
+
_a.label = 1;
|
|
1917
|
+
case 1:
|
|
1918
|
+
if (!(queue.length > 0)) return [3 /*break*/, 4];
|
|
1919
|
+
entry = queue.shift();
|
|
1920
|
+
next = entry.firstChild;
|
|
1921
|
+
while (next) {
|
|
1922
|
+
queue.push(next);
|
|
1923
|
+
next = next.nextSibling;
|
|
1924
|
+
}
|
|
1925
|
+
state = state$a(timer);
|
|
1926
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
|
|
1927
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
1928
|
+
case 2:
|
|
1929
|
+
state = _a.sent();
|
|
1930
|
+
_a.label = 3;
|
|
1931
|
+
case 3:
|
|
1932
|
+
if (state === 2 /* Task.Stop */) {
|
|
1933
|
+
return [3 /*break*/, 4];
|
|
1934
|
+
}
|
|
1935
|
+
subnode = processNode(entry, source, timestamp);
|
|
1936
|
+
if (subnode) {
|
|
1937
|
+
queue.push(subnode);
|
|
1938
|
+
}
|
|
1939
|
+
return [3 /*break*/, 1];
|
|
1940
|
+
case 4: return [2 /*return*/];
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
var observers = [];
|
|
1947
|
+
var mutations = [];
|
|
1948
|
+
var throttledMutations = {};
|
|
1949
|
+
var insertRule = null;
|
|
1950
|
+
var deleteRule = null;
|
|
1951
|
+
var attachShadow = null;
|
|
1952
|
+
var mediaInsertRule = null;
|
|
1953
|
+
var mediaDeleteRule = null;
|
|
1954
|
+
var queue$2 = [];
|
|
1955
|
+
var timeout$1 = null;
|
|
1956
|
+
var throttleDelay = null;
|
|
1957
|
+
var activePeriod = null;
|
|
1958
|
+
var history$4 = {};
|
|
1959
|
+
function start$k() {
|
|
1960
|
+
observers = [];
|
|
1961
|
+
queue$2 = [];
|
|
1962
|
+
timeout$1 = null;
|
|
1963
|
+
activePeriod = 0;
|
|
1964
|
+
history$4 = {};
|
|
1965
|
+
// Some popular open source libraries, like styled-components, optimize performance
|
|
1966
|
+
// by injecting CSS using insertRule API vs. appending text node. A side effect of
|
|
1967
|
+
// using javascript API is that it doesn't trigger DOM mutation and therefore we
|
|
1968
|
+
// need to override the insertRule API and listen for changes manually.
|
|
1969
|
+
if (insertRule === null) {
|
|
1970
|
+
insertRule = CSSStyleSheet.prototype.insertRule;
|
|
1971
|
+
CSSStyleSheet.prototype.insertRule = function () {
|
|
1972
|
+
return insertRule.apply(this, arguments);
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
if ("CSSMediaRule" in window && mediaInsertRule === null) {
|
|
1976
|
+
mediaInsertRule = CSSMediaRule.prototype.insertRule;
|
|
1977
|
+
CSSMediaRule.prototype.insertRule = function () {
|
|
1978
|
+
return mediaInsertRule.apply(this, arguments);
|
|
1979
|
+
};
|
|
1980
|
+
}
|
|
1981
|
+
if (deleteRule === null) {
|
|
1982
|
+
deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
1983
|
+
CSSStyleSheet.prototype.deleteRule = function () {
|
|
1984
|
+
return deleteRule.apply(this, arguments);
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
if ("CSSMediaRule" in window && mediaDeleteRule === null) {
|
|
1988
|
+
mediaDeleteRule = CSSMediaRule.prototype.deleteRule;
|
|
1989
|
+
CSSMediaRule.prototype.deleteRule = function () {
|
|
1990
|
+
return mediaDeleteRule.apply(this, arguments);
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
// Add a hook to attachShadow API calls
|
|
1994
|
+
// In case we are unable to add a hook and browser throws an exception,
|
|
1995
|
+
// reset attachShadow variable and resume processing like before
|
|
1996
|
+
if (attachShadow === null) {
|
|
1997
|
+
attachShadow = Element.prototype.attachShadow;
|
|
1998
|
+
try {
|
|
1999
|
+
Element.prototype.attachShadow = function () {
|
|
2000
|
+
if (active()) ;
|
|
2001
|
+
else {
|
|
2002
|
+
return attachShadow.apply(this, arguments);
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
2005
|
+
}
|
|
2006
|
+
catch (_a) {
|
|
2007
|
+
attachShadow = null;
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
start$k.dn = 21 /* FunctionNames.MutationStart */;
|
|
2012
|
+
function observe$3(node) {
|
|
2013
|
+
// Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
|
|
2014
|
+
// In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
|
|
2015
|
+
// For this reason, we need to wire up mutations every time we see a new shadow dom.
|
|
2016
|
+
// Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
|
|
2017
|
+
try {
|
|
2018
|
+
var m = api("MutationObserver" /* Constant.MutationObserver */);
|
|
2019
|
+
var observer = m in window ? new window[m](measure(handle$1)) : null;
|
|
2020
|
+
if (observer) {
|
|
2021
|
+
observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
|
|
2022
|
+
observers.push(observer);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
catch (e) {
|
|
2026
|
+
log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
function monitor(frame) {
|
|
2030
|
+
// Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
|
|
2031
|
+
// This includes cases where iframe location is updated without explicitly updating src attribute
|
|
2032
|
+
// E.g. iframe.contentWindow.location.href = "new-location";
|
|
2033
|
+
if (has(frame) === false) {
|
|
2034
|
+
bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
function active$2() {
|
|
2038
|
+
activePeriod = time$1() + 3000 /* Setting.MutationActivePeriod */;
|
|
2039
|
+
}
|
|
2040
|
+
function handle$1(m) {
|
|
2041
|
+
// Queue up mutation records for asynchronous processing
|
|
2042
|
+
var now = time$1();
|
|
2043
|
+
track$7(6 /* Event.Mutation */, now);
|
|
2044
|
+
mutations.push({ time: now, mutations: m });
|
|
2045
|
+
schedule$1(process$2, 1 /* Priority.High */).then(function () {
|
|
2046
|
+
setTimeout$1(compute$9);
|
|
2047
|
+
measure(compute$6)();
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
handle$1.dn = 22 /* FunctionNames.MutationHandle */;
|
|
2051
|
+
function processMutation(timer, mutation, instance, timestamp) {
|
|
2052
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2053
|
+
var state, target, type;
|
|
2054
|
+
return __generator(this, function (_a) {
|
|
2055
|
+
switch (_a.label) {
|
|
2056
|
+
case 0:
|
|
2057
|
+
state = state$a(timer);
|
|
2058
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 2];
|
|
2059
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
2060
|
+
case 1:
|
|
2061
|
+
state = _a.sent();
|
|
2062
|
+
_a.label = 2;
|
|
2063
|
+
case 2:
|
|
2064
|
+
if (state === 2 /* Task.Stop */) {
|
|
2065
|
+
return [2 /*return*/];
|
|
2066
|
+
}
|
|
2067
|
+
target = mutation.target;
|
|
2068
|
+
type = track$5(mutation, timer, instance, timestamp) ;
|
|
2069
|
+
if (type && target && target.ownerDocument) {
|
|
2070
|
+
parse$1(target.ownerDocument);
|
|
2071
|
+
}
|
|
2072
|
+
if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
|
|
2073
|
+
parse$1(target);
|
|
2074
|
+
}
|
|
2075
|
+
switch (type) {
|
|
2076
|
+
case "attributes" /* Constant.Attributes */:
|
|
2077
|
+
processNode(target, 3 /* Source.Attributes */, timestamp);
|
|
2078
|
+
break;
|
|
2079
|
+
case "characterData" /* Constant.CharacterData */:
|
|
2080
|
+
processNode(target, 4 /* Source.CharacterData */, timestamp);
|
|
2081
|
+
break;
|
|
2082
|
+
case "childList" /* Constant.ChildList */:
|
|
2083
|
+
processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer, timestamp);
|
|
2084
|
+
processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer, timestamp);
|
|
2085
|
+
break;
|
|
2086
|
+
}
|
|
2087
|
+
return [2 /*return*/];
|
|
2088
|
+
}
|
|
2089
|
+
});
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
function process$2() {
|
|
2093
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2094
|
+
var timer, record, instance, _i, _a, mutation, processedMutations, _b, _c, key, throttledMutationToProcess;
|
|
2095
|
+
return __generator(this, function (_d) {
|
|
2096
|
+
switch (_d.label) {
|
|
2097
|
+
case 0:
|
|
2098
|
+
timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
|
|
2099
|
+
start$y(timer);
|
|
2100
|
+
_d.label = 1;
|
|
2101
|
+
case 1:
|
|
2102
|
+
if (!(mutations.length > 0)) return [3 /*break*/, 3];
|
|
2103
|
+
record = mutations.shift();
|
|
2104
|
+
instance = time$1();
|
|
2105
|
+
for (_i = 0, _a = record.mutations; _i < _a.length; _i++) {
|
|
2106
|
+
mutation = _a[_i];
|
|
2107
|
+
processMutation(timer, mutation, instance, record.time);
|
|
2108
|
+
}
|
|
2109
|
+
return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
|
|
2110
|
+
case 2:
|
|
2111
|
+
_d.sent();
|
|
2112
|
+
return [3 /*break*/, 1];
|
|
2113
|
+
case 3:
|
|
2114
|
+
processedMutations = false;
|
|
2115
|
+
for (_b = 0, _c = Object.keys(throttledMutations); _b < _c.length; _b++) {
|
|
2116
|
+
key = _c[_b];
|
|
2117
|
+
throttledMutationToProcess = throttledMutations[key];
|
|
2118
|
+
delete throttledMutations[key];
|
|
2119
|
+
processMutation(timer, throttledMutationToProcess.mutation, time$1(), throttledMutationToProcess.timestamp);
|
|
2120
|
+
processedMutations = true;
|
|
2121
|
+
}
|
|
2122
|
+
if (Object.keys(throttledMutations).length > 0) {
|
|
2123
|
+
processThrottledMutations();
|
|
2124
|
+
}
|
|
2125
|
+
if (!(Object.keys(throttledMutations).length === 0 && processedMutations)) return [3 /*break*/, 5];
|
|
2126
|
+
return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, time$1())];
|
|
2127
|
+
case 4:
|
|
2128
|
+
_d.sent();
|
|
2129
|
+
_d.label = 5;
|
|
2130
|
+
case 5:
|
|
2131
|
+
stop$w(timer);
|
|
2132
|
+
return [2 /*return*/];
|
|
2133
|
+
}
|
|
2134
|
+
});
|
|
2135
|
+
});
|
|
2136
|
+
}
|
|
2137
|
+
function track$5(m, timer, instance, timestamp) {
|
|
2138
|
+
var value = m.target ? get$2(m.target.parentNode) : null;
|
|
2139
|
+
// Check if the parent is already discovered and that the parent is not the document root
|
|
2140
|
+
if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
|
|
2141
|
+
// calculate inactive period based on the timestamp of the mutation not when the mutation is processed
|
|
2142
|
+
var inactive = timestamp > activePeriod;
|
|
2143
|
+
var target = get$2(m.target);
|
|
2144
|
+
var element = target && target.selector ? target.selector.join() : m.target.nodeName;
|
|
2145
|
+
var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
|
|
2146
|
+
// We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
|
|
2147
|
+
// repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
|
|
2148
|
+
// In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
|
|
2149
|
+
var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
|
|
2150
|
+
// Initialize an entry if it doesn't already exist
|
|
2151
|
+
history$4[key] = key in history$4 ? history$4[key] : [0, instance];
|
|
2152
|
+
var h = history$4[key];
|
|
2153
|
+
// Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
|
|
2154
|
+
if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
|
|
2155
|
+
processNodeList(h[2], 2 /* Source.ChildListRemove */, timer, timestamp);
|
|
2156
|
+
}
|
|
2157
|
+
// Update the counter
|
|
2158
|
+
h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
|
|
2159
|
+
h[1] = instance;
|
|
2160
|
+
// Return updated mutation type based on if we have already hit the threshold or not
|
|
2161
|
+
if (h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
|
|
2162
|
+
// Store a reference to removedNodes so we can process them later
|
|
2163
|
+
// when we resume mutations again on user interactions
|
|
2164
|
+
h[2] = m.removedNodes;
|
|
2165
|
+
if (instance > timestamp + 3000 /* Setting.MutationActivePeriod */) {
|
|
2166
|
+
return m.type;
|
|
2167
|
+
}
|
|
2168
|
+
// we only store the most recent mutation for a given key if it is being throttled
|
|
2169
|
+
throttledMutations[key] = { mutation: m, timestamp: timestamp };
|
|
2170
|
+
return "throttle" /* Constant.Throttle */;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
return m.type;
|
|
2174
|
+
}
|
|
2175
|
+
function names(nodes) {
|
|
2176
|
+
var output = [];
|
|
2177
|
+
for (var i = 0; nodes && i < nodes.length; i++) {
|
|
2178
|
+
output.push(nodes[i].nodeName);
|
|
2179
|
+
}
|
|
2180
|
+
return output.join();
|
|
2181
|
+
}
|
|
2182
|
+
function processNodeList(list, source, timer, timestamp) {
|
|
2183
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2184
|
+
var length, i, state;
|
|
2185
|
+
return __generator(this, function (_a) {
|
|
2186
|
+
switch (_a.label) {
|
|
2187
|
+
case 0:
|
|
2188
|
+
length = list ? list.length : 0;
|
|
2189
|
+
i = 0;
|
|
2190
|
+
_a.label = 1;
|
|
2191
|
+
case 1:
|
|
2192
|
+
if (!(i < length)) return [3 /*break*/, 6];
|
|
2193
|
+
if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
|
|
2194
|
+
traverse(list[i], timer, source, timestamp);
|
|
2195
|
+
return [3 /*break*/, 5];
|
|
2196
|
+
case 2:
|
|
2197
|
+
state = state$a(timer);
|
|
2198
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2199
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
2200
|
+
case 3:
|
|
2201
|
+
state = _a.sent();
|
|
2202
|
+
_a.label = 4;
|
|
2203
|
+
case 4:
|
|
2204
|
+
if (state === 2 /* Task.Stop */) {
|
|
2205
|
+
return [3 /*break*/, 6];
|
|
2206
|
+
}
|
|
2207
|
+
processNode(list[i], source, timestamp);
|
|
2208
|
+
_a.label = 5;
|
|
2209
|
+
case 5:
|
|
2210
|
+
i++;
|
|
2211
|
+
return [3 /*break*/, 1];
|
|
2212
|
+
case 6: return [2 /*return*/];
|
|
2213
|
+
}
|
|
2214
|
+
});
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
function processThrottledMutations() {
|
|
2218
|
+
if (throttleDelay) {
|
|
2219
|
+
clearTimeout$1(throttleDelay);
|
|
2220
|
+
}
|
|
2221
|
+
throttleDelay = setTimeout$1(function () { schedule$1(process$2, 1 /* Priority.High */); }, 33 /* Setting.LookAhead */);
|
|
2222
|
+
}
|
|
2223
|
+
function schedule(node) {
|
|
2224
|
+
// Only schedule manual trigger for this node if it's not already in the queue
|
|
2225
|
+
if (queue$2.indexOf(node) < 0) {
|
|
2226
|
+
queue$2.push(node);
|
|
2227
|
+
}
|
|
2228
|
+
// Cancel any previous trigger before scheduling a new one.
|
|
2229
|
+
// It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
|
|
2230
|
+
// And in those cases we do not wish to monitor changes multiple times for the same node.
|
|
2231
|
+
if (timeout$1) {
|
|
2232
|
+
clearTimeout$1(timeout$1);
|
|
2233
|
+
}
|
|
2234
|
+
timeout$1 = setTimeout$1(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
|
|
2235
|
+
return node;
|
|
2236
|
+
}
|
|
2237
|
+
function trigger$2() {
|
|
2238
|
+
for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
|
|
2239
|
+
var node = queue_1[_i];
|
|
2240
|
+
// Generate a mutation for this node only if it still exists
|
|
2241
|
+
if (node) {
|
|
2242
|
+
var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
|
2243
|
+
// Skip re-processing shadowRoot if it was already discovered
|
|
2244
|
+
if (shadowRoot && has(node)) {
|
|
2245
|
+
continue;
|
|
2246
|
+
}
|
|
2247
|
+
generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
queue$2 = [];
|
|
2251
|
+
}
|
|
2252
|
+
function generate(target, type) {
|
|
2253
|
+
measure(handle$1)([{
|
|
2254
|
+
addedNodes: [target],
|
|
2255
|
+
attributeName: null,
|
|
2256
|
+
attributeNamespace: null,
|
|
2257
|
+
nextSibling: null,
|
|
2258
|
+
oldValue: null,
|
|
2259
|
+
previousSibling: null,
|
|
2260
|
+
removedNodes: [],
|
|
2261
|
+
target: target,
|
|
2262
|
+
type: type
|
|
2263
|
+
}]);
|
|
2264
|
+
}
|
|
2265
|
+
generate.dn = 23 /* FunctionNames.MutationGenerate */;
|
|
2266
|
+
|
|
2267
|
+
var digitsRegex = /[^0-9\.]/g;
|
|
2268
|
+
/* JSON+LD (Linked Data) Recursive Parser */
|
|
2269
|
+
function ld(json) {
|
|
2270
|
+
for (var _i = 0, _a = Object.keys(json); _i < _a.length; _i++) {
|
|
2271
|
+
var key = _a[_i];
|
|
2272
|
+
var value = json[key];
|
|
2273
|
+
if (key === "@type" /* JsonLD.Type */ && typeof value === "string") {
|
|
2274
|
+
value = value.toLowerCase();
|
|
2275
|
+
/* Normalizations */
|
|
2276
|
+
value = value.indexOf("article" /* JsonLD.Article */) >= 0 || value.indexOf("posting" /* JsonLD.Posting */) >= 0 ? "article" /* JsonLD.Article */ : value;
|
|
2277
|
+
switch (value) {
|
|
2278
|
+
case "article" /* JsonLD.Article */:
|
|
2279
|
+
case "recipe" /* JsonLD.Recipe */:
|
|
2280
|
+
log(5 /* Dimension.SchemaType */, json[key]);
|
|
2281
|
+
log(8 /* Dimension.AuthorName */, json["creator" /* JsonLD.Creator */]);
|
|
2282
|
+
log(18 /* Dimension.Headline */, json["headline" /* JsonLD.Headline */]);
|
|
2283
|
+
break;
|
|
2284
|
+
case "product" /* JsonLD.Product */:
|
|
2285
|
+
log(5 /* Dimension.SchemaType */, json[key]);
|
|
2286
|
+
log(10 /* Dimension.ProductName */, json["name" /* JsonLD.Name */]);
|
|
2287
|
+
log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
|
|
2288
|
+
if (json["brand" /* JsonLD.Brand */]) {
|
|
2289
|
+
log(6 /* Dimension.ProductBrand */, json["brand" /* JsonLD.Brand */]["name" /* JsonLD.Name */]);
|
|
2290
|
+
}
|
|
2291
|
+
break;
|
|
2292
|
+
case "aggregaterating" /* JsonLD.AggregateRating */:
|
|
2293
|
+
if (json["ratingValue" /* JsonLD.RatingValue */]) {
|
|
2294
|
+
max(11 /* Metric.RatingValue */, num$1(json["ratingValue" /* JsonLD.RatingValue */], 100 /* Setting.RatingScale */));
|
|
2295
|
+
max(18 /* Metric.BestRating */, num$1(json["bestRating" /* JsonLD.BestRating */]));
|
|
2296
|
+
max(19 /* Metric.WorstRating */, num$1(json["worstRating" /* JsonLD.WorstRating */]));
|
|
2297
|
+
}
|
|
2298
|
+
max(12 /* Metric.RatingCount */, num$1(json["ratingCount" /* JsonLD.RatingCount */]));
|
|
2299
|
+
max(17 /* Metric.ReviewCount */, num$1(json["reviewCount" /* JsonLD.ReviewCount */]));
|
|
2300
|
+
break;
|
|
2301
|
+
case "offer" /* JsonLD.Offer */:
|
|
2302
|
+
log(7 /* Dimension.ProductAvailability */, json["availability" /* JsonLD.Availability */]);
|
|
2303
|
+
log(14 /* Dimension.ProductCondition */, json["itemCondition" /* JsonLD.ItemCondition */]);
|
|
2304
|
+
log(13 /* Dimension.ProductCurrency */, json["priceCurrency" /* JsonLD.PriceCurrency */]);
|
|
2305
|
+
log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
|
|
2306
|
+
max(13 /* Metric.ProductPrice */, num$1(json["price" /* JsonLD.Price */]));
|
|
2307
|
+
break;
|
|
2308
|
+
case "brand" /* JsonLD.Brand */:
|
|
2309
|
+
log(6 /* Dimension.ProductBrand */, json["name" /* JsonLD.Name */]);
|
|
2310
|
+
break;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
// Continue parsing nested objects
|
|
2314
|
+
if (value !== null && typeof (value) === "object" /* Constant.Object */) {
|
|
2315
|
+
ld(value);
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
function num$1(input, scale) {
|
|
2320
|
+
if (scale === void 0) { scale = 1; }
|
|
2321
|
+
if (input !== null) {
|
|
2322
|
+
switch (typeof input) {
|
|
2323
|
+
case "number" /* Constant.Number */: return Math.round(input * scale);
|
|
2324
|
+
case "string" /* Constant.String */: return Math.round(parseFloat(input.replace(digitsRegex, "" /* Constant.Empty */)) * scale);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
return null;
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror", "data-drupal-form-submit-last", "aria-label"];
|
|
2331
|
+
var newlineRegex = /[\r\n]+/g;
|
|
2332
|
+
function processNode (node, source, timestamp) {
|
|
2333
|
+
var _a;
|
|
2334
|
+
var child = null;
|
|
2335
|
+
// Do not track this change if we are attempting to remove a node before discovering it
|
|
2336
|
+
if (source === 2 /* Source.ChildListRemove */ && has(node) === false) {
|
|
2337
|
+
return child;
|
|
2338
|
+
}
|
|
2339
|
+
// Special handling for text nodes that belong to style nodes
|
|
2340
|
+
if (source !== 0 /* Source.Discover */ &&
|
|
2341
|
+
node.nodeType === Node.TEXT_NODE &&
|
|
2342
|
+
node.parentElement &&
|
|
2343
|
+
node.parentElement.tagName === "STYLE") {
|
|
2344
|
+
node = node.parentNode;
|
|
2345
|
+
}
|
|
2346
|
+
var add = has(node) === false;
|
|
2347
|
+
var call = add ? "add" : "update";
|
|
2348
|
+
var parent = node.parentElement ? node.parentElement : null;
|
|
2349
|
+
var insideFrame = node.ownerDocument !== document;
|
|
2350
|
+
switch (node.nodeType) {
|
|
2351
|
+
case Node.DOCUMENT_TYPE_NODE:
|
|
2352
|
+
parent = insideFrame && node.parentNode ? iframe(node.parentNode) : parent;
|
|
2353
|
+
var docTypePrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
|
|
2354
|
+
var doctype = node;
|
|
2355
|
+
var docName = doctype.name ? doctype.name : "HTML" /* Constant.HTML */;
|
|
2356
|
+
var docAttributes = { name: docName, publicId: doctype.publicId, systemId: doctype.systemId };
|
|
2357
|
+
var docData = { tag: docTypePrefix + "*D" /* Constant.DocumentTag */, attributes: docAttributes };
|
|
2358
|
+
dom$1[call](node, parent, docData, source);
|
|
2359
|
+
break;
|
|
2360
|
+
case Node.DOCUMENT_NODE:
|
|
2361
|
+
// We check for regions in the beginning when discovering document and
|
|
2362
|
+
// later whenever there are new additions or modifications to DOM (mutations)
|
|
2363
|
+
if (node === document)
|
|
2364
|
+
parse$1(document);
|
|
2365
|
+
checkDocumentStyles(node, timestamp);
|
|
2366
|
+
observe$2(node);
|
|
2367
|
+
break;
|
|
2368
|
+
case Node.DOCUMENT_FRAGMENT_NODE:
|
|
2369
|
+
var shadowRoot = node;
|
|
2370
|
+
if (shadowRoot.host) {
|
|
2371
|
+
parse$1(shadowRoot);
|
|
2372
|
+
var type = typeof (shadowRoot.constructor);
|
|
2373
|
+
if (type === "function" /* Constant.Function */ && shadowRoot.constructor.toString().indexOf("[native code]" /* Constant.NativeCode */) >= 0) {
|
|
2374
|
+
observe$2(shadowRoot);
|
|
2375
|
+
// See: https://wicg.github.io/construct-stylesheets/ for more details on adoptedStyleSheets.
|
|
2376
|
+
// At the moment, we are only able to capture "open" shadow DOM nodes. If they are closed, they are not accessible.
|
|
2377
|
+
// In future we may decide to proxy "attachShadow" call to gain access, but at the moment, we don't want to
|
|
2378
|
+
// cause any unintended side effect to the page. We will re-evaluate after we gather more real world data on this.
|
|
2379
|
+
var style = "" /* Constant.Empty */;
|
|
2380
|
+
var fragmentData = { tag: "*S" /* Constant.ShadowDomTag */, attributes: { style: style } };
|
|
2381
|
+
dom$1[call](node, shadowRoot.host, fragmentData, source);
|
|
2382
|
+
}
|
|
2383
|
+
else {
|
|
2384
|
+
// If the browser doesn't support shadow DOM natively, we detect that, and send appropriate tag back.
|
|
2385
|
+
// The differentiation is important because we don't have to observe pollyfill shadow DOM nodes,
|
|
2386
|
+
// the same way we observe real shadow DOM nodes (encapsulation provided by the browser).
|
|
2387
|
+
dom$1[call](node, shadowRoot.host, { tag: "*P" /* Constant.PolyfillShadowDomTag */, attributes: {} }, source);
|
|
2388
|
+
}
|
|
2389
|
+
checkDocumentStyles(node, timestamp);
|
|
2390
|
+
}
|
|
2391
|
+
break;
|
|
2392
|
+
case Node.TEXT_NODE:
|
|
2393
|
+
// In IE11 TEXT_NODE doesn't expose a valid parentElement property. Instead we need to lookup parentNode property.
|
|
2394
|
+
parent = parent ? parent : node.parentNode;
|
|
2395
|
+
// Account for this text node only if we are tracking the parent node
|
|
2396
|
+
// We do not wish to track text nodes for ignored parent nodes, like script tags
|
|
2397
|
+
// Also, we do not track text nodes for STYLE tags
|
|
2398
|
+
// The only exception is when we receive a mutation to remove the text node, in that case
|
|
2399
|
+
// parent will be null, but we can still process the node by checking it's an update call.
|
|
2400
|
+
if (call === "update" || (parent && has(parent) && parent.tagName !== "STYLE" && parent.tagName !== "NOSCRIPT")) {
|
|
2401
|
+
var textData = { tag: "*T" /* Constant.TextTag */, value: node.nodeValue };
|
|
2402
|
+
dom$1[call](node, parent, textData, source);
|
|
2403
|
+
}
|
|
2404
|
+
break;
|
|
2405
|
+
case Node.ELEMENT_NODE:
|
|
2406
|
+
var element = node;
|
|
2407
|
+
var tag = element.tagName;
|
|
2408
|
+
var attributes = getAttributes(element);
|
|
2409
|
+
// In some cases, external libraries like vue-fragment, can modify parentNode property to not be in sync with the DOM
|
|
2410
|
+
// For correctness, we first look at parentElement and if it not present then fall back to using parentNode
|
|
2411
|
+
parent = node.parentElement ? node.parentElement : (node.parentNode ? node.parentNode : null);
|
|
2412
|
+
// If we encounter a node that is part of SVG namespace, prefix the tag with SVG_PREFIX
|
|
2413
|
+
if (element.namespaceURI === "http://www.w3.org/2000/svg" /* Constant.SvgNamespace */) {
|
|
2414
|
+
tag = "svg:" /* Constant.SvgPrefix */ + tag;
|
|
2415
|
+
}
|
|
2416
|
+
switch (tag) {
|
|
2417
|
+
case "HTML":
|
|
2418
|
+
parent = insideFrame && parent ? iframe(parent) : parent;
|
|
2419
|
+
var htmlPrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
|
|
2420
|
+
var htmlData = { tag: htmlPrefix + tag, attributes: attributes };
|
|
2421
|
+
dom$1[call](node, parent, htmlData, source);
|
|
2422
|
+
break;
|
|
2423
|
+
case "SCRIPT":
|
|
2424
|
+
if ("type" /* Constant.Type */ in attributes && attributes["type" /* Constant.Type */] === "application/ld+json" /* Constant.JsonLD */) {
|
|
2425
|
+
try {
|
|
2426
|
+
ld(JSON.parse(element.text.replace(newlineRegex, "" /* Constant.Empty */)));
|
|
2427
|
+
}
|
|
2428
|
+
catch ( /* do nothing */_b) { /* do nothing */ }
|
|
2429
|
+
}
|
|
2430
|
+
break;
|
|
2431
|
+
case "NOSCRIPT":
|
|
2432
|
+
// keeping the noscript tag but ignoring its contents. Some HTML markup relies on having these tags
|
|
2433
|
+
// to maintain parity with the original css view, but we don't want to execute any noscript in Clarity
|
|
2434
|
+
var noscriptData = { tag: tag, attributes: {}, value: '' };
|
|
2435
|
+
dom$1[call](node, parent, noscriptData, source);
|
|
2436
|
+
break;
|
|
2437
|
+
case "META":
|
|
2438
|
+
var key = ("property" /* Constant.Property */ in attributes ?
|
|
2439
|
+
"property" /* Constant.Property */ :
|
|
2440
|
+
("name" /* Constant.Name */ in attributes ? "name" /* Constant.Name */ : null));
|
|
2441
|
+
if (key && "content" /* Constant.Content */ in attributes) {
|
|
2442
|
+
var content = attributes["content" /* Constant.Content */];
|
|
2443
|
+
switch (attributes[key]) {
|
|
2444
|
+
case "og:title" /* Constant.ogTitle */:
|
|
2445
|
+
log(20 /* Dimension.MetaTitle */, content);
|
|
2446
|
+
break;
|
|
2447
|
+
case "og:type" /* Constant.ogType */:
|
|
2448
|
+
log(19 /* Dimension.MetaType */, content);
|
|
2449
|
+
break;
|
|
2450
|
+
case "generator" /* Constant.Generator */:
|
|
2451
|
+
log(21 /* Dimension.Generator */, content);
|
|
2452
|
+
break;
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
break;
|
|
2456
|
+
case "HEAD":
|
|
2457
|
+
var head = { tag: tag, attributes: attributes };
|
|
2458
|
+
var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
|
|
2459
|
+
head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.host + l.pathname;
|
|
2460
|
+
dom$1[call](node, parent, head, source);
|
|
2461
|
+
break;
|
|
2462
|
+
case "BASE":
|
|
2463
|
+
// Override the auto detected base path to explicit value specified in this tag
|
|
2464
|
+
var baseHead = get$2(node.parentElement);
|
|
2465
|
+
if (baseHead) {
|
|
2466
|
+
// We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
|
|
2467
|
+
var a = document.createElement("a");
|
|
2468
|
+
a.href = attributes["href"];
|
|
2469
|
+
baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.host + a.pathname;
|
|
2470
|
+
}
|
|
2471
|
+
break;
|
|
2472
|
+
case "STYLE":
|
|
2473
|
+
var styleData = { tag: tag, attributes: attributes, value: getStyleValue(element) };
|
|
2474
|
+
dom$1[call](node, parent, styleData, source);
|
|
2475
|
+
break;
|
|
2476
|
+
case "IFRAME":
|
|
2477
|
+
var iframe$1 = node;
|
|
2478
|
+
var frameData = { tag: tag, attributes: attributes };
|
|
2479
|
+
if (sameorigin(iframe$1)) {
|
|
2480
|
+
monitor(iframe$1);
|
|
2481
|
+
frameData.attributes["*O" /* Constant.SameOrigin */] = "true";
|
|
2482
|
+
if (iframe$1.contentDocument && iframe$1.contentWindow && iframe$1.contentDocument.readyState !== "loading") {
|
|
2483
|
+
child = iframe$1.contentDocument;
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
dom$1[call](node, parent, frameData, source);
|
|
2487
|
+
break;
|
|
2488
|
+
case "LINK":
|
|
2489
|
+
// for links that aren't electron style sheets we can process them normally
|
|
2490
|
+
var linkData = { tag: tag, attributes: attributes };
|
|
2491
|
+
dom$1[call](node, parent, linkData, source);
|
|
2492
|
+
break;
|
|
2493
|
+
case "VIDEO":
|
|
2494
|
+
case "AUDIO":
|
|
2495
|
+
case "SOURCE":
|
|
2496
|
+
// Ignoring any base64 src attribute for media elements to prevent big unused tokens to be sent and shock the network
|
|
2497
|
+
if ("src" /* Constant.Src */ in attributes && attributes["src" /* Constant.Src */].startsWith("data:")) {
|
|
2498
|
+
attributes["src" /* Constant.Src */] = "";
|
|
2499
|
+
}
|
|
2500
|
+
var mediaTag = { tag: tag, attributes: attributes };
|
|
2501
|
+
dom$1[call](node, parent, mediaTag, source);
|
|
2502
|
+
break;
|
|
2503
|
+
default:
|
|
2504
|
+
var data = { tag: tag, attributes: attributes };
|
|
2505
|
+
if (element.shadowRoot) {
|
|
2506
|
+
child = element.shadowRoot;
|
|
2507
|
+
}
|
|
2508
|
+
dom$1[call](node, parent, data, source);
|
|
2509
|
+
break;
|
|
2510
|
+
}
|
|
2511
|
+
break;
|
|
2512
|
+
}
|
|
2513
|
+
return child;
|
|
2514
|
+
}
|
|
2515
|
+
function observe$2(root) {
|
|
2516
|
+
if (has(root)) {
|
|
2517
|
+
return;
|
|
2518
|
+
}
|
|
2519
|
+
observe$3(root); // Observe mutations for this root node
|
|
2520
|
+
observe$4(root); // Observe interactions for this root node
|
|
2521
|
+
}
|
|
2522
|
+
function getStyleValue(style) {
|
|
2523
|
+
// Call trim on the text content to ensure we do not process white spaces ( , \n, \r\n, \t, etc.)
|
|
2524
|
+
// Also, check if stylesheet has any data-* attribute, if so process rules instead of looking up text
|
|
2525
|
+
// Additionally, check if style node has an id - if so it's at a high risk to have experienced dynamic
|
|
2526
|
+
// style updates which would make the textContent out of date with its true style contribution.
|
|
2527
|
+
var value = style.textContent ? style.textContent.trim() : "" /* Constant.Empty */;
|
|
2528
|
+
var dataset = style.dataset ? Object.keys(style.dataset).length : 0;
|
|
2529
|
+
if (value.length === 0 || dataset > 0 || style.id.length > 0) {
|
|
2530
|
+
value = getCssRules(style.sheet);
|
|
2531
|
+
}
|
|
2532
|
+
return value;
|
|
2533
|
+
}
|
|
2534
|
+
function getCssRules(sheet) {
|
|
2535
|
+
var value = "" /* Constant.Empty */;
|
|
2536
|
+
var cssRules = null;
|
|
2537
|
+
// Firefox throws a SecurityError when trying to access cssRules of a stylesheet from a different domain
|
|
2538
|
+
try {
|
|
2539
|
+
cssRules = sheet ? sheet.cssRules : [];
|
|
2540
|
+
}
|
|
2541
|
+
catch (e) {
|
|
2542
|
+
log$1(1 /* Code.CssRules */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
2543
|
+
if (e && e.name !== "SecurityError") {
|
|
2544
|
+
throw e;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
if (cssRules !== null) {
|
|
2548
|
+
for (var i = 0; i < cssRules.length; i++) {
|
|
2549
|
+
value += cssRules[i].cssText;
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
return value;
|
|
2553
|
+
}
|
|
2554
|
+
function getAttributes(element) {
|
|
2555
|
+
var output = {};
|
|
2556
|
+
var attributes = element.attributes;
|
|
2557
|
+
if (attributes && attributes.length > 0) {
|
|
2558
|
+
for (var i = 0; i < attributes.length; i++) {
|
|
2559
|
+
var name_1 = attributes[i].name;
|
|
2560
|
+
if (IGNORE_ATTRIBUTES.indexOf(name_1) < 0) {
|
|
2561
|
+
output[name_1] = attributes[i].value;
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
// For INPUT tags read the dynamic "value" property if an explicit "value" attribute is not set
|
|
2566
|
+
if (element.tagName === "INPUT" /* Constant.InputTag */ && !("value" /* Constant.Value */ in output) && element.value) {
|
|
2567
|
+
output["value" /* Constant.Value */] = element.value;
|
|
2568
|
+
}
|
|
2569
|
+
return output;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
var sheetUpdateState = [];
|
|
2573
|
+
var sheetAdoptionState = [];
|
|
2574
|
+
var replace = null;
|
|
2575
|
+
var replaceSync = null;
|
|
2576
|
+
var styleSheetId = 'claritySheetId';
|
|
2577
|
+
var styleSheetPageNum = 'claritySheetNum';
|
|
2578
|
+
var styleSheetMap = {};
|
|
2579
|
+
function start$j() {
|
|
2580
|
+
if (replace === null) {
|
|
2581
|
+
replace = CSSStyleSheet.prototype.replace;
|
|
2582
|
+
CSSStyleSheet.prototype.replace = function () {
|
|
2583
|
+
return replace.apply(this, arguments);
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
if (replaceSync === null) {
|
|
2587
|
+
replaceSync = CSSStyleSheet.prototype.replaceSync;
|
|
2588
|
+
CSSStyleSheet.prototype.replaceSync = function () {
|
|
2589
|
+
return replaceSync.apply(this, arguments);
|
|
2590
|
+
};
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
function checkDocumentStyles(documentNode, timestamp) {
|
|
2594
|
+
timestamp = timestamp || time$1();
|
|
2595
|
+
if (!(documentNode === null || documentNode === void 0 ? void 0 : documentNode.adoptedStyleSheets)) {
|
|
2596
|
+
// if we don't have adoptedStyledSheets on the Node passed to us, we can short circuit.
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
2599
|
+
max(36 /* Metric.ConstructedStyles */, 1);
|
|
2600
|
+
var currentStyleSheets = [];
|
|
2601
|
+
for (var _i = 0, _a = documentNode.adoptedStyleSheets; _i < _a.length; _i++) {
|
|
2602
|
+
var styleSheet = _a[_i];
|
|
2603
|
+
var pageNum = data$2.pageNum;
|
|
2604
|
+
// If we haven't seen this style sheet on this page yet, we create a reference to it for the visualizer.
|
|
2605
|
+
// For SPA or times in which Clarity restarts on a given page, our visualizer would lose context
|
|
2606
|
+
// on the previously created style sheet for page N-1.
|
|
2607
|
+
// Then we synthetically call replaceSync with its contents to bootstrap it
|
|
2608
|
+
if (styleSheet[styleSheetPageNum] !== pageNum) {
|
|
2609
|
+
styleSheet[styleSheetPageNum] = pageNum;
|
|
2610
|
+
styleSheet[styleSheetId] = shortid();
|
|
2611
|
+
trackStyleChange(timestamp, styleSheet[styleSheetId], 0 /* StyleSheetOperation.Create */);
|
|
2612
|
+
trackStyleChange(timestamp, styleSheet[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, getCssRules(styleSheet));
|
|
2613
|
+
}
|
|
2614
|
+
currentStyleSheets.push(styleSheet[styleSheetId]);
|
|
2615
|
+
}
|
|
2616
|
+
var documentId = getId(documentNode, true);
|
|
2617
|
+
if (!styleSheetMap[documentId]) {
|
|
2618
|
+
styleSheetMap[documentId] = [];
|
|
2619
|
+
}
|
|
2620
|
+
if (!arraysEqual(currentStyleSheets, styleSheetMap[documentId])) {
|
|
2621
|
+
// Using -1 to signify the root document node as we don't track that as part of our nodeMap
|
|
2622
|
+
trackStyleAdoption(timestamp, documentNode == document ? -1 : getId(documentNode), 3 /* StyleSheetOperation.SetAdoptedStyles */, currentStyleSheets);
|
|
2623
|
+
styleSheetMap[documentId] = currentStyleSheets;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
function reset$8() {
|
|
2627
|
+
sheetAdoptionState = [];
|
|
2628
|
+
sheetUpdateState = [];
|
|
2629
|
+
}
|
|
2630
|
+
function trackStyleChange(time, id, operation, cssRules) {
|
|
2631
|
+
sheetUpdateState.push({
|
|
2632
|
+
time: time,
|
|
2633
|
+
event: 46 /* Event.StyleSheetUpdate */,
|
|
2634
|
+
data: {
|
|
2635
|
+
id: id,
|
|
2636
|
+
operation: operation,
|
|
2637
|
+
cssRules: cssRules
|
|
2638
|
+
}
|
|
2639
|
+
});
|
|
2640
|
+
encode$4(46 /* Event.StyleSheetUpdate */);
|
|
2641
|
+
}
|
|
2642
|
+
function trackStyleAdoption(time, id, operation, newIds) {
|
|
2643
|
+
sheetAdoptionState.push({
|
|
2644
|
+
time: time,
|
|
2645
|
+
event: 45 /* Event.StyleSheetAdoption */,
|
|
2646
|
+
data: {
|
|
2647
|
+
id: id,
|
|
2648
|
+
operation: operation,
|
|
2649
|
+
newIds: newIds
|
|
2650
|
+
}
|
|
2651
|
+
});
|
|
2652
|
+
encode$4(45 /* Event.StyleSheetAdoption */);
|
|
2653
|
+
}
|
|
2654
|
+
function arraysEqual(a, b) {
|
|
2655
|
+
if (a.length !== b.length) {
|
|
2656
|
+
return false;
|
|
2657
|
+
}
|
|
2658
|
+
return a.every(function (value, index) { return value === b[index]; });
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
var state$2 = [];
|
|
2662
|
+
var elementAnimate = null;
|
|
2663
|
+
var animationPlay = null;
|
|
2664
|
+
var animationPause = null;
|
|
2665
|
+
var animationCommitStyles = null;
|
|
2666
|
+
var animationCancel = null;
|
|
2667
|
+
var animationFinish = null;
|
|
2668
|
+
function start$i() {
|
|
2669
|
+
if (window["Animation"] &&
|
|
2670
|
+
window["Animation"].prototype &&
|
|
2671
|
+
window["KeyframeEffect"] &&
|
|
2672
|
+
window["KeyframeEffect"].prototype &&
|
|
2673
|
+
window["KeyframeEffect"].prototype.getKeyframes &&
|
|
2674
|
+
window["KeyframeEffect"].prototype.getTiming) {
|
|
2675
|
+
reset$7();
|
|
2676
|
+
overrideAnimationHelper(animationPlay, "play");
|
|
2677
|
+
overrideAnimationHelper(animationPause, "pause");
|
|
2678
|
+
overrideAnimationHelper(animationCommitStyles, "commitStyles");
|
|
2679
|
+
overrideAnimationHelper(animationCancel, "cancel");
|
|
2680
|
+
overrideAnimationHelper(animationFinish, "finish");
|
|
2681
|
+
if (elementAnimate === null) {
|
|
2682
|
+
elementAnimate = Element.prototype.animate;
|
|
2683
|
+
Element.prototype.animate = function () {
|
|
2684
|
+
var createdAnimation = elementAnimate.apply(this, arguments);
|
|
2685
|
+
return createdAnimation;
|
|
2686
|
+
};
|
|
2687
|
+
}
|
|
2688
|
+
if (document.getAnimations) {
|
|
2689
|
+
for (var _i = 0, _a = document.getAnimations(); _i < _a.length; _i++) {
|
|
2690
|
+
var animation = _a[_i];
|
|
2691
|
+
if (animation.playState === "finished") ;
|
|
2692
|
+
else if (animation.playState === "paused" || animation.playState === "idle") ;
|
|
2693
|
+
else if (animation.playState === "running") ;
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
function reset$7() {
|
|
2699
|
+
state$2 = [];
|
|
2700
|
+
}
|
|
2701
|
+
function overrideAnimationHelper(functionToOverride, name) {
|
|
2702
|
+
if (functionToOverride === null) {
|
|
2703
|
+
functionToOverride = Animation.prototype[name];
|
|
2704
|
+
Animation.prototype[name] = function () {
|
|
2705
|
+
return functionToOverride.apply(this, arguments);
|
|
2706
|
+
};
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
function encode$4 (type, timer, ts) {
|
|
2711
|
+
if (timer === void 0) { timer = null; }
|
|
2712
|
+
if (ts === void 0) { ts = null; }
|
|
2713
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2714
|
+
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;
|
|
2715
|
+
return __generator(this, function (_l) {
|
|
2716
|
+
switch (_l.label) {
|
|
2717
|
+
case 0:
|
|
2718
|
+
eventTime = ts || time$1();
|
|
2719
|
+
tokens = [eventTime, type];
|
|
2720
|
+
_a = type;
|
|
2721
|
+
switch (_a) {
|
|
2722
|
+
case 8 /* Event.Document */: return [3 /*break*/, 1];
|
|
2723
|
+
case 7 /* Event.Region */: return [3 /*break*/, 2];
|
|
2724
|
+
case 45 /* Event.StyleSheetAdoption */: return [3 /*break*/, 3];
|
|
2725
|
+
case 46 /* Event.StyleSheetUpdate */: return [3 /*break*/, 3];
|
|
2726
|
+
case 44 /* Event.Animation */: return [3 /*break*/, 4];
|
|
2727
|
+
case 5 /* Event.Discover */: return [3 /*break*/, 5];
|
|
2728
|
+
case 6 /* Event.Mutation */: return [3 /*break*/, 5];
|
|
2729
|
+
}
|
|
2730
|
+
return [3 /*break*/, 12];
|
|
2731
|
+
case 1:
|
|
2732
|
+
d = data$c;
|
|
2733
|
+
tokens.push(d.width);
|
|
2734
|
+
tokens.push(d.height);
|
|
2735
|
+
track$8(type, d.width, d.height);
|
|
2736
|
+
return [3 /*break*/, 12];
|
|
2737
|
+
case 2:
|
|
2738
|
+
for (_i = 0, _b = state$1; _i < _b.length; _i++) {
|
|
2739
|
+
r = _b[_i];
|
|
2740
|
+
tokens = [r.time, 7 /* Event.Region */];
|
|
2741
|
+
tokens.push(r.data.id);
|
|
2742
|
+
tokens.push(r.data.interaction);
|
|
2743
|
+
tokens.push(r.data.visibility);
|
|
2744
|
+
tokens.push(r.data.name);
|
|
2745
|
+
}
|
|
2746
|
+
reset$6();
|
|
2747
|
+
return [3 /*break*/, 12];
|
|
2748
|
+
case 3:
|
|
2749
|
+
for (_c = 0, _d = sheetAdoptionState; _c < _d.length; _c++) {
|
|
2750
|
+
entry = _d[_c];
|
|
2751
|
+
tokens = [entry.time, entry.event];
|
|
2752
|
+
tokens.push(entry.data.id);
|
|
2753
|
+
tokens.push(entry.data.operation);
|
|
2754
|
+
tokens.push(entry.data.newIds);
|
|
2755
|
+
}
|
|
2756
|
+
for (_e = 0, _f = sheetUpdateState; _e < _f.length; _e++) {
|
|
2757
|
+
entry = _f[_e];
|
|
2758
|
+
tokens = [entry.time, entry.event];
|
|
2759
|
+
tokens.push(entry.data.id);
|
|
2760
|
+
tokens.push(entry.data.operation);
|
|
2761
|
+
tokens.push(entry.data.cssRules);
|
|
2762
|
+
}
|
|
2763
|
+
reset$8();
|
|
2764
|
+
return [3 /*break*/, 12];
|
|
2765
|
+
case 4:
|
|
2766
|
+
for (_g = 0, _h = state$2; _g < _h.length; _g++) {
|
|
2767
|
+
entry = _h[_g];
|
|
2768
|
+
tokens = [entry.time, entry.event];
|
|
2769
|
+
tokens.push(entry.data.id);
|
|
2770
|
+
tokens.push(entry.data.operation);
|
|
2771
|
+
tokens.push(entry.data.keyFrames);
|
|
2772
|
+
tokens.push(entry.data.timing);
|
|
2773
|
+
tokens.push(entry.data.timeline);
|
|
2774
|
+
tokens.push(entry.data.targetId);
|
|
2775
|
+
}
|
|
2776
|
+
reset$7();
|
|
2777
|
+
return [3 /*break*/, 12];
|
|
2778
|
+
case 5:
|
|
2779
|
+
// Check if we are operating within the context of the current page
|
|
2780
|
+
if (state$a(timer) === 2 /* Task.Stop */) {
|
|
2781
|
+
return [3 /*break*/, 12];
|
|
2782
|
+
}
|
|
2783
|
+
values = updates$2();
|
|
2784
|
+
if (!(values.length > 0)) return [3 /*break*/, 11];
|
|
2785
|
+
_j = 0, values_1 = values;
|
|
2786
|
+
_l.label = 6;
|
|
2787
|
+
case 6:
|
|
2788
|
+
if (!(_j < values_1.length)) return [3 /*break*/, 10];
|
|
2789
|
+
value = values_1[_j];
|
|
2790
|
+
state = state$a(timer);
|
|
2791
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 8];
|
|
2792
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
2793
|
+
case 7:
|
|
2794
|
+
state = _l.sent();
|
|
2795
|
+
_l.label = 8;
|
|
2796
|
+
case 8:
|
|
2797
|
+
if (state === 2 /* Task.Stop */) {
|
|
2798
|
+
return [3 /*break*/, 10];
|
|
2799
|
+
}
|
|
2800
|
+
data = value.data;
|
|
2801
|
+
active = value.metadata.active;
|
|
2802
|
+
suspend = value.metadata.suspend;
|
|
2803
|
+
privacy = value.metadata.privacy;
|
|
2804
|
+
mangle = shouldMangle(value);
|
|
2805
|
+
keys = active ? ["tag", "attributes", "value"] : ["tag"];
|
|
2806
|
+
for (_k = 0, keys_1 = keys; _k < keys_1.length; _k++) {
|
|
2807
|
+
key = keys_1[_k];
|
|
2808
|
+
if (data[key]) {
|
|
2809
|
+
switch (key) {
|
|
2810
|
+
case "tag":
|
|
2811
|
+
box = size(value);
|
|
2812
|
+
factor = mangle ? -1 : 1;
|
|
2813
|
+
tokens.push(value.id * factor);
|
|
2814
|
+
if (value.parent && active) {
|
|
2815
|
+
tokens.push(value.parent);
|
|
2816
|
+
if (value.previous) {
|
|
2817
|
+
tokens.push(value.previous);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
|
|
2821
|
+
if (box && box.length === 2) {
|
|
2822
|
+
tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
|
|
2823
|
+
}
|
|
2824
|
+
break;
|
|
2825
|
+
case "attributes":
|
|
2826
|
+
for (attr in data[key]) {
|
|
2827
|
+
if (data[key][attr] !== undefined) {
|
|
2828
|
+
tokens.push(attribute(attr, data[key][attr], privacy));
|
|
2829
|
+
}
|
|
2830
|
+
}
|
|
2831
|
+
break;
|
|
2832
|
+
case "value":
|
|
2833
|
+
check$4(value.metadata.fraud, value.id, data[key]);
|
|
2834
|
+
tokens.push(text$1(data[key], data.tag, privacy, mangle));
|
|
2835
|
+
break;
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
_l.label = 9;
|
|
2840
|
+
case 9:
|
|
2841
|
+
_j++;
|
|
2842
|
+
return [3 /*break*/, 6];
|
|
2843
|
+
case 10:
|
|
2844
|
+
if (type === 6 /* Event.Mutation */) {
|
|
2845
|
+
activity(eventTime);
|
|
2846
|
+
}
|
|
2847
|
+
queue(tokenize(tokens));
|
|
2848
|
+
_l.label = 11;
|
|
2849
|
+
case 11: return [3 /*break*/, 12];
|
|
2850
|
+
case 12: return [2 /*return*/];
|
|
2851
|
+
}
|
|
2852
|
+
});
|
|
2853
|
+
});
|
|
2854
|
+
}
|
|
2855
|
+
function shouldMangle(value) {
|
|
2856
|
+
var privacy = value.metadata.privacy;
|
|
2857
|
+
return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
|
|
2858
|
+
}
|
|
2859
|
+
function size(value) {
|
|
2860
|
+
if (value.metadata.size !== null && value.metadata.size.length === 0) {
|
|
2861
|
+
var img = getNode(value.id);
|
|
2862
|
+
if (img) {
|
|
2863
|
+
return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
return value.metadata.size;
|
|
2867
|
+
}
|
|
2868
|
+
function str$1(input) {
|
|
2869
|
+
return input.toString(36);
|
|
2870
|
+
}
|
|
2871
|
+
function attribute(key, value, privacy) {
|
|
2872
|
+
return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2875
|
+
var state$1 = [];
|
|
2876
|
+
var regionMap = null; // Maps region nodes => region name
|
|
2877
|
+
var regions = {};
|
|
2878
|
+
var queue$1 = [];
|
|
2879
|
+
var watch = false;
|
|
2880
|
+
var observer$1 = null;
|
|
2881
|
+
function start$h() {
|
|
2882
|
+
reset$6();
|
|
2883
|
+
observer$1 = null;
|
|
2884
|
+
regionMap = new WeakMap();
|
|
2885
|
+
regions = {};
|
|
2886
|
+
queue$1 = [];
|
|
2887
|
+
watch = window["IntersectionObserver"] ? true : false;
|
|
2888
|
+
}
|
|
2889
|
+
function observe$1(node, name) {
|
|
2890
|
+
if (regionMap.has(node) === false) {
|
|
2891
|
+
regionMap.set(node, name);
|
|
2892
|
+
observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$1, {
|
|
2893
|
+
// Get notified as intersection continues to change
|
|
2894
|
+
// This allows us to process regions that get partially hidden during the lifetime of the page
|
|
2895
|
+
// See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
|
|
2896
|
+
// By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
|
|
2897
|
+
threshold: [0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
2898
|
+
}) : observer$1;
|
|
2899
|
+
if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
|
|
2900
|
+
observer$1.observe(node);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
function exists(node) {
|
|
2905
|
+
// Check if regionMap is not null before looking up a node
|
|
2906
|
+
// Since, dom module stops after region module, it's possible that we may set regionMap to be null
|
|
2907
|
+
// and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
|
|
2908
|
+
return regionMap && regionMap.has(node);
|
|
2909
|
+
}
|
|
2910
|
+
function track$3(id, event) {
|
|
2911
|
+
var node = getNode(id);
|
|
2912
|
+
var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
|
|
2913
|
+
// Determine the interaction state based on incoming event
|
|
2914
|
+
var interaction = 16 /* InteractionState.None */;
|
|
2915
|
+
switch (event) {
|
|
2916
|
+
case 9 /* Event.Click */:
|
|
2917
|
+
interaction = 20 /* InteractionState.Clicked */;
|
|
2918
|
+
break;
|
|
2919
|
+
case 27 /* Event.Input */:
|
|
2920
|
+
interaction = 30 /* InteractionState.Input */;
|
|
2921
|
+
break;
|
|
2922
|
+
}
|
|
2923
|
+
// Process updates to this region, if applicable
|
|
2924
|
+
process$1(node, data, interaction, data.visibility);
|
|
2925
|
+
}
|
|
2926
|
+
function compute$6() {
|
|
2927
|
+
// Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
|
|
2928
|
+
// This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
|
|
2929
|
+
// For those cases we add them to the queue and re-process them below
|
|
2930
|
+
var q = [];
|
|
2931
|
+
for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
|
|
2932
|
+
var r = queue_1[_i];
|
|
2933
|
+
var id = getId(r.node);
|
|
2934
|
+
if (id) {
|
|
2935
|
+
r.state.data.id = id;
|
|
2936
|
+
regions[id] = r.state.data;
|
|
2937
|
+
state$1.push(r.state);
|
|
2938
|
+
}
|
|
2939
|
+
else {
|
|
2940
|
+
q.push(r);
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
queue$1 = q;
|
|
2944
|
+
// Schedule encode only when we have at least one valid data entry
|
|
2945
|
+
if (state$1.length > 0) {
|
|
2946
|
+
encode$4(7 /* Event.Region */);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
compute$6.dn = 24 /* FunctionNames.RegionCompute */;
|
|
2950
|
+
function handler$1(entries) {
|
|
2951
|
+
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
|
|
2952
|
+
var entry = entries_1[_i];
|
|
2953
|
+
var target = entry.target;
|
|
2954
|
+
var rect = entry.boundingClientRect;
|
|
2955
|
+
var overlap = entry.intersectionRect;
|
|
2956
|
+
var viewport = entry.rootBounds;
|
|
2957
|
+
// Only capture regions that have non-zero width or height to avoid tracking and sending regions
|
|
2958
|
+
// that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
|
|
2959
|
+
// like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
|
|
2960
|
+
// 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
|
|
2961
|
+
if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
|
|
2962
|
+
var id = target ? getId(target) : null;
|
|
2963
|
+
var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
|
|
2964
|
+
// For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
|
|
2965
|
+
// However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
|
|
2966
|
+
var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
|
|
2967
|
+
var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
|
|
2968
|
+
// If an element is either visible or was visible and has been scrolled to the end
|
|
2969
|
+
// 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.
|
|
2970
|
+
// 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
|
|
2971
|
+
var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
|
|
2972
|
+
// Process updates to this region, if applicable
|
|
2973
|
+
process$1(target, data, data.interaction, (scrolledToEnd ?
|
|
2974
|
+
13 /* RegionVisibility.ScrolledToEnd */ :
|
|
2975
|
+
(visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
|
|
2976
|
+
// Stop observing this element now that we have already received scrolled signal
|
|
2977
|
+
if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
|
|
2978
|
+
observer$1.unobserve(target);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
if (state$1.length > 0) {
|
|
2983
|
+
encode$4(7 /* Event.Region */);
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
function process$1(n, d, s, v) {
|
|
2987
|
+
// Check if received a state that supersedes existing state
|
|
2988
|
+
var updated = s > d.interaction || v > d.visibility;
|
|
2989
|
+
d.interaction = s > d.interaction ? s : d.interaction;
|
|
2990
|
+
d.visibility = v > d.visibility ? v : d.visibility;
|
|
2991
|
+
// If the corresponding node is already discovered, update the internal state
|
|
2992
|
+
// Otherwise, track it in a queue to reprocess later.
|
|
2993
|
+
if (d.id) {
|
|
2994
|
+
if ((d.id in regions && updated) || !(d.id in regions)) {
|
|
2995
|
+
regions[d.id] = d;
|
|
2996
|
+
state$1.push(clone$1(d));
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
else {
|
|
3000
|
+
// Get the time before adding to queue to ensure accurate event time
|
|
3001
|
+
queue$1.push({ node: n, state: clone$1(d) });
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
function clone$1(r) {
|
|
3005
|
+
return { time: time$1(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
|
|
3006
|
+
}
|
|
3007
|
+
function reset$6() {
|
|
3008
|
+
state$1 = [];
|
|
3009
|
+
}
|
|
3010
|
+
|
|
3011
|
+
function target(evt) {
|
|
3012
|
+
var path = evt.composed && evt.composedPath ? evt.composedPath() : null;
|
|
3013
|
+
var node = (path && path.length > 0 ? path[0] : evt.target);
|
|
3014
|
+
active$2(); // Mark active periods of time so mutations can continue uninterrupted
|
|
3015
|
+
return node && node.nodeType === Node.DOCUMENT_NODE ? node.documentElement : node;
|
|
3016
|
+
}
|
|
3017
|
+
function metadata$2(node, event, text) {
|
|
3018
|
+
if (text === void 0) { text = null; }
|
|
3019
|
+
// If the node is null, we return a reserved value for id: 0. Valid assignment of id begins from 1+.
|
|
3020
|
+
var output = { id: 0, hash: null, privacy: 2 /* Privacy.Text */, node: node };
|
|
3021
|
+
if (node) {
|
|
3022
|
+
var value = get$2(node);
|
|
3023
|
+
if (value !== null) {
|
|
3024
|
+
var metadata_1 = value.metadata;
|
|
3025
|
+
output.id = value.id;
|
|
3026
|
+
output.hash = value.hash;
|
|
3027
|
+
output.privacy = metadata_1.privacy;
|
|
3028
|
+
if (value.region) {
|
|
3029
|
+
track$3(value.region, event);
|
|
3030
|
+
}
|
|
3031
|
+
if (metadata_1.fraud) {
|
|
3032
|
+
check$4(metadata_1.fraud, value.id, text || value.data.value);
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
return output;
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
function encode$3 (type, ts) {
|
|
3040
|
+
if (ts === void 0) { ts = null; }
|
|
3041
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3042
|
+
var t, tokens, _i, _a, entry, pTarget, _b, _c, entry, cTarget, cHash, _d, _e, entry, target, r, u, _f, _g, entry, iTarget, s, startTarget, endTarget, _h, _j, entry, sTarget, top_1, bottom, sTopHash, sBottomHash, _k, _l, entry, target, _m, _o, entry, target, _p, _q, entry, v;
|
|
3043
|
+
return __generator(this, function (_r) {
|
|
3044
|
+
t = ts || time$1();
|
|
3045
|
+
tokens = [t, type];
|
|
3046
|
+
switch (type) {
|
|
3047
|
+
case 13 /* Event.MouseDown */:
|
|
3048
|
+
case 14 /* Event.MouseUp */:
|
|
3049
|
+
case 12 /* Event.MouseMove */:
|
|
3050
|
+
case 15 /* Event.MouseWheel */:
|
|
3051
|
+
case 16 /* Event.DoubleClick */:
|
|
3052
|
+
case 17 /* Event.TouchStart */:
|
|
3053
|
+
case 18 /* Event.TouchEnd */:
|
|
3054
|
+
case 19 /* Event.TouchMove */:
|
|
3055
|
+
case 20 /* Event.TouchCancel */:
|
|
3056
|
+
for (_i = 0, _a = state$5; _i < _a.length; _i++) {
|
|
3057
|
+
entry = _a[_i];
|
|
3058
|
+
pTarget = metadata$2(entry.data.target, entry.event);
|
|
3059
|
+
if (pTarget.id > 0) {
|
|
3060
|
+
tokens = [entry.time, entry.event];
|
|
3061
|
+
tokens.push(pTarget.id);
|
|
3062
|
+
tokens.push(entry.data.x);
|
|
3063
|
+
tokens.push(entry.data.y);
|
|
3064
|
+
if (entry.data.id !== undefined) {
|
|
3065
|
+
tokens.push(entry.data.id);
|
|
3066
|
+
if (entry.data.isPrimary !== undefined) {
|
|
3067
|
+
tokens.push(entry.data.isPrimary.toString());
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
track$8(entry.event, entry.data.x, entry.data.y);
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
reset$f();
|
|
3074
|
+
break;
|
|
3075
|
+
case 9 /* Event.Click */:
|
|
3076
|
+
for (_b = 0, _c = state$8; _b < _c.length; _b++) {
|
|
3077
|
+
entry = _c[_b];
|
|
3078
|
+
cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
|
|
3079
|
+
tokens = [entry.time, entry.event];
|
|
3080
|
+
cHash = cTarget.hash ? cTarget.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
|
|
3081
|
+
tokens.push(cTarget.id);
|
|
3082
|
+
tokens.push(entry.data.x);
|
|
3083
|
+
tokens.push(entry.data.y);
|
|
3084
|
+
tokens.push(entry.data.eX);
|
|
3085
|
+
tokens.push(entry.data.eY);
|
|
3086
|
+
tokens.push(entry.data.button);
|
|
3087
|
+
tokens.push(entry.data.reaction);
|
|
3088
|
+
tokens.push(entry.data.context);
|
|
3089
|
+
tokens.push(text$1(entry.data.text, "click", cTarget.privacy));
|
|
3090
|
+
tokens.push(url$1(entry.data.link));
|
|
3091
|
+
tokens.push(cHash);
|
|
3092
|
+
tokens.push(entry.data.trust);
|
|
3093
|
+
track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
|
|
3094
|
+
}
|
|
3095
|
+
reset$i();
|
|
3096
|
+
break;
|
|
3097
|
+
case 38 /* Event.Clipboard */:
|
|
3098
|
+
for (_d = 0, _e = state$7; _d < _e.length; _d++) {
|
|
3099
|
+
entry = _e[_d];
|
|
3100
|
+
tokens = [entry.time, entry.event];
|
|
3101
|
+
target = metadata$2(entry.data.target, entry.event);
|
|
3102
|
+
if (target.id > 0) {
|
|
3103
|
+
tokens.push(target.id);
|
|
3104
|
+
tokens.push(entry.data.action);
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
reset$h();
|
|
3108
|
+
break;
|
|
3109
|
+
case 11 /* Event.Resize */:
|
|
3110
|
+
r = data$b;
|
|
3111
|
+
tokens.push(r.width);
|
|
3112
|
+
tokens.push(r.height);
|
|
3113
|
+
track$8(type, r.width, r.height);
|
|
3114
|
+
reset$e();
|
|
3115
|
+
break;
|
|
3116
|
+
case 26 /* Event.Unload */:
|
|
3117
|
+
u = data$9;
|
|
3118
|
+
tokens.push(u.name);
|
|
3119
|
+
reset$a();
|
|
3120
|
+
break;
|
|
3121
|
+
case 27 /* Event.Input */:
|
|
3122
|
+
for (_f = 0, _g = state$6; _f < _g.length; _f++) {
|
|
3123
|
+
entry = _g[_f];
|
|
3124
|
+
iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
|
|
3125
|
+
tokens = [entry.time, entry.event];
|
|
3126
|
+
tokens.push(iTarget.id);
|
|
3127
|
+
tokens.push(text$1(entry.data.value, "input", iTarget.privacy, false, entry.data.type));
|
|
3128
|
+
}
|
|
3129
|
+
reset$g();
|
|
3130
|
+
break;
|
|
3131
|
+
case 21 /* Event.Selection */:
|
|
3132
|
+
s = data$a;
|
|
3133
|
+
if (s) {
|
|
3134
|
+
startTarget = metadata$2(s.start, type);
|
|
3135
|
+
endTarget = metadata$2(s.end, type);
|
|
3136
|
+
tokens.push(startTarget.id);
|
|
3137
|
+
tokens.push(s.startOffset);
|
|
3138
|
+
tokens.push(endTarget.id);
|
|
3139
|
+
tokens.push(s.endOffset);
|
|
3140
|
+
reset$c();
|
|
3141
|
+
}
|
|
3142
|
+
break;
|
|
3143
|
+
case 10 /* Event.Scroll */:
|
|
3144
|
+
for (_h = 0, _j = state$4; _h < _j.length; _h++) {
|
|
3145
|
+
entry = _j[_h];
|
|
3146
|
+
sTarget = metadata$2(entry.data.target, entry.event);
|
|
3147
|
+
top_1 = metadata$2(entry.data.top, entry.event);
|
|
3148
|
+
bottom = metadata$2(entry.data.bottom, entry.event);
|
|
3149
|
+
sTopHash = (top_1 === null || top_1 === void 0 ? void 0 : top_1.hash) ? top_1.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
|
|
3150
|
+
sBottomHash = (bottom === null || bottom === void 0 ? void 0 : bottom.hash) ? bottom.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
|
|
3151
|
+
if (sTarget.id > 0) {
|
|
3152
|
+
tokens = [entry.time, entry.event];
|
|
3153
|
+
tokens.push(sTarget.id);
|
|
3154
|
+
tokens.push(entry.data.x);
|
|
3155
|
+
tokens.push(entry.data.y);
|
|
3156
|
+
tokens.push(sTopHash);
|
|
3157
|
+
tokens.push(sBottomHash);
|
|
3158
|
+
track$8(entry.event, entry.data.x, entry.data.y, entry.time);
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
reset$d();
|
|
3162
|
+
break;
|
|
3163
|
+
case 42 /* Event.Change */:
|
|
3164
|
+
for (_k = 0, _l = state$9; _k < _l.length; _k++) {
|
|
3165
|
+
entry = _l[_k];
|
|
3166
|
+
tokens = [entry.time, entry.event];
|
|
3167
|
+
target = metadata$2(entry.data.target, entry.event);
|
|
3168
|
+
if (target.id > 0) {
|
|
3169
|
+
tokens = [entry.time, entry.event];
|
|
3170
|
+
tokens.push(target.id);
|
|
3171
|
+
tokens.push(entry.data.type);
|
|
3172
|
+
tokens.push(text$1(entry.data.value, "change", target.privacy));
|
|
3173
|
+
tokens.push(text$1(entry.data.checksum, "checksum", target.privacy));
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
reset$j();
|
|
3177
|
+
break;
|
|
3178
|
+
case 39 /* Event.Submit */:
|
|
3179
|
+
for (_m = 0, _o = state$3; _m < _o.length; _m++) {
|
|
3180
|
+
entry = _o[_m];
|
|
3181
|
+
tokens = [entry.time, entry.event];
|
|
3182
|
+
target = metadata$2(entry.data.target, entry.event);
|
|
3183
|
+
if (target.id > 0) {
|
|
3184
|
+
tokens.push(target.id);
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
reset$b();
|
|
3188
|
+
break;
|
|
3189
|
+
case 22 /* Event.Timeline */:
|
|
3190
|
+
for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
|
|
3191
|
+
entry = _q[_p];
|
|
3192
|
+
tokens = [entry.time, entry.event];
|
|
3193
|
+
tokens.push(entry.data.type);
|
|
3194
|
+
tokens.push(entry.data.hash);
|
|
3195
|
+
tokens.push(entry.data.x);
|
|
3196
|
+
tokens.push(entry.data.y);
|
|
3197
|
+
tokens.push(entry.data.reaction);
|
|
3198
|
+
tokens.push(entry.data.context);
|
|
3199
|
+
}
|
|
3200
|
+
reset$5();
|
|
3201
|
+
break;
|
|
3202
|
+
case 28 /* Event.Visibility */:
|
|
3203
|
+
v = data$8;
|
|
3204
|
+
tokens.push(v.visible);
|
|
3205
|
+
visibility(t, v.visible);
|
|
3206
|
+
reset$9();
|
|
3207
|
+
break;
|
|
3208
|
+
}
|
|
3209
|
+
return [2 /*return*/];
|
|
3210
|
+
});
|
|
3211
|
+
});
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
var state$b = [];
|
|
3215
|
+
var updates$1 = [];
|
|
3216
|
+
function start$g() {
|
|
3217
|
+
state$b = [];
|
|
3218
|
+
reset$5();
|
|
3219
|
+
}
|
|
3220
|
+
function reset$5() {
|
|
3221
|
+
updates$1 = [];
|
|
3222
|
+
}
|
|
3223
|
+
function track$2(time, event, hash, x, y, reaction, context) {
|
|
3224
|
+
if (reaction === void 0) { reaction = 1 /* BooleanFlag.True */; }
|
|
3225
|
+
if (context === void 0) { context = 0 /* BrowsingContext.Self */; }
|
|
3226
|
+
state$b.push({
|
|
3227
|
+
time: time,
|
|
3228
|
+
event: 22 /* Event.Timeline */,
|
|
3229
|
+
data: {
|
|
3230
|
+
type: event,
|
|
3231
|
+
hash: hash,
|
|
3232
|
+
x: x,
|
|
3233
|
+
y: y,
|
|
3234
|
+
reaction: reaction,
|
|
3235
|
+
context: context
|
|
3236
|
+
}
|
|
3237
|
+
});
|
|
3238
|
+
// Since timeline only keeps the data for configured time, we still want to continue tracking these values
|
|
3239
|
+
// as part of the baseline. For instance, in a scenario where last scroll happened 5s ago.
|
|
3240
|
+
// We would still need to capture the last scroll position as part of the baseline event, even when timeline will be empty.
|
|
3241
|
+
track$8(event, x, y);
|
|
3242
|
+
}
|
|
3243
|
+
function queue(tokens, transmit) {
|
|
3244
|
+
}
|
|
3245
|
+
|
|
3246
|
+
var history$3 = {};
|
|
3247
|
+
var data$7;
|
|
3248
|
+
function start$e() {
|
|
3249
|
+
bind(window, "error", handler);
|
|
3250
|
+
history$3 = {};
|
|
3251
|
+
}
|
|
3252
|
+
function handler(error) {
|
|
3253
|
+
var e = error["error"] || error;
|
|
3254
|
+
// While rare, it's possible for code to fail repeatedly during the lifetime of the same page
|
|
3255
|
+
// In those cases, we only want to log the failure first few times and not spam logs with redundant information.
|
|
3256
|
+
if (!(e.message in history$3)) {
|
|
3257
|
+
history$3[e.message] = 0;
|
|
3258
|
+
}
|
|
3259
|
+
if (history$3[e.message]++ >= 5 /* Setting.ScriptErrorLimit */) {
|
|
3260
|
+
return true;
|
|
3261
|
+
}
|
|
3262
|
+
// Send back information only if the handled error has valid information
|
|
3263
|
+
if (e && e.message) {
|
|
3264
|
+
data$7 = {
|
|
3265
|
+
message: e.message,
|
|
3266
|
+
line: error["lineno"],
|
|
3267
|
+
column: error["colno"],
|
|
3268
|
+
stack: e.stack,
|
|
3269
|
+
source: error["filename"]
|
|
3270
|
+
};
|
|
3271
|
+
encode$2(31 /* Event.ScriptError */);
|
|
3272
|
+
}
|
|
3273
|
+
return true;
|
|
3274
|
+
}
|
|
3275
|
+
handler.dn = 4 /* FunctionNames.ScriptHandler */;
|
|
3276
|
+
|
|
3277
|
+
function encode$2 (type) {
|
|
3278
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3279
|
+
var tokens;
|
|
3280
|
+
return __generator(this, function (_a) {
|
|
3281
|
+
tokens = [time$1(), type];
|
|
3282
|
+
switch (type) {
|
|
3283
|
+
case 31 /* Event.ScriptError */:
|
|
3284
|
+
tokens.push(data$7.message);
|
|
3285
|
+
tokens.push(data$7.line);
|
|
3286
|
+
tokens.push(data$7.column);
|
|
3287
|
+
tokens.push(data$7.stack);
|
|
3288
|
+
tokens.push(url$1(data$7.source));
|
|
3289
|
+
break;
|
|
3290
|
+
case 33 /* Event.Log */:
|
|
3291
|
+
if (data$6) {
|
|
3292
|
+
tokens.push(data$6.code);
|
|
3293
|
+
tokens.push(data$6.name);
|
|
3294
|
+
tokens.push(data$6.message);
|
|
3295
|
+
tokens.push(data$6.stack);
|
|
3296
|
+
tokens.push(data$6.severity);
|
|
3297
|
+
}
|
|
3298
|
+
break;
|
|
3299
|
+
case 41 /* Event.Fraud */:
|
|
3300
|
+
if (data$d) {
|
|
3301
|
+
tokens.push(data$d.id);
|
|
3302
|
+
tokens.push(data$d.target);
|
|
3303
|
+
tokens.push(data$d.checksum);
|
|
3304
|
+
}
|
|
3305
|
+
break;
|
|
3306
|
+
}
|
|
3307
|
+
return [2 /*return*/];
|
|
3308
|
+
});
|
|
3309
|
+
});
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3312
|
+
var history$2 = {};
|
|
3313
|
+
var data$6;
|
|
3314
|
+
function start$d() {
|
|
3315
|
+
history$2 = {};
|
|
3316
|
+
}
|
|
3317
|
+
function log$1(code, severity, name, message, stack) {
|
|
3318
|
+
if (name === void 0) { name = null; }
|
|
3319
|
+
if (message === void 0) { message = null; }
|
|
3320
|
+
if (stack === void 0) { stack = null; }
|
|
3321
|
+
var key = name ? "".concat(name, "|").concat(message) : "";
|
|
3322
|
+
// While rare, it's possible for code to fail repeatedly during the lifetime of the same page
|
|
3323
|
+
// In those cases, we only want to log the failure once and not spam logs with redundant information.
|
|
3324
|
+
if (code in history$2 && history$2[code].indexOf(key) >= 0) {
|
|
3325
|
+
return;
|
|
3326
|
+
}
|
|
3327
|
+
data$6 = { code: code, name: name, message: message, stack: stack, severity: severity };
|
|
3328
|
+
// Maintain history of errors in memory to avoid sending redundant information
|
|
3329
|
+
if (code in history$2) {
|
|
3330
|
+
history$2[code].push(key);
|
|
3331
|
+
}
|
|
3332
|
+
else {
|
|
3333
|
+
history$2[code] = [key];
|
|
3334
|
+
}
|
|
3335
|
+
encode$2(33 /* Event.Log */);
|
|
3336
|
+
}
|
|
3337
|
+
|
|
3338
|
+
var data$4;
|
|
3339
|
+
function trigger(reason) {
|
|
3340
|
+
data$4.check = reason;
|
|
3341
|
+
// limit the dimensions we collect, but we don't need to stop Clarity entirely if we hit the limit
|
|
3342
|
+
if (reason !== 5 /* Check.Collection */) {
|
|
3343
|
+
clear();
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
|
|
3347
|
+
var data$3 = null;
|
|
3348
|
+
var updates = null;
|
|
3349
|
+
var limited = false;
|
|
3350
|
+
function log(dimension, value) {
|
|
3351
|
+
// Check valid value before moving ahead
|
|
3352
|
+
if (value) {
|
|
3353
|
+
// Ensure received value is casted into a string if it wasn't a string to begin with
|
|
3354
|
+
value = "".concat(value);
|
|
3355
|
+
if (!(dimension in data$3)) {
|
|
3356
|
+
data$3[dimension] = [];
|
|
3357
|
+
}
|
|
3358
|
+
if (data$3[dimension].indexOf(value) < 0) {
|
|
3359
|
+
// Limit check to ensure we have a cap on number of dimensions we can collect
|
|
3360
|
+
if (data$3[dimension].length > 128 /* Setting.CollectionLimit */) {
|
|
3361
|
+
if (!limited) {
|
|
3362
|
+
limited = true;
|
|
3363
|
+
trigger(5 /* Check.Collection */);
|
|
3364
|
+
}
|
|
3365
|
+
return;
|
|
3366
|
+
}
|
|
3367
|
+
data$3[dimension].push(value);
|
|
3368
|
+
// If this is a new value, track it as part of updates object
|
|
3369
|
+
// This allows us to only send back new values in subsequent payloads
|
|
3370
|
+
if (!(dimension in updates)) {
|
|
3371
|
+
updates[dimension] = [];
|
|
3372
|
+
}
|
|
3373
|
+
updates[dimension].push(value);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
|
|
3378
|
+
var data$2 = null;
|
|
3379
|
+
var rootDomain = null;
|
|
3380
|
+
function id() {
|
|
3381
|
+
return data$2 ? [data$2.userId, data$2.sessionId, data$2.pageNum].join("." /* Constant.Dot */) : "" /* Constant.Empty */;
|
|
3382
|
+
}
|
|
3383
|
+
function clear() {
|
|
3384
|
+
// Clear any stored information in the cookie that tracks session information so we can restart fresh the next time
|
|
3385
|
+
setCookie("_clsk" /* Constant.SessionKey */, "" /* Constant.Empty */, 0);
|
|
3386
|
+
}
|
|
3387
|
+
function supported(target, api) {
|
|
3388
|
+
try {
|
|
3389
|
+
return !!target[api];
|
|
3390
|
+
}
|
|
3391
|
+
catch (_a) {
|
|
3392
|
+
return false;
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
function shortid() {
|
|
3396
|
+
var id = Math.floor(Math.random() * Math.pow(2, 32));
|
|
3397
|
+
if (window && window.crypto && window.crypto.getRandomValues && Uint32Array) {
|
|
3398
|
+
id = window.crypto.getRandomValues(new Uint32Array(1))[0];
|
|
3399
|
+
}
|
|
3400
|
+
return id.toString(36);
|
|
3401
|
+
}
|
|
3402
|
+
function getCookie(key, limit) {
|
|
3403
|
+
var _a;
|
|
3404
|
+
if (limit === void 0) { limit = false; }
|
|
3405
|
+
if (supported(document, "cookie" /* Constant.Cookie */)) {
|
|
3406
|
+
var cookies = document.cookie.split(";" /* Constant.Semicolon */);
|
|
3407
|
+
if (cookies) {
|
|
3408
|
+
for (var i = 0; i < cookies.length; i++) {
|
|
3409
|
+
var pair = cookies[i].split("=" /* Constant.Equals */);
|
|
3410
|
+
if (pair.length > 1 && pair[0] && pair[0].trim() === key) {
|
|
3411
|
+
// Some browsers automatically url encode cookie values if they are not url encoded.
|
|
3412
|
+
// We therefore encode and decode cookie values ourselves.
|
|
3413
|
+
// For backwards compatability we need to consider 3 cases:
|
|
3414
|
+
// * Cookie was previously not encoded by Clarity and browser did not encode it
|
|
3415
|
+
// * Cookie was previously not encoded by Clarity and browser encoded it once or more
|
|
3416
|
+
// * Cookie was previously encoded by Clarity and browser did not encode it
|
|
3417
|
+
var _b = decodeCookieValue(pair[1]), isEncoded = _b[0], decodedValue = _b[1];
|
|
3418
|
+
while (isEncoded) {
|
|
3419
|
+
_a = decodeCookieValue(decodedValue), isEncoded = _a[0], decodedValue = _a[1];
|
|
3420
|
+
}
|
|
3421
|
+
// If we are limiting cookies, check if the cookie value is limited
|
|
3422
|
+
if (limit) {
|
|
3423
|
+
return decodedValue.endsWith("".concat("~" /* Constant.Tilde */, "1"))
|
|
3424
|
+
? decodedValue.substring(0, decodedValue.length - 2)
|
|
3425
|
+
: null;
|
|
3426
|
+
}
|
|
3427
|
+
return decodedValue;
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
return null;
|
|
3433
|
+
}
|
|
3434
|
+
function decodeCookieValue(value) {
|
|
3435
|
+
try {
|
|
3436
|
+
var decodedValue = decodeURIComponent(value);
|
|
3437
|
+
return [decodedValue != value, decodedValue];
|
|
3438
|
+
}
|
|
3439
|
+
catch (_a) {
|
|
3440
|
+
}
|
|
3441
|
+
return [false, value];
|
|
3442
|
+
}
|
|
3443
|
+
function encodeCookieValue(value) {
|
|
3444
|
+
return encodeURIComponent(value);
|
|
3445
|
+
}
|
|
3446
|
+
function setCookie(key, value, time) {
|
|
3447
|
+
// only write cookies if we are currently in a cookie writing mode (and they are supported)
|
|
3448
|
+
// OR if we are trying to write an empty cookie (i.e. clear the cookie value out)
|
|
3449
|
+
if (((navigator && navigator.cookieEnabled) || supported(document, "cookie" /* Constant.Cookie */))) {
|
|
3450
|
+
// Some browsers automatically url encode cookie values if they are not url encoded.
|
|
3451
|
+
// We therefore encode and decode cookie values ourselves.
|
|
3452
|
+
var encodedValue = encodeCookieValue(value);
|
|
3453
|
+
var expiry = new Date();
|
|
3454
|
+
expiry.setDate(expiry.getDate() + time);
|
|
3455
|
+
var expires = expiry ? "expires=" /* Constant.Expires */ + expiry.toUTCString() : "" /* Constant.Empty */;
|
|
3456
|
+
var cookie = "".concat(key, "=").concat(encodedValue).concat(";" /* Constant.Semicolon */).concat(expires).concat(";path=/" /* Constant.Path */);
|
|
3457
|
+
try {
|
|
3458
|
+
// Attempt to get the root domain only once and fall back to writing cookie on the current domain.
|
|
3459
|
+
if (rootDomain === null) {
|
|
3460
|
+
var hostname = location.hostname ? location.hostname.split("." /* Constant.Dot */) : [];
|
|
3461
|
+
// Walk backwards on a domain and attempt to set a cookie, until successful
|
|
3462
|
+
for (var i = hostname.length - 1; i >= 0; i--) {
|
|
3463
|
+
rootDomain = ".".concat(hostname[i]).concat(rootDomain ? rootDomain : "" /* Constant.Empty */);
|
|
3464
|
+
// We do not wish to attempt writing a cookie on the absolute last part of the domain, e.g. .com or .net.
|
|
3465
|
+
// So we start attempting after second-last part, e.g. .domain.com (PASS) or .co.uk (FAIL)
|
|
3466
|
+
if (i < hostname.length - 1) {
|
|
3467
|
+
// Write the cookie on the current computed top level domain
|
|
3468
|
+
document.cookie = "".concat(cookie).concat(";" /* Constant.Semicolon */).concat("domain=" /* Constant.Domain */).concat(rootDomain);
|
|
3469
|
+
// Once written, check if the cookie exists and its value matches exactly with what we intended to set
|
|
3470
|
+
// Checking for exact value match helps us eliminate a corner case where the cookie may already be present with a different value
|
|
3471
|
+
// If the check is successful, no more action is required and we can return from the function since rootDomain cookie is already set
|
|
3472
|
+
// If the check fails, continue with the for loop until we can successfully set and verify the cookie
|
|
3473
|
+
if (getCookie(key) === value) {
|
|
3474
|
+
return;
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
// Finally, if we were not successful and gone through all the options, play it safe and reset rootDomain to be empty
|
|
3479
|
+
// This forces our code to fall back to always writing cookie to the current domain
|
|
3480
|
+
rootDomain = "" /* Constant.Empty */;
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
catch (_a) {
|
|
3484
|
+
rootDomain = "" /* Constant.Empty */;
|
|
3485
|
+
}
|
|
3486
|
+
document.cookie = rootDomain ? "".concat(cookie).concat(";" /* Constant.Semicolon */).concat("domain=" /* Constant.Domain */).concat(rootDomain) : cookie;
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
function report(e) {
|
|
3490
|
+
return e;
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
// tslint:disable-next-line: ban-types
|
|
3494
|
+
function measure (method) {
|
|
3495
|
+
return function () {
|
|
3496
|
+
var start = performance.now();
|
|
3497
|
+
try {
|
|
3498
|
+
method.apply(this, arguments);
|
|
3499
|
+
}
|
|
3500
|
+
catch (ex) {
|
|
3501
|
+
throw report(ex);
|
|
3502
|
+
}
|
|
3503
|
+
var duration = performance.now() - start;
|
|
3504
|
+
sum(4 /* Metric.TotalCost */, duration);
|
|
3505
|
+
if (duration > config$2.longTask) {
|
|
3506
|
+
count$1(7 /* Metric.LongTaskCount */);
|
|
3507
|
+
max(6 /* Metric.ThreadBlockedTime */, duration);
|
|
3508
|
+
log$1(9 /* Code.FunctionExecutionTime */, 0 /* Severity.Info */, "".concat(method.dn || method.name, "-").concat(duration));
|
|
3509
|
+
}
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3513
|
+
var bindings = [];
|
|
3514
|
+
function bind(target, event, listener, capture) {
|
|
3515
|
+
if (capture === void 0) { capture = false; }
|
|
3516
|
+
listener = measure(listener);
|
|
3517
|
+
// Wrapping following lines inside try / catch to cover edge cases where we might try to access an inaccessible element.
|
|
3518
|
+
// E.g. Iframe may start off as same-origin but later turn into cross-origin, and the following lines will throw an exception.
|
|
3519
|
+
try {
|
|
3520
|
+
target[api("addEventListener" /* Constant.AddEventListener */)](event, listener, capture);
|
|
3521
|
+
bindings.push({ event: event, target: target, listener: listener, capture: capture });
|
|
3522
|
+
}
|
|
3523
|
+
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
3524
|
+
}
|
|
3525
|
+
|
|
3526
|
+
var status = false;
|
|
3527
|
+
function active() {
|
|
3528
|
+
return status;
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
function start$5() {
|
|
3532
|
+
start$A();
|
|
3533
|
+
start$e();
|
|
3534
|
+
start$d();
|
|
3535
|
+
}
|
|
3536
|
+
start$5.dn = 3 /* FunctionNames.DiagnosticStart */;
|
|
3537
|
+
|
|
3538
|
+
function start$4() {
|
|
3539
|
+
schedule$1(discover, 1 /* Priority.High */).then(function () {
|
|
3540
|
+
measure(compute$9)();
|
|
3541
|
+
measure(compute$6)();
|
|
3542
|
+
measure(compute$8)();
|
|
3543
|
+
});
|
|
3544
|
+
}
|
|
3545
|
+
function discover() {
|
|
3546
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3547
|
+
var ts, timer;
|
|
3548
|
+
return __generator(this, function (_a) {
|
|
3549
|
+
switch (_a.label) {
|
|
3550
|
+
case 0:
|
|
3551
|
+
ts = time$1();
|
|
3552
|
+
timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
|
|
3553
|
+
start$y(timer);
|
|
3554
|
+
return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */, ts)];
|
|
3555
|
+
case 1:
|
|
3556
|
+
_a.sent();
|
|
3557
|
+
checkDocumentStyles(document, ts);
|
|
3558
|
+
return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
|
|
3559
|
+
case 2:
|
|
3560
|
+
_a.sent();
|
|
3561
|
+
stop$w(timer);
|
|
3562
|
+
return [2 /*return*/];
|
|
3563
|
+
}
|
|
3564
|
+
});
|
|
3565
|
+
});
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
function start$3() {
|
|
3569
|
+
// The order below is important
|
|
3570
|
+
// and is determined by interdependencies of modules
|
|
3571
|
+
start$x();
|
|
3572
|
+
start$h();
|
|
3573
|
+
start$z();
|
|
3574
|
+
{
|
|
3575
|
+
start$k();
|
|
3576
|
+
}
|
|
3577
|
+
start$4();
|
|
3578
|
+
start$j();
|
|
3579
|
+
start$i();
|
|
3580
|
+
}
|
|
3581
|
+
start$3.dn = 20 /* FunctionNames.LayoutStart */;
|
|
3582
|
+
|
|
3583
|
+
function encode (type) {
|
|
3584
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3585
|
+
var t, tokens;
|
|
3586
|
+
return __generator(this, function (_a) {
|
|
3587
|
+
t = time$1();
|
|
3588
|
+
tokens = [t, type];
|
|
3589
|
+
switch (type) {
|
|
3590
|
+
case 29 /* Event.Navigation */:
|
|
3591
|
+
tokens.push(data.fetchStart);
|
|
3592
|
+
tokens.push(data.connectStart);
|
|
3593
|
+
tokens.push(data.connectEnd);
|
|
3594
|
+
tokens.push(data.requestStart);
|
|
3595
|
+
tokens.push(data.responseStart);
|
|
3596
|
+
tokens.push(data.responseEnd);
|
|
3597
|
+
tokens.push(data.domInteractive);
|
|
3598
|
+
tokens.push(data.domComplete);
|
|
3599
|
+
tokens.push(data.loadEventStart);
|
|
3600
|
+
tokens.push(data.loadEventEnd);
|
|
3601
|
+
tokens.push(data.redirectCount);
|
|
3602
|
+
tokens.push(data.size);
|
|
3603
|
+
tokens.push(data.type);
|
|
3604
|
+
tokens.push(data.protocol);
|
|
3605
|
+
tokens.push(data.encodedSize);
|
|
3606
|
+
tokens.push(data.decodedSize);
|
|
3607
|
+
reset();
|
|
3608
|
+
break;
|
|
3609
|
+
}
|
|
3610
|
+
return [2 /*return*/];
|
|
3611
|
+
});
|
|
3612
|
+
});
|
|
3613
|
+
}
|
|
3614
|
+
|
|
3615
|
+
var data = null;
|
|
3616
|
+
function reset() {
|
|
3617
|
+
data = null;
|
|
3618
|
+
}
|
|
3619
|
+
function compute(entry) {
|
|
3620
|
+
data = {
|
|
3621
|
+
fetchStart: Math.round(entry.fetchStart),
|
|
3622
|
+
connectStart: Math.round(entry.connectStart),
|
|
3623
|
+
connectEnd: Math.round(entry.connectEnd),
|
|
3624
|
+
requestStart: Math.round(entry.requestStart),
|
|
3625
|
+
responseStart: Math.round(entry.responseStart),
|
|
3626
|
+
responseEnd: Math.round(entry.responseEnd),
|
|
3627
|
+
domInteractive: Math.round(entry.domInteractive),
|
|
3628
|
+
domComplete: Math.round(entry.domComplete),
|
|
3629
|
+
loadEventStart: Math.round(entry.loadEventStart),
|
|
3630
|
+
loadEventEnd: Math.round(entry.loadEventEnd),
|
|
3631
|
+
redirectCount: Math.round(entry.redirectCount),
|
|
3632
|
+
size: entry.transferSize ? entry.transferSize : 0,
|
|
3633
|
+
type: entry.type,
|
|
3634
|
+
protocol: entry.nextHopProtocol,
|
|
3635
|
+
encodedSize: entry.encodedBodySize ? entry.encodedBodySize : 0,
|
|
3636
|
+
decodedSize: entry.decodedBodySize ? entry.decodedBodySize : 0
|
|
3637
|
+
};
|
|
3638
|
+
encode(29 /* Event.Navigation */);
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
// Estimate variables to keep track of interactions
|
|
3642
|
+
var interactionCountEstimate = 0;
|
|
3643
|
+
var minKnownInteractionId = Infinity;
|
|
3644
|
+
var maxKnownInteractionId = 0;
|
|
3645
|
+
var prevInteractionCount = 0; // Used to track interaction count between pages
|
|
3646
|
+
var MAX_INTERACTIONS_TO_CONSIDER = 10; // Maximum number of interactions we consider for INP
|
|
3647
|
+
var DEFAULT_DURATION_THRESHOLD = 40; // Threshold to ignore very short interactions
|
|
3648
|
+
// List to store the longest interaction events
|
|
3649
|
+
var longestInteractionList = [];
|
|
3650
|
+
// Map to track interactions by their ID, ensuring we handle duplicates
|
|
3651
|
+
var longestInteractionMap = new Map();
|
|
3652
|
+
/**
|
|
3653
|
+
* Update the approx number of interactions estimate count if the interactionCount is not supported.
|
|
3654
|
+
* The difference between `maxKnownInteractionId` and `minKnownInteractionId` gives us a rough range of how many interactions have occurred.
|
|
3655
|
+
* Dividing by 7 helps approximate the interaction count more accurately, since interaction IDs are spread out across a large range.
|
|
3656
|
+
*/
|
|
3657
|
+
var countInteractions = function (entry) {
|
|
3658
|
+
if ('interactionCount' in performance) {
|
|
3659
|
+
interactionCountEstimate = performance.interactionCount;
|
|
3660
|
+
return;
|
|
3661
|
+
}
|
|
3662
|
+
if (entry.interactionId) {
|
|
3663
|
+
minKnownInteractionId = Math.min(minKnownInteractionId, entry.interactionId);
|
|
3664
|
+
maxKnownInteractionId = Math.max(maxKnownInteractionId, entry.interactionId);
|
|
3665
|
+
interactionCountEstimate = maxKnownInteractionId
|
|
3666
|
+
? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1
|
|
3667
|
+
: 0;
|
|
3668
|
+
}
|
|
3669
|
+
};
|
|
3670
|
+
var getInteractionCount = function () {
|
|
3671
|
+
return interactionCountEstimate || 0;
|
|
3672
|
+
};
|
|
3673
|
+
var getInteractionCountForNavigation = function () {
|
|
3674
|
+
return getInteractionCount() - prevInteractionCount;
|
|
3675
|
+
};
|
|
3676
|
+
/**
|
|
3677
|
+
* Estimates the 98th percentile (P98) of the longest interactions by selecting
|
|
3678
|
+
* the candidate interaction based on the current interaction count.
|
|
3679
|
+
* Dividing by 50 is a heuristic to estimate the 98th percentile (P98) interaction.
|
|
3680
|
+
* This assumes one out of every 50 interactions represents the P98 interaction.
|
|
3681
|
+
* By dividing the total interaction count by 50, we get an index to approximate
|
|
3682
|
+
* the slowest 2% of interactions, helping identify a likely P98 candidate.
|
|
3683
|
+
*/
|
|
3684
|
+
var estimateP98LongestInteraction = function () {
|
|
3685
|
+
if (!longestInteractionList.length) {
|
|
3686
|
+
return -1;
|
|
3687
|
+
}
|
|
3688
|
+
var candidateInteractionIndex = Math.min(longestInteractionList.length - 1, Math.floor(getInteractionCountForNavigation() / 50));
|
|
3689
|
+
return longestInteractionList[candidateInteractionIndex].latency;
|
|
3690
|
+
};
|
|
3691
|
+
/**
|
|
3692
|
+
* Processes a PerformanceEventTiming entry by updating the longest interaction list.
|
|
3693
|
+
*/
|
|
3694
|
+
var processInteractionEntry = function (entry) {
|
|
3695
|
+
// Ignore entries with 0 interactionId or very short durations
|
|
3696
|
+
if (!entry.interactionId || entry.duration < DEFAULT_DURATION_THRESHOLD) {
|
|
3697
|
+
return;
|
|
3698
|
+
}
|
|
3699
|
+
countInteractions(entry);
|
|
3700
|
+
var minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
|
|
3701
|
+
var existingInteraction = longestInteractionMap.get(entry.interactionId);
|
|
3702
|
+
// Either update existing, add new, or replace shortest interaction if necessary
|
|
3703
|
+
if (existingInteraction ||
|
|
3704
|
+
longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
|
|
3705
|
+
entry.duration > (minLongestInteraction === null || minLongestInteraction === void 0 ? void 0 : minLongestInteraction.latency)) {
|
|
3706
|
+
if (!existingInteraction) {
|
|
3707
|
+
var interaction = {
|
|
3708
|
+
id: entry.interactionId,
|
|
3709
|
+
latency: entry.duration,
|
|
3710
|
+
};
|
|
3711
|
+
longestInteractionMap.set(interaction.id, interaction);
|
|
3712
|
+
longestInteractionList.push(interaction);
|
|
3713
|
+
}
|
|
3714
|
+
else if (entry.duration > existingInteraction.latency) {
|
|
3715
|
+
existingInteraction.latency = entry.duration;
|
|
3716
|
+
}
|
|
3717
|
+
longestInteractionList.sort(function (a, b) { return b.latency - a.latency; });
|
|
3718
|
+
// Trim the list to the maximum number of interactions to consider
|
|
3719
|
+
if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {
|
|
3720
|
+
longestInteractionList
|
|
3721
|
+
.splice(MAX_INTERACTIONS_TO_CONSIDER)
|
|
3722
|
+
.forEach(function (i) { return longestInteractionMap.delete(i.id); });
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
};
|
|
3726
|
+
|
|
3727
|
+
var observer;
|
|
3728
|
+
var types = ["navigation" /* Constant.Navigation */, "resource" /* Constant.Resource */, "longtask" /* Constant.LongTask */, "first-input" /* Constant.FID */, "layout-shift" /* Constant.CLS */, "largest-contentful-paint" /* Constant.LCP */, "event" /* Constant.PerformanceEventTiming */];
|
|
3729
|
+
function start$2() {
|
|
3730
|
+
// Capture connection properties, if available
|
|
3731
|
+
if (navigator && "connection" in navigator) {
|
|
3732
|
+
log(27 /* Dimension.ConnectionType */, navigator["connection"]["effectiveType"]);
|
|
3733
|
+
}
|
|
3734
|
+
// Check the browser support performance observer as a pre-requisite for any performance measurement
|
|
3735
|
+
if (window["PerformanceObserver"] && PerformanceObserver.supportedEntryTypes) {
|
|
3736
|
+
// Start monitoring performance data after page has finished loading.
|
|
3737
|
+
// If the document.readyState is not yet complete, we intentionally call observe using a setTimeout.
|
|
3738
|
+
// This allows us to capture loadEventEnd on navigation timeline.
|
|
3739
|
+
if (document.readyState !== "complete") {
|
|
3740
|
+
bind(window, "load", setTimeout$1.bind(this, observe, 0));
|
|
3741
|
+
}
|
|
3742
|
+
else {
|
|
3743
|
+
observe();
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
else {
|
|
3747
|
+
log$1(3 /* Code.PerformanceObserver */, 0 /* Severity.Info */);
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
function observe() {
|
|
3751
|
+
// Some browsers will throw an error for unsupported entryType, e.g. "layout-shift"
|
|
3752
|
+
// In those cases, we log it as a warning and continue with rest of the Clarity processing
|
|
3753
|
+
try {
|
|
3754
|
+
if (observer) {
|
|
3755
|
+
observer.disconnect();
|
|
3756
|
+
}
|
|
3757
|
+
observer = new PerformanceObserver(measure(handle));
|
|
3758
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver/observe
|
|
3759
|
+
// "buffered" flag indicates whether buffered entries should be queued into the observer's buffer.
|
|
3760
|
+
// It must only be used only with the "type" option, and cannot be used with entryTypes.
|
|
3761
|
+
// This is why we need to individually "observe" each supported type
|
|
3762
|
+
for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
|
|
3763
|
+
var x = types_1[_i];
|
|
3764
|
+
if (PerformanceObserver.supportedEntryTypes.indexOf(x) >= 0) {
|
|
3765
|
+
// Initialize CLS with a value of zero. It's possible (and recommended) for sites to not have any cumulative layout shift.
|
|
3766
|
+
// In those cases, we want to still initialize the metric in Clarity
|
|
3767
|
+
if (x === "layout-shift" /* Constant.CLS */) {
|
|
3768
|
+
sum(9 /* Metric.CumulativeLayoutShift */, 0);
|
|
3769
|
+
}
|
|
3770
|
+
observer.observe({ type: x, buffered: true });
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
catch (_a) {
|
|
3775
|
+
log$1(3 /* Code.PerformanceObserver */, 1 /* Severity.Warning */);
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
observe.dn = 26 /* FunctionNames.ObserverObserve */;
|
|
3779
|
+
function handle(entries) {
|
|
3780
|
+
process(entries.getEntries());
|
|
3781
|
+
}
|
|
3782
|
+
handle.dn = 27 /* FunctionNames.ObserverHandle */;
|
|
3783
|
+
function process(entries) {
|
|
3784
|
+
var visible = "visibilityState" in document ? document.visibilityState === "visible" : true;
|
|
3785
|
+
for (var i = 0; i < entries.length; i++) {
|
|
3786
|
+
var entry = entries[i];
|
|
3787
|
+
switch (entry.entryType) {
|
|
3788
|
+
case "navigation" /* Constant.Navigation */:
|
|
3789
|
+
compute(entry);
|
|
3790
|
+
break;
|
|
3791
|
+
case "resource" /* Constant.Resource */:
|
|
3792
|
+
var name_1 = entry.name;
|
|
3793
|
+
log(4 /* Dimension.NetworkHosts */, host(name_1));
|
|
3794
|
+
if (name_1 === config$2.upload || name_1 === config$2.fallback) {
|
|
3795
|
+
max(28 /* Metric.UploadTime */, entry.duration);
|
|
3796
|
+
}
|
|
3797
|
+
break;
|
|
3798
|
+
case "longtask" /* Constant.LongTask */:
|
|
3799
|
+
count$1(7 /* Metric.LongTaskCount */);
|
|
3800
|
+
break;
|
|
3801
|
+
case "first-input" /* Constant.FID */:
|
|
3802
|
+
if (visible) {
|
|
3803
|
+
max(10 /* Metric.FirstInputDelay */, entry["processingStart"] - entry.startTime);
|
|
3804
|
+
}
|
|
3805
|
+
break;
|
|
3806
|
+
case "event" /* Constant.PerformanceEventTiming */:
|
|
3807
|
+
if (visible && 'PerformanceEventTiming' in window && 'interactionId' in PerformanceEventTiming.prototype) {
|
|
3808
|
+
processInteractionEntry(entry);
|
|
3809
|
+
// Logging it as dimension because we're always looking for the last value.
|
|
3810
|
+
log(37 /* Dimension.InteractionNextPaint */, estimateP98LongestInteraction().toString());
|
|
3811
|
+
}
|
|
3812
|
+
break;
|
|
3813
|
+
case "layout-shift" /* Constant.CLS */:
|
|
3814
|
+
// Scale the value to avoid sending back floating point number
|
|
3815
|
+
if (visible && !entry["hadRecentInput"]) {
|
|
3816
|
+
sum(9 /* Metric.CumulativeLayoutShift */, entry["value"] * 1000);
|
|
3817
|
+
}
|
|
3818
|
+
break;
|
|
3819
|
+
case "largest-contentful-paint" /* Constant.LCP */:
|
|
3820
|
+
if (visible) {
|
|
3821
|
+
max(8 /* Metric.LargestPaint */, entry.startTime);
|
|
3822
|
+
}
|
|
3823
|
+
break;
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
function host(url) {
|
|
3828
|
+
var a = document.createElement("a");
|
|
3829
|
+
a.href = url;
|
|
3830
|
+
return a.host;
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
function start$1() {
|
|
3834
|
+
reset();
|
|
3835
|
+
start$2();
|
|
3836
|
+
}
|
|
3837
|
+
start$1.dn = 25 /* FunctionNames.PerformanceStart */;
|
|
298
3838
|
|
|
299
3839
|
var helper = { hash: hash, selector: selector, get: get$2, getNode: getNode, lookup: lookup };
|
|
300
3840
|
|
|
@@ -1137,9 +4677,9 @@ var LayoutHelper = /** @class */ (function () {
|
|
|
1137
4677
|
break;
|
|
1138
4678
|
}
|
|
1139
4679
|
};
|
|
1140
|
-
this.dom = function (event, useproxy) { return __awaiter(_this, void 0, void 0, function () {
|
|
4680
|
+
this.dom = function (event, useproxy) { return __awaiter$1(_this, void 0, void 0, function () {
|
|
1141
4681
|
var doc;
|
|
1142
|
-
return __generator(this, function (_a) {
|
|
4682
|
+
return __generator$1(this, function (_a) {
|
|
1143
4683
|
switch (_a.label) {
|
|
1144
4684
|
case 0:
|
|
1145
4685
|
if (!event) return [3 /*break*/, 2];
|
|
@@ -1617,8 +5157,8 @@ var Visualizer = /** @class */ (function () {
|
|
|
1617
5157
|
this._state = null;
|
|
1618
5158
|
this.renderTime = 0;
|
|
1619
5159
|
this.hashFoundTime = -1;
|
|
1620
|
-
this.dom = function (event) { return __awaiter(_this, void 0, void 0, function () {
|
|
1621
|
-
return __generator(this, function (_a) {
|
|
5160
|
+
this.dom = function (event) { return __awaiter$1(_this, void 0, void 0, function () {
|
|
5161
|
+
return __generator$1(this, function (_a) {
|
|
1622
5162
|
switch (_a.label) {
|
|
1623
5163
|
case 0: return [4 /*yield*/, this.layout.dom(event)];
|
|
1624
5164
|
case 1:
|
|
@@ -1656,9 +5196,9 @@ var Visualizer = /** @class */ (function () {
|
|
|
1656
5196
|
this.html = function (decoded, target, hash, useproxy, logerror, shortCircuitStrategy) {
|
|
1657
5197
|
if (hash === void 0) { hash = null; }
|
|
1658
5198
|
if (shortCircuitStrategy === void 0) { shortCircuitStrategy = 0 /* ShortCircuitStrategy.None */; }
|
|
1659
|
-
return __awaiter(_this, void 0, void 0, function () {
|
|
5199
|
+
return __awaiter$1(_this, void 0, void 0, function () {
|
|
1660
5200
|
var merged, entry, _a, domEvent, e_1;
|
|
1661
|
-
return __generator(this, function (_b) {
|
|
5201
|
+
return __generator$1(this, function (_b) {
|
|
1662
5202
|
switch (_b.label) {
|
|
1663
5203
|
case 0:
|
|
1664
5204
|
if (!(decoded && decoded.length > 0 && target)) return [3 /*break*/, 10];
|
|
@@ -1766,8 +5306,8 @@ var Visualizer = /** @class */ (function () {
|
|
|
1766
5306
|
merged.events = merged.events.sort(_this.sortEvents);
|
|
1767
5307
|
return merged;
|
|
1768
5308
|
};
|
|
1769
|
-
this.setup = function (target, options) { return __awaiter(_this, void 0, void 0, function () {
|
|
1770
|
-
return __generator(this, function (_a) {
|
|
5309
|
+
this.setup = function (target, options) { return __awaiter$1(_this, void 0, void 0, function () {
|
|
5310
|
+
return __generator$1(this, function (_a) {
|
|
1771
5311
|
switch (_a.label) {
|
|
1772
5312
|
case 0:
|
|
1773
5313
|
this.reset();
|
|
@@ -1791,9 +5331,9 @@ var Visualizer = /** @class */ (function () {
|
|
|
1791
5331
|
}
|
|
1792
5332
|
});
|
|
1793
5333
|
}); };
|
|
1794
|
-
this.render = function (events) { return __awaiter(_this, void 0, void 0, function () {
|
|
5334
|
+
this.render = function (events) { return __awaiter$1(_this, void 0, void 0, function () {
|
|
1795
5335
|
var time, _i, events_1, entry, _a;
|
|
1796
|
-
return __generator(this, function (_b) {
|
|
5336
|
+
return __generator$1(this, function (_b) {
|
|
1797
5337
|
switch (_b.label) {
|
|
1798
5338
|
case 0:
|
|
1799
5339
|
if (this.state === null) {
|