@usermaven/sdk-js 1.0.7 → 1.1.0
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/README.md +1 -2
- package/dist/npm/usermaven.cjs.js +569 -1802
- package/dist/npm/usermaven.d.ts +72 -28
- package/dist/npm/usermaven.es.js +569 -1802
- package/dist/web/lib.js +1 -1
- package/package.json +1 -1
package/dist/npm/usermaven.es.js
CHANGED
|
@@ -170,25 +170,24 @@ function createLogger(logLevel) {
|
|
|
170
170
|
* Checks if global variable 'window' is available. If it's available,
|
|
171
171
|
* code runs in browser environment
|
|
172
172
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
function isWindowAvailable(warnMsg) {
|
|
174
|
+
if (warnMsg === void 0) { warnMsg = undefined; }
|
|
175
|
+
var windowAvailable = !!globalThis.window;
|
|
176
|
+
if (!windowAvailable && warnMsg) {
|
|
177
|
+
getLogger().warn(warnMsg);
|
|
178
|
+
}
|
|
179
|
+
return windowAvailable;
|
|
180
180
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
181
|
/**
|
|
184
182
|
* @param msg
|
|
185
183
|
* @return {Window}
|
|
186
184
|
*/
|
|
187
|
-
function requireWindow(msg
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
185
|
+
function requireWindow(msg) {
|
|
186
|
+
if (msg === void 0) { msg = undefined; }
|
|
187
|
+
if (!isWindowAvailable()) {
|
|
188
|
+
throw new Error(msg || "window' is not available. Seems like this code runs outside browser environment. It shouldn't happen");
|
|
189
|
+
}
|
|
190
|
+
return window;
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
function serializeCookie(name, val, opt) {
|
|
@@ -411,1500 +410,291 @@ var getHostWithProtocol = function (host) {
|
|
|
411
410
|
}
|
|
412
411
|
};
|
|
413
412
|
|
|
414
|
-
var
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
}
|
|
413
|
+
var MemoryQueue = /** @class */ (function () {
|
|
414
|
+
function MemoryQueue() {
|
|
415
|
+
this.queue = [];
|
|
416
|
+
}
|
|
417
|
+
MemoryQueue.prototype.flush = function () {
|
|
418
|
+
var queue = this.queue;
|
|
419
|
+
this.queue = [];
|
|
420
|
+
return queue;
|
|
421
|
+
};
|
|
422
|
+
MemoryQueue.prototype.push = function () {
|
|
423
|
+
var _a;
|
|
424
|
+
var values = [];
|
|
425
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
426
|
+
values[_i] = arguments[_i];
|
|
427
|
+
}
|
|
428
|
+
(_a = this.queue).push.apply(_a, values);
|
|
429
|
+
};
|
|
430
|
+
return MemoryQueue;
|
|
431
|
+
}());
|
|
432
|
+
var LocalStorageQueue = /** @class */ (function () {
|
|
433
|
+
function LocalStorageQueue(key) {
|
|
434
|
+
this.key = key;
|
|
435
|
+
}
|
|
436
|
+
LocalStorageQueue.prototype.flush = function () {
|
|
437
|
+
var queue = this.get();
|
|
438
|
+
if (queue.length) {
|
|
439
|
+
this.set([]);
|
|
440
|
+
}
|
|
441
|
+
return queue;
|
|
442
|
+
};
|
|
443
|
+
LocalStorageQueue.prototype.push = function () {
|
|
444
|
+
var values = [];
|
|
445
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
446
|
+
values[_i] = arguments[_i];
|
|
447
|
+
}
|
|
448
|
+
var queue = this.get();
|
|
449
|
+
queue.push.apply(queue, values);
|
|
450
|
+
this.set(queue);
|
|
451
|
+
};
|
|
452
|
+
LocalStorageQueue.prototype.set = function (queue) {
|
|
453
|
+
localStorage.setItem(this.key, JSON.stringify(queue));
|
|
454
|
+
};
|
|
455
|
+
LocalStorageQueue.prototype.get = function () {
|
|
456
|
+
var data = localStorage.getItem(this.key);
|
|
457
|
+
if (data !== null && data !== "") {
|
|
458
|
+
return JSON.parse(data);
|
|
459
|
+
}
|
|
460
|
+
return [];
|
|
461
|
+
};
|
|
462
|
+
return LocalStorageQueue;
|
|
463
|
+
}());
|
|
449
464
|
|
|
450
|
-
|
|
451
|
-
var
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
465
|
+
var ObjProto = Object.prototype;
|
|
466
|
+
var toString = ObjProto.toString;
|
|
467
|
+
var hasOwnProperty = ObjProto.hasOwnProperty;
|
|
468
|
+
var ArrayProto = Array.prototype;
|
|
469
|
+
var nativeForEach = ArrayProto.forEach, nativeIsArray = Array.isArray, breaker = {};
|
|
470
|
+
var _isArray = nativeIsArray ||
|
|
471
|
+
function (obj) {
|
|
472
|
+
return toString.call(obj) === '[object Array]';
|
|
473
|
+
};
|
|
474
|
+
function _eachArray(obj, iterator, thisArg) {
|
|
475
|
+
if (Array.isArray(obj)) {
|
|
476
|
+
if (nativeForEach && obj.forEach === nativeForEach) {
|
|
477
|
+
obj.forEach(iterator, thisArg);
|
|
478
|
+
}
|
|
479
|
+
else if ('length' in obj && obj.length === +obj.length) {
|
|
480
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
|
481
|
+
if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
468
484
|
}
|
|
469
485
|
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// UNDERSCORE
|
|
486
|
+
}
|
|
487
|
+
}
|
|
474
488
|
// Embed part of the Underscore Library
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
if (nativeBind && func.bind === nativeBind) {
|
|
478
|
-
return nativeBind.apply(func, slice.call(arguments, 1))
|
|
479
|
-
}
|
|
480
|
-
if (!_.isFunction(func)) {
|
|
481
|
-
throw new TypeError()
|
|
482
|
-
}
|
|
483
|
-
args = slice.call(arguments, 2);
|
|
484
|
-
bound = function () {
|
|
485
|
-
if (!(this instanceof bound)) {
|
|
486
|
-
return func.apply(context, args.concat(slice.call(arguments)))
|
|
487
|
-
}
|
|
488
|
-
var ctor = {};
|
|
489
|
-
ctor.prototype = func.prototype;
|
|
490
|
-
var self = new ctor();
|
|
491
|
-
ctor.prototype = null;
|
|
492
|
-
var result = func.apply(self, args.concat(slice.call(arguments)));
|
|
493
|
-
if (Object(result) === result) {
|
|
494
|
-
return result
|
|
495
|
-
}
|
|
496
|
-
return self
|
|
497
|
-
};
|
|
498
|
-
return bound
|
|
489
|
+
var _trim = function (str) {
|
|
490
|
+
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
|
499
491
|
};
|
|
500
|
-
|
|
501
|
-
_.bind_instance_methods = function (obj) {
|
|
492
|
+
var _bind_instance_methods = function (obj) {
|
|
502
493
|
for (var func in obj) {
|
|
503
494
|
if (typeof obj[func] === 'function') {
|
|
504
|
-
obj[func] =
|
|
495
|
+
obj[func] = obj[func].bind(obj);
|
|
505
496
|
}
|
|
506
497
|
}
|
|
507
498
|
};
|
|
508
|
-
|
|
509
499
|
/**
|
|
510
500
|
* @param {*=} obj
|
|
511
501
|
* @param {function(...*)=} iterator
|
|
512
|
-
* @param {Object=}
|
|
502
|
+
* @param {Object=} thisArg
|
|
513
503
|
*/
|
|
514
|
-
|
|
504
|
+
function _each(obj, iterator, thisArg) {
|
|
515
505
|
if (obj === null || obj === undefined) {
|
|
516
|
-
return
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (nativeForEach && Array.isArray(obj) && obj.forEach === nativeForEach) {
|
|
509
|
+
obj.forEach(iterator, thisArg);
|
|
517
510
|
}
|
|
518
|
-
if (
|
|
519
|
-
obj.forEach(iterator, context);
|
|
520
|
-
} else if (obj.length === +obj.length) {
|
|
511
|
+
else if ('length' in obj && obj.length === +obj.length) {
|
|
521
512
|
for (var i = 0, l = obj.length; i < l; i++) {
|
|
522
|
-
if (i in obj && iterator.call(
|
|
523
|
-
return
|
|
513
|
+
if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {
|
|
514
|
+
return;
|
|
524
515
|
}
|
|
525
516
|
}
|
|
526
|
-
}
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
527
519
|
for (var key in obj) {
|
|
528
520
|
if (hasOwnProperty.call(obj, key)) {
|
|
529
|
-
if (iterator.call(
|
|
530
|
-
return
|
|
521
|
+
if (iterator.call(thisArg, obj[key], key) === breaker) {
|
|
522
|
+
return;
|
|
531
523
|
}
|
|
532
524
|
}
|
|
533
525
|
}
|
|
534
526
|
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
527
|
+
}
|
|
528
|
+
var _extend = function (obj) {
|
|
529
|
+
var args = [];
|
|
530
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
531
|
+
args[_i - 1] = arguments[_i];
|
|
532
|
+
}
|
|
533
|
+
_eachArray(args, function (source) {
|
|
539
534
|
for (var prop in source) {
|
|
540
535
|
if (source[prop] !== void 0) {
|
|
541
536
|
obj[prop] = source[prop];
|
|
542
537
|
}
|
|
543
538
|
}
|
|
544
539
|
});
|
|
545
|
-
return obj
|
|
540
|
+
return obj;
|
|
546
541
|
};
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
function (obj) {
|
|
551
|
-
return toString.call(obj) === '[object Array]'
|
|
552
|
-
};
|
|
553
|
-
|
|
542
|
+
function _includes(str, needle) {
|
|
543
|
+
return str.indexOf(needle) !== -1;
|
|
544
|
+
}
|
|
554
545
|
// from a comment on http://dbj.org/dbj/?p=286
|
|
555
546
|
// fails on only one very rare and deliberate custom object:
|
|
556
|
-
//
|
|
557
|
-
|
|
558
|
-
try {
|
|
559
|
-
return /^\s*\bfunction\b/.test(f)
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
};
|
|
564
|
-
|
|
565
|
-
_.include = function (obj, target) {
|
|
566
|
-
var found = false;
|
|
567
|
-
if (obj === null) {
|
|
568
|
-
return found
|
|
569
|
-
}
|
|
570
|
-
if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
|
|
571
|
-
return obj.indexOf(target) != -1
|
|
572
|
-
}
|
|
573
|
-
_.each(obj, function (value) {
|
|
574
|
-
if (found || (found = value === target)) {
|
|
575
|
-
return breaker
|
|
576
|
-
}
|
|
577
|
-
});
|
|
578
|
-
return found
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
_.includes = function (str, needle) {
|
|
582
|
-
return str.indexOf(needle) !== -1
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
// Underscore Addons
|
|
586
|
-
_.isObject = function (obj) {
|
|
587
|
-
return obj === Object(obj) && !_.isArray(obj)
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
_.isEmptyObject = function (obj) {
|
|
591
|
-
if (_.isObject(obj)) {
|
|
592
|
-
for (var key in obj) {
|
|
593
|
-
if (hasOwnProperty.call(obj, key)) {
|
|
594
|
-
return false
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
return true
|
|
598
|
-
}
|
|
599
|
-
return false
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
_.isUndefined = function (obj) {
|
|
603
|
-
return obj === void 0
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
_.isString = function (obj) {
|
|
607
|
-
return toString.call(obj) == '[object String]'
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
_.isDate = function (obj) {
|
|
611
|
-
return toString.call(obj) == '[object Date]'
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
_.isNumber = function (obj) {
|
|
615
|
-
return toString.call(obj) == '[object Number]'
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
_.encodeDates = function (obj) {
|
|
619
|
-
_.each(obj, function (v, k) {
|
|
620
|
-
if (_.isDate(v)) {
|
|
621
|
-
obj[k] = _.formatDate(v);
|
|
622
|
-
} else if (_.isObject(v)) {
|
|
623
|
-
obj[k] = _.encodeDates(v); // recurse
|
|
624
|
-
}
|
|
625
|
-
});
|
|
626
|
-
return obj
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
_.timestamp = function () {
|
|
630
|
-
Date.now =
|
|
631
|
-
Date.now ||
|
|
632
|
-
function () {
|
|
633
|
-
return +new Date()
|
|
634
|
-
};
|
|
635
|
-
return Date.now()
|
|
636
|
-
};
|
|
637
|
-
|
|
638
|
-
_.formatDate = function (d) {
|
|
639
|
-
// YYYY-MM-DDTHH:MM:SS in UTC
|
|
640
|
-
function pad(n) {
|
|
641
|
-
return n < 10 ? '0' + n : n
|
|
642
|
-
}
|
|
643
|
-
return (
|
|
644
|
-
d.getUTCFullYear() +
|
|
645
|
-
'-' +
|
|
646
|
-
pad(d.getUTCMonth() + 1) +
|
|
647
|
-
'-' +
|
|
648
|
-
pad(d.getUTCDate()) +
|
|
649
|
-
'T' +
|
|
650
|
-
pad(d.getUTCHours()) +
|
|
651
|
-
':' +
|
|
652
|
-
pad(d.getUTCMinutes()) +
|
|
653
|
-
':' +
|
|
654
|
-
pad(d.getUTCSeconds())
|
|
655
|
-
)
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
_.safewrap = function (f) {
|
|
659
|
-
return function () {
|
|
660
|
-
try {
|
|
661
|
-
return f.apply(this, arguments)
|
|
662
|
-
} catch (e) {
|
|
663
|
-
console$1.critical('Implementation error. Please turn on debug and contact support@usermaven.com.');
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
|
|
668
|
-
_.safewrap_class = function (klass, functions) {
|
|
669
|
-
for (var i = 0; i < functions.length; i++) {
|
|
670
|
-
klass.prototype[functions[i]] = _.safewrap(klass.prototype[functions[i]]);
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
|
|
674
|
-
_.safewrap_instance_methods = function (obj) {
|
|
675
|
-
for (var func in obj) {
|
|
676
|
-
if (typeof obj[func] === 'function') {
|
|
677
|
-
obj[func] = _.safewrap(obj[func]);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
};
|
|
681
|
-
|
|
682
|
-
_.strip_empty_properties = function (p) {
|
|
683
|
-
var ret = {};
|
|
684
|
-
_.each(p, function (v, k) {
|
|
685
|
-
if (_.isString(v) && v.length > 0) {
|
|
686
|
-
ret[k] = v;
|
|
687
|
-
}
|
|
688
|
-
});
|
|
689
|
-
return ret
|
|
690
|
-
};
|
|
691
|
-
|
|
692
|
-
// Deep copies an object.
|
|
693
|
-
// It handles cycles by replacing all references to them with `undefined`
|
|
694
|
-
// Also supports customizing native values
|
|
695
|
-
const COPY_IN_PROGRESS_ATTRIBUTE =
|
|
696
|
-
typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
|
|
697
|
-
|
|
698
|
-
function deepCircularCopy(value, customizer) {
|
|
699
|
-
if (value !== Object(value)) return customizer ? customizer(value) : value // primitive value
|
|
700
|
-
|
|
701
|
-
if (value[COPY_IN_PROGRESS_ATTRIBUTE]) return undefined
|
|
702
|
-
|
|
703
|
-
value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
|
|
704
|
-
let result;
|
|
705
|
-
|
|
706
|
-
if (_.isArray(value)) {
|
|
707
|
-
result = [];
|
|
708
|
-
_.each(value, (it) => {
|
|
709
|
-
result.push(deepCircularCopy(it, customizer));
|
|
710
|
-
});
|
|
711
|
-
} else {
|
|
712
|
-
result = {};
|
|
713
|
-
_.each(value, (val, key) => {
|
|
714
|
-
if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
|
|
715
|
-
result[key] = deepCircularCopy(val, customizer);
|
|
716
|
-
}
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
delete value[COPY_IN_PROGRESS_ATTRIBUTE];
|
|
720
|
-
return result
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
_.copyAndTruncateStrings = (object, maxStringLength) =>
|
|
724
|
-
deepCircularCopy(
|
|
725
|
-
object,
|
|
726
|
-
(value) => {
|
|
727
|
-
if (typeof value === 'string' && maxStringLength !== null) {
|
|
728
|
-
value = value.slice(0, maxStringLength);
|
|
729
|
-
}
|
|
730
|
-
return value
|
|
731
|
-
});
|
|
732
|
-
|
|
733
|
-
_.base64Encode = function (data) {
|
|
734
|
-
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
735
|
-
var o1,
|
|
736
|
-
o2,
|
|
737
|
-
o3,
|
|
738
|
-
h1,
|
|
739
|
-
h2,
|
|
740
|
-
h3,
|
|
741
|
-
h4,
|
|
742
|
-
bits,
|
|
743
|
-
i = 0,
|
|
744
|
-
ac = 0,
|
|
745
|
-
enc = '',
|
|
746
|
-
tmp_arr = [];
|
|
747
|
-
|
|
748
|
-
if (!data) {
|
|
749
|
-
return data
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
data = _.utf8Encode(data);
|
|
753
|
-
|
|
754
|
-
do {
|
|
755
|
-
// pack three octets into four hexets
|
|
756
|
-
o1 = data.charCodeAt(i++);
|
|
757
|
-
o2 = data.charCodeAt(i++);
|
|
758
|
-
o3 = data.charCodeAt(i++);
|
|
759
|
-
|
|
760
|
-
bits = (o1 << 16) | (o2 << 8) | o3;
|
|
761
|
-
|
|
762
|
-
h1 = (bits >> 18) & 0x3f;
|
|
763
|
-
h2 = (bits >> 12) & 0x3f;
|
|
764
|
-
h3 = (bits >> 6) & 0x3f;
|
|
765
|
-
h4 = bits & 0x3f;
|
|
766
|
-
|
|
767
|
-
// use hexets to index into b64, and append result to encoded string
|
|
768
|
-
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
|
|
769
|
-
} while (i < data.length)
|
|
770
|
-
|
|
771
|
-
enc = tmp_arr.join('');
|
|
772
|
-
|
|
773
|
-
switch (data.length % 3) {
|
|
774
|
-
case 1:
|
|
775
|
-
enc = enc.slice(0, -2) + '==';
|
|
776
|
-
break
|
|
777
|
-
case 2:
|
|
778
|
-
enc = enc.slice(0, -1) + '=';
|
|
779
|
-
break
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
return enc
|
|
783
|
-
};
|
|
784
|
-
|
|
785
|
-
_.utf8Encode = function (string) {
|
|
786
|
-
string = (string + '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
787
|
-
|
|
788
|
-
var utftext = '',
|
|
789
|
-
start,
|
|
790
|
-
end;
|
|
791
|
-
var stringl = 0,
|
|
792
|
-
n;
|
|
793
|
-
|
|
794
|
-
start = end = 0;
|
|
795
|
-
stringl = string.length;
|
|
796
|
-
|
|
797
|
-
for (n = 0; n < stringl; n++) {
|
|
798
|
-
var c1 = string.charCodeAt(n);
|
|
799
|
-
var enc = null;
|
|
800
|
-
|
|
801
|
-
if (c1 < 128) {
|
|
802
|
-
end++;
|
|
803
|
-
} else if (c1 > 127 && c1 < 2048) {
|
|
804
|
-
enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128);
|
|
805
|
-
} else {
|
|
806
|
-
enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
|
|
807
|
-
}
|
|
808
|
-
if (enc !== null) {
|
|
809
|
-
if (end > start) {
|
|
810
|
-
utftext += string.substring(start, end);
|
|
811
|
-
}
|
|
812
|
-
utftext += enc;
|
|
813
|
-
start = end = n + 1;
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
if (end > start) {
|
|
818
|
-
utftext += string.substring(start, string.length);
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
return utftext
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
_.UUID = (function () {
|
|
825
|
-
// Time/ticks information
|
|
826
|
-
// 1*new Date() is a cross browser version of Date.now()
|
|
827
|
-
var T = function () {
|
|
828
|
-
var d = 1 * new Date(),
|
|
829
|
-
i = 0;
|
|
830
|
-
|
|
831
|
-
// this while loop figures how many browser ticks go by
|
|
832
|
-
// before 1*new Date() returns a new number, ie the amount
|
|
833
|
-
// of ticks that go by per millisecond
|
|
834
|
-
while (d == 1 * new Date()) {
|
|
835
|
-
i++;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
return d.toString(16) + i.toString(16)
|
|
839
|
-
};
|
|
840
|
-
|
|
841
|
-
// Math.Random entropy
|
|
842
|
-
var R = function () {
|
|
843
|
-
return Math.random().toString(16).replace('.', '')
|
|
844
|
-
};
|
|
845
|
-
|
|
846
|
-
// User agent entropy
|
|
847
|
-
// This function takes the user agent string, and then xors
|
|
848
|
-
// together each sequence of 8 bytes. This produces a final
|
|
849
|
-
// sequence of 8 bytes which it returns as hex.
|
|
850
|
-
var UA = function () {
|
|
851
|
-
var ua = userAgent,
|
|
852
|
-
i,
|
|
853
|
-
ch,
|
|
854
|
-
buffer = [],
|
|
855
|
-
ret = 0;
|
|
856
|
-
|
|
857
|
-
function xor(result, byte_array) {
|
|
858
|
-
var j,
|
|
859
|
-
tmp = 0;
|
|
860
|
-
for (j = 0; j < byte_array.length; j++) {
|
|
861
|
-
tmp |= buffer[j] << (j * 8);
|
|
862
|
-
}
|
|
863
|
-
return result ^ tmp
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
for (i = 0; i < ua.length; i++) {
|
|
867
|
-
ch = ua.charCodeAt(i);
|
|
868
|
-
buffer.unshift(ch & 0xff);
|
|
869
|
-
if (buffer.length >= 4) {
|
|
870
|
-
ret = xor(ret, buffer);
|
|
871
|
-
buffer = [];
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
if (buffer.length > 0) {
|
|
876
|
-
ret = xor(ret, buffer);
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
return ret.toString(16)
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
return function () {
|
|
883
|
-
var se = (window.screen.height * window.screen.width).toString(16);
|
|
884
|
-
return T() + '-' + R() + '-' + UA() + '-' + se + '-' + T()
|
|
885
|
-
}
|
|
886
|
-
})();
|
|
887
|
-
|
|
888
|
-
// _.isBlockedUA()
|
|
889
|
-
// This is to block various web spiders from executing our JS and
|
|
890
|
-
// sending false captureing data
|
|
891
|
-
_.isBlockedUA = function (ua) {
|
|
892
|
-
if (/(google web preview|baiduspider|yandexbot|bingbot|googlebot|yahoo! slurp)/i.test(ua)) {
|
|
893
|
-
return true
|
|
894
|
-
}
|
|
895
|
-
return false
|
|
896
|
-
};
|
|
897
|
-
|
|
898
|
-
/**
|
|
899
|
-
* @param {Object=} formdata
|
|
900
|
-
* @param {string=} arg_separator
|
|
901
|
-
*/
|
|
902
|
-
_.HTTPBuildQuery = function (formdata, arg_separator) {
|
|
903
|
-
var use_val,
|
|
904
|
-
use_key,
|
|
905
|
-
tph_arr = [];
|
|
906
|
-
|
|
907
|
-
if (_.isUndefined(arg_separator)) {
|
|
908
|
-
arg_separator = '&';
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
_.each(formdata, function (val, key) {
|
|
912
|
-
use_val = encodeURIComponent(val.toString());
|
|
913
|
-
use_key = encodeURIComponent(key);
|
|
914
|
-
tph_arr[tph_arr.length] = use_key + '=' + use_val;
|
|
915
|
-
});
|
|
916
|
-
|
|
917
|
-
return tph_arr.join(arg_separator)
|
|
918
|
-
};
|
|
919
|
-
|
|
920
|
-
_.getQueryParam = function (url, param) {
|
|
921
|
-
// Expects a raw URL
|
|
922
|
-
|
|
923
|
-
param = param.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
|
|
924
|
-
var regexS = '[\\?&]' + param + '=([^&#]*)',
|
|
925
|
-
regex = new RegExp(regexS),
|
|
926
|
-
results = regex.exec(url);
|
|
927
|
-
if (results === null || (results && typeof results[1] !== 'string' && results[1].length)) {
|
|
928
|
-
return ''
|
|
929
|
-
} else {
|
|
930
|
-
var result = results[1];
|
|
931
|
-
try {
|
|
932
|
-
result = decodeURIComponent(result);
|
|
933
|
-
} catch (err) {
|
|
934
|
-
}
|
|
935
|
-
return result.replace(/\+/g, ' ')
|
|
936
|
-
}
|
|
937
|
-
};
|
|
938
|
-
|
|
939
|
-
_.getHashParam = function (hash, param) {
|
|
940
|
-
var matches = hash.match(new RegExp(param + '=([^&]*)'));
|
|
941
|
-
return matches ? matches[1] : null
|
|
942
|
-
};
|
|
943
|
-
|
|
944
|
-
_.register_event = (function () {
|
|
945
|
-
// written by Dean Edwards, 2005
|
|
946
|
-
// with input from Tino Zijdel - crisp@xs4all.nl
|
|
947
|
-
// with input from Carl Sverre - mail@carlsverre.com
|
|
948
|
-
// http://dean.edwards.name/weblog/2005/10/add-event/
|
|
949
|
-
// https://gist.github.com/1930440
|
|
950
|
-
|
|
951
|
-
/**
|
|
952
|
-
* @param {Object} element
|
|
953
|
-
* @param {string} type
|
|
954
|
-
* @param {function(...*)} handler
|
|
955
|
-
* @param {boolean=} oldSchool
|
|
956
|
-
* @param {boolean=} useCapture
|
|
957
|
-
*/
|
|
958
|
-
var register_event = function (element, type, handler, oldSchool, useCapture) {
|
|
959
|
-
if (!element) {
|
|
960
|
-
return
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
if (element.addEventListener && !oldSchool) {
|
|
964
|
-
element.addEventListener(type, handler, !!useCapture);
|
|
965
|
-
} else {
|
|
966
|
-
var ontype = 'on' + type;
|
|
967
|
-
var old_handler = element[ontype]; // can be undefined
|
|
968
|
-
element[ontype] = makeHandler(element, handler, old_handler);
|
|
969
|
-
}
|
|
970
|
-
};
|
|
971
|
-
|
|
972
|
-
function makeHandler(element, new_handler, old_handlers) {
|
|
973
|
-
var handler = function (event) {
|
|
974
|
-
event = event || fixEvent(window.event);
|
|
975
|
-
|
|
976
|
-
// this basically happens in firefox whenever another script
|
|
977
|
-
// overwrites the onload callback and doesn't pass the event
|
|
978
|
-
// object to previously defined callbacks. All the browsers
|
|
979
|
-
// that don't define window.event implement addEventListener
|
|
980
|
-
// so the dom_loaded handler will still be fired as usual.
|
|
981
|
-
if (!event) {
|
|
982
|
-
return undefined
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
var ret = true;
|
|
986
|
-
var old_result, new_result;
|
|
987
|
-
|
|
988
|
-
if (_.isFunction(old_handlers)) {
|
|
989
|
-
old_result = old_handlers(event);
|
|
990
|
-
}
|
|
991
|
-
new_result = new_handler.call(element, event);
|
|
992
|
-
|
|
993
|
-
if (false === old_result || false === new_result) {
|
|
994
|
-
ret = false;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
return ret
|
|
998
|
-
};
|
|
999
|
-
|
|
1000
|
-
return handler
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
function fixEvent(event) {
|
|
1004
|
-
if (event) {
|
|
1005
|
-
event.preventDefault = fixEvent.preventDefault;
|
|
1006
|
-
event.stopPropagation = fixEvent.stopPropagation;
|
|
1007
|
-
}
|
|
1008
|
-
return event
|
|
1009
|
-
}
|
|
1010
|
-
fixEvent.preventDefault = function () {
|
|
1011
|
-
this.returnValue = false;
|
|
1012
|
-
};
|
|
1013
|
-
fixEvent.stopPropagation = function () {
|
|
1014
|
-
this.cancelBubble = true;
|
|
1015
|
-
};
|
|
1016
|
-
|
|
1017
|
-
return register_event
|
|
1018
|
-
})();
|
|
1019
|
-
|
|
1020
|
-
_.info = {
|
|
1021
|
-
campaignParams: function () {
|
|
1022
|
-
var campaign_keywords = 'utm_source utm_medium utm_campaign utm_content utm_term gclid'.split(' '),
|
|
1023
|
-
kw = '',
|
|
1024
|
-
params = {};
|
|
1025
|
-
_.each(campaign_keywords, function (kwkey) {
|
|
1026
|
-
kw = _.getQueryParam(document$1.URL, kwkey);
|
|
1027
|
-
if (kw.length) {
|
|
1028
|
-
params[kwkey] = kw;
|
|
1029
|
-
}
|
|
1030
|
-
});
|
|
1031
|
-
|
|
1032
|
-
return params
|
|
1033
|
-
},
|
|
1034
|
-
|
|
1035
|
-
searchEngine: function (referrer) {
|
|
1036
|
-
if (referrer.search('https?://(.*)google.([^/?]*)') === 0) {
|
|
1037
|
-
return 'google'
|
|
1038
|
-
} else if (referrer.search('https?://(.*)bing.com') === 0) {
|
|
1039
|
-
return 'bing'
|
|
1040
|
-
} else if (referrer.search('https?://(.*)yahoo.com') === 0) {
|
|
1041
|
-
return 'yahoo'
|
|
1042
|
-
} else if (referrer.search('https?://(.*)duckduckgo.com') === 0) {
|
|
1043
|
-
return 'duckduckgo'
|
|
1044
|
-
} else {
|
|
1045
|
-
return null
|
|
1046
|
-
}
|
|
1047
|
-
},
|
|
1048
|
-
|
|
1049
|
-
searchInfo: function (referrer) {
|
|
1050
|
-
var search = _.info.searchEngine(referrer),
|
|
1051
|
-
param = search != 'yahoo' ? 'q' : 'p',
|
|
1052
|
-
ret = {};
|
|
1053
|
-
|
|
1054
|
-
if (search !== null) {
|
|
1055
|
-
ret['$search_engine'] = search;
|
|
1056
|
-
|
|
1057
|
-
var keyword = _.getQueryParam(referrer, param);
|
|
1058
|
-
if (keyword.length) {
|
|
1059
|
-
ret['um_keyword'] = keyword;
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
return ret
|
|
1064
|
-
},
|
|
1065
|
-
|
|
1066
|
-
/**
|
|
1067
|
-
* This function detects which browser is running this script.
|
|
1068
|
-
* The order of the checks are important since many user agents
|
|
1069
|
-
* include key words used in later checks.
|
|
1070
|
-
*/
|
|
1071
|
-
browser: function (user_agent, vendor, opera) {
|
|
1072
|
-
vendor = vendor || ''; // vendor is undefined for at least IE9
|
|
1073
|
-
if (opera || _.includes(user_agent, ' OPR/')) {
|
|
1074
|
-
if (_.includes(user_agent, 'Mini')) {
|
|
1075
|
-
return 'Opera Mini'
|
|
1076
|
-
}
|
|
1077
|
-
return 'Opera'
|
|
1078
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) {
|
|
1079
|
-
return 'BlackBerry'
|
|
1080
|
-
} else if (_.includes(user_agent, 'IEMobile') || _.includes(user_agent, 'WPDesktop')) {
|
|
1081
|
-
return 'Internet Explorer Mobile'
|
|
1082
|
-
} else if (_.includes(user_agent, 'SamsungBrowser/')) {
|
|
1083
|
-
// https://developer.samsung.com/internet/user-agent-string-format
|
|
1084
|
-
return 'Samsung Internet'
|
|
1085
|
-
} else if (_.includes(user_agent, 'Edge') || _.includes(user_agent, 'Edg/')) {
|
|
1086
|
-
return 'Microsoft Edge'
|
|
1087
|
-
} else if (_.includes(user_agent, 'FBIOS')) {
|
|
1088
|
-
return 'Facebook Mobile'
|
|
1089
|
-
} else if (_.includes(user_agent, 'Chrome')) {
|
|
1090
|
-
return 'Chrome'
|
|
1091
|
-
} else if (_.includes(user_agent, 'CriOS')) {
|
|
1092
|
-
return 'Chrome iOS'
|
|
1093
|
-
} else if (_.includes(user_agent, 'UCWEB') || _.includes(user_agent, 'UCBrowser')) {
|
|
1094
|
-
return 'UC Browser'
|
|
1095
|
-
} else if (_.includes(user_agent, 'FxiOS')) {
|
|
1096
|
-
return 'Firefox iOS'
|
|
1097
|
-
} else if (_.includes(vendor, 'Apple')) {
|
|
1098
|
-
if (_.includes(user_agent, 'Mobile')) {
|
|
1099
|
-
return 'Mobile Safari'
|
|
1100
|
-
}
|
|
1101
|
-
return 'Safari'
|
|
1102
|
-
} else if (_.includes(user_agent, 'Android')) {
|
|
1103
|
-
return 'Android Mobile'
|
|
1104
|
-
} else if (_.includes(user_agent, 'Konqueror')) {
|
|
1105
|
-
return 'Konqueror'
|
|
1106
|
-
} else if (_.includes(user_agent, 'Firefox')) {
|
|
1107
|
-
return 'Firefox'
|
|
1108
|
-
} else if (_.includes(user_agent, 'MSIE') || _.includes(user_agent, 'Trident/')) {
|
|
1109
|
-
return 'Internet Explorer'
|
|
1110
|
-
} else if (_.includes(user_agent, 'Gecko')) {
|
|
1111
|
-
return 'Mozilla'
|
|
1112
|
-
} else {
|
|
1113
|
-
return ''
|
|
1114
|
-
}
|
|
1115
|
-
},
|
|
1116
|
-
|
|
1117
|
-
/**
|
|
1118
|
-
* This function detects which browser version is running this script,
|
|
1119
|
-
* parsing major and minor version (e.g., 42.1). User agent strings from:
|
|
1120
|
-
* http://www.useragentstring.com/pages/useragentstring.php
|
|
1121
|
-
*/
|
|
1122
|
-
browserVersion: function (userAgent, vendor, opera) {
|
|
1123
|
-
var browser = _.info.browser(userAgent, vendor, opera);
|
|
1124
|
-
var versionRegexs = {
|
|
1125
|
-
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
|
|
1126
|
-
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/,
|
|
1127
|
-
Chrome: /Chrome\/(\d+(\.\d+)?)/,
|
|
1128
|
-
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/,
|
|
1129
|
-
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/,
|
|
1130
|
-
Safari: /Version\/(\d+(\.\d+)?)/,
|
|
1131
|
-
'Mobile Safari': /Version\/(\d+(\.\d+)?)/,
|
|
1132
|
-
Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/,
|
|
1133
|
-
Firefox: /Firefox\/(\d+(\.\d+)?)/,
|
|
1134
|
-
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/,
|
|
1135
|
-
Konqueror: /Konqueror:(\d+(\.\d+)?)/,
|
|
1136
|
-
BlackBerry: /BlackBerry (\d+(\.\d+)?)/,
|
|
1137
|
-
'Android Mobile': /android\s(\d+(\.\d+)?)/,
|
|
1138
|
-
'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
|
|
1139
|
-
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
|
|
1140
|
-
Mozilla: /rv:(\d+(\.\d+)?)/,
|
|
1141
|
-
};
|
|
1142
|
-
var regex = versionRegexs[browser];
|
|
1143
|
-
if (regex === undefined) {
|
|
1144
|
-
return null
|
|
1145
|
-
}
|
|
1146
|
-
var matches = userAgent.match(regex);
|
|
1147
|
-
if (!matches) {
|
|
1148
|
-
return null
|
|
1149
|
-
}
|
|
1150
|
-
return parseFloat(matches[matches.length - 2])
|
|
1151
|
-
},
|
|
1152
|
-
|
|
1153
|
-
os: function () {
|
|
1154
|
-
var a = userAgent;
|
|
1155
|
-
if (/Windows/i.test(a)) {
|
|
1156
|
-
if (/Phone/.test(a) || /WPDesktop/.test(a)) {
|
|
1157
|
-
return 'Windows Phone'
|
|
1158
|
-
}
|
|
1159
|
-
return 'Windows'
|
|
1160
|
-
} else if (/(iPhone|iPad|iPod)/.test(a)) {
|
|
1161
|
-
return 'iOS'
|
|
1162
|
-
} else if (/Android/.test(a)) {
|
|
1163
|
-
return 'Android'
|
|
1164
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) {
|
|
1165
|
-
return 'BlackBerry'
|
|
1166
|
-
} else if (/Mac/i.test(a)) {
|
|
1167
|
-
return 'Mac OS X'
|
|
1168
|
-
} else if (/Linux/.test(a)) {
|
|
1169
|
-
return 'Linux'
|
|
1170
|
-
} else if (/CrOS/.test(a)) {
|
|
1171
|
-
return 'Chrome OS'
|
|
1172
|
-
} else {
|
|
1173
|
-
return ''
|
|
1174
|
-
}
|
|
1175
|
-
},
|
|
1176
|
-
|
|
1177
|
-
device: function (user_agent) {
|
|
1178
|
-
if (/Windows Phone/i.test(user_agent) || /WPDesktop/.test(user_agent)) {
|
|
1179
|
-
return 'Windows Phone'
|
|
1180
|
-
} else if (/iPad/.test(user_agent)) {
|
|
1181
|
-
return 'iPad'
|
|
1182
|
-
} else if (/iPod/.test(user_agent)) {
|
|
1183
|
-
return 'iPod Touch'
|
|
1184
|
-
} else if (/iPhone/.test(user_agent)) {
|
|
1185
|
-
return 'iPhone'
|
|
1186
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) {
|
|
1187
|
-
return 'BlackBerry'
|
|
1188
|
-
} else if (/Android/.test(user_agent) && !/Mobile/.test(user_agent)) {
|
|
1189
|
-
return 'Android Tablet'
|
|
1190
|
-
} else if (/Android/.test(user_agent)) {
|
|
1191
|
-
return 'Android'
|
|
1192
|
-
} else {
|
|
1193
|
-
return ''
|
|
1194
|
-
}
|
|
1195
|
-
},
|
|
1196
|
-
|
|
1197
|
-
deviceType: function (user_agent) {
|
|
1198
|
-
const device = this.device(user_agent);
|
|
1199
|
-
if (device === 'iPad' || device === 'Android Tablet') {
|
|
1200
|
-
return 'Tablet'
|
|
1201
|
-
} else if (device) {
|
|
1202
|
-
return 'Mobile'
|
|
1203
|
-
} else {
|
|
1204
|
-
return 'Desktop'
|
|
1205
|
-
}
|
|
1206
|
-
},
|
|
1207
|
-
|
|
1208
|
-
referringDomain: function (referrer) {
|
|
1209
|
-
var split = referrer.split('/');
|
|
1210
|
-
if (split.length >= 3) {
|
|
1211
|
-
return split[2]
|
|
1212
|
-
}
|
|
1213
|
-
return ''
|
|
1214
|
-
},
|
|
1215
|
-
|
|
1216
|
-
properties: function () {
|
|
1217
|
-
return _.extend(
|
|
1218
|
-
_.strip_empty_properties({
|
|
1219
|
-
$os: _.info.os(),
|
|
1220
|
-
$browser: _.info.browser(userAgent, navigator$1.vendor, window.opera),
|
|
1221
|
-
$device: _.info.device(userAgent),
|
|
1222
|
-
$device_type: _.info.deviceType(userAgent),
|
|
1223
|
-
}),
|
|
1224
|
-
{
|
|
1225
|
-
$current_url: window.location.href,
|
|
1226
|
-
$host: window.location.host,
|
|
1227
|
-
$pathname: window.location.pathname,
|
|
1228
|
-
$browser_version: _.info.browserVersion(userAgent, navigator$1.vendor, window.opera),
|
|
1229
|
-
$screen_height: window.screen.height,
|
|
1230
|
-
$screen_width: window.screen.width,
|
|
1231
|
-
$viewport_height: window.innerHeight,
|
|
1232
|
-
$viewport_width: window.innerWidth,
|
|
1233
|
-
$lib: 'web',
|
|
1234
|
-
$lib_version: Config$1.LIB_VERSION,
|
|
1235
|
-
$insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
|
|
1236
|
-
$time: _.timestamp() / 1000, // epoch time in seconds
|
|
1237
|
-
}
|
|
1238
|
-
)
|
|
1239
|
-
},
|
|
1240
|
-
|
|
1241
|
-
people_properties: function () {
|
|
1242
|
-
return _.extend(
|
|
1243
|
-
_.strip_empty_properties({
|
|
1244
|
-
$os: _.info.os(),
|
|
1245
|
-
$browser: _.info.browser(userAgent, navigator$1.vendor, window.opera),
|
|
1246
|
-
}),
|
|
1247
|
-
{
|
|
1248
|
-
$browser_version: _.info.browserVersion(userAgent, navigator$1.vendor, window.opera),
|
|
1249
|
-
}
|
|
1250
|
-
)
|
|
1251
|
-
},
|
|
1252
|
-
};
|
|
1253
|
-
|
|
1254
|
-
// EXPORTS (for closure compiler)
|
|
1255
|
-
_['isObject'] = _.isObject;
|
|
1256
|
-
_['isBlockedUA'] = _.isBlockedUA;
|
|
1257
|
-
_['isEmptyObject'] = _.isEmptyObject;
|
|
1258
|
-
_['info'] = _.info;
|
|
1259
|
-
_['info']['device'] = _.info.device;
|
|
1260
|
-
_['info']['browser'] = _.info.browser;
|
|
1261
|
-
_['info']['browserVersion'] = _.info.browserVersion;
|
|
1262
|
-
_['info']['properties'] = _.info.properties;
|
|
1263
|
-
|
|
1264
|
-
var DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i;
|
|
1265
|
-
|
|
1266
|
-
// Methods partially borrowed from quirksmode.org/js/cookies.html
|
|
1267
|
-
const cookieStore = {
|
|
1268
|
-
get: function (name) {
|
|
1269
|
-
try {
|
|
1270
|
-
var nameEQ = name + '=';
|
|
1271
|
-
var ca = document.cookie.split(';');
|
|
1272
|
-
for (var i = 0; i < ca.length; i++) {
|
|
1273
|
-
var c = ca[i];
|
|
1274
|
-
while (c.charAt(0) == ' ') {
|
|
1275
|
-
c = c.substring(1, c.length);
|
|
1276
|
-
}
|
|
1277
|
-
if (c.indexOf(nameEQ) === 0) {
|
|
1278
|
-
return decodeURIComponent(c.substring(nameEQ.length, c.length))
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
|
-
} catch (err) {}
|
|
1282
|
-
return null
|
|
1283
|
-
},
|
|
1284
|
-
|
|
1285
|
-
parse: function (name) {
|
|
1286
|
-
var cookie;
|
|
1287
|
-
try {
|
|
1288
|
-
cookie = JSON.parse(cookieStore.get(name)) || {};
|
|
1289
|
-
} catch (err) {
|
|
1290
|
-
// noop
|
|
1291
|
-
}
|
|
1292
|
-
return cookie
|
|
1293
|
-
},
|
|
1294
|
-
|
|
1295
|
-
set: function (name, value, days, cross_subdomain, is_secure) {
|
|
1296
|
-
try {
|
|
1297
|
-
var cdomain = '',
|
|
1298
|
-
expires = '',
|
|
1299
|
-
secure = '';
|
|
1300
|
-
|
|
1301
|
-
if (cross_subdomain) {
|
|
1302
|
-
var matches = document.location.hostname.match(DOMAIN_MATCH_REGEX),
|
|
1303
|
-
domain = matches ? matches[0] : '';
|
|
1304
|
-
|
|
1305
|
-
cdomain = domain ? '; domain=.' + domain : '';
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
if (days) {
|
|
1309
|
-
var date = new Date();
|
|
1310
|
-
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
1311
|
-
expires = '; expires=' + date.toGMTString();
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
if (is_secure) {
|
|
1315
|
-
secure = '; secure';
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
var new_cookie_val =
|
|
1319
|
-
name + '=' + encodeURIComponent(JSON.stringify(value)) + expires + '; path=/' + cdomain + secure;
|
|
1320
|
-
document.cookie = new_cookie_val;
|
|
1321
|
-
return new_cookie_val
|
|
1322
|
-
} catch (err) {
|
|
1323
|
-
return
|
|
1324
|
-
}
|
|
1325
|
-
},
|
|
1326
|
-
|
|
1327
|
-
remove: function (name, cross_subdomain) {
|
|
1328
|
-
try {
|
|
1329
|
-
cookieStore.set(name, '', -1, cross_subdomain);
|
|
1330
|
-
} catch (err) {
|
|
1331
|
-
return
|
|
1332
|
-
}
|
|
1333
|
-
},
|
|
1334
|
-
};
|
|
1335
|
-
|
|
1336
|
-
var _localStorage_supported = null;
|
|
1337
|
-
const localStore = {
|
|
1338
|
-
is_supported: function () {
|
|
1339
|
-
if (_localStorage_supported !== null) {
|
|
1340
|
-
return _localStorage_supported
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
var supported = true;
|
|
1344
|
-
if (window) {
|
|
1345
|
-
try {
|
|
1346
|
-
var key = '__mplssupport__',
|
|
1347
|
-
val = 'xyz';
|
|
1348
|
-
localStore.set(key, val);
|
|
1349
|
-
if (localStore.get(key) !== '"xyz"') {
|
|
1350
|
-
supported = false;
|
|
1351
|
-
}
|
|
1352
|
-
localStore.remove(key);
|
|
1353
|
-
} catch (err) {
|
|
1354
|
-
supported = false;
|
|
1355
|
-
}
|
|
1356
|
-
} else {
|
|
1357
|
-
supported = false;
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
_localStorage_supported = supported;
|
|
1361
|
-
return supported
|
|
1362
|
-
},
|
|
1363
|
-
|
|
1364
|
-
error: function (msg) {
|
|
1365
|
-
},
|
|
1366
|
-
|
|
1367
|
-
get: function (name) {
|
|
1368
|
-
try {
|
|
1369
|
-
return window.localStorage.getItem(name)
|
|
1370
|
-
} catch (err) {
|
|
1371
|
-
localStore.error(err);
|
|
1372
|
-
}
|
|
1373
|
-
return null
|
|
1374
|
-
},
|
|
1375
|
-
|
|
1376
|
-
parse: function (name) {
|
|
1377
|
-
try {
|
|
1378
|
-
return JSON.parse(localStore.get(name)) || {}
|
|
1379
|
-
} catch (err) {
|
|
1380
|
-
// noop
|
|
1381
|
-
}
|
|
1382
|
-
return null
|
|
1383
|
-
},
|
|
1384
|
-
|
|
1385
|
-
set: function (name, value) {
|
|
1386
|
-
try {
|
|
1387
|
-
window.localStorage.setItem(name, JSON.stringify(value));
|
|
1388
|
-
} catch (err) {
|
|
1389
|
-
localStore.error(err);
|
|
1390
|
-
}
|
|
1391
|
-
},
|
|
1392
|
-
|
|
1393
|
-
remove: function (name) {
|
|
1394
|
-
try {
|
|
1395
|
-
window.localStorage.removeItem(name);
|
|
1396
|
-
} catch (err) {
|
|
1397
|
-
localStore.error(err);
|
|
1398
|
-
}
|
|
1399
|
-
},
|
|
1400
|
-
};
|
|
1401
|
-
|
|
1402
|
-
// Use localstorage for most data but still use cookie for distinct_id
|
|
1403
|
-
// This solves issues with cookies having too much data in them causing headers too large
|
|
1404
|
-
// Also makes sure we don't have to send a ton of data to the server
|
|
1405
|
-
const localPlusCookieStore = {
|
|
1406
|
-
...localStore,
|
|
1407
|
-
parse: function (name) {
|
|
1408
|
-
try {
|
|
1409
|
-
let extend = {};
|
|
1410
|
-
try {
|
|
1411
|
-
// See if there's a cookie stored with data.
|
|
1412
|
-
extend = cookieStore.parse(name) || {};
|
|
1413
|
-
if (extend['distinct_id']) {
|
|
1414
|
-
cookieStore.set(name, { distinct_id: extend['distinct_id'] });
|
|
1415
|
-
}
|
|
1416
|
-
} catch (err) {}
|
|
1417
|
-
const value = _.extend(extend, JSON.parse(localStore.get(name) || '{}'));
|
|
1418
|
-
localStore.set(name, value);
|
|
1419
|
-
return value
|
|
1420
|
-
} catch (err) {
|
|
1421
|
-
// noop
|
|
1422
|
-
}
|
|
1423
|
-
return null
|
|
1424
|
-
},
|
|
1425
|
-
|
|
1426
|
-
set: function (name, value) {
|
|
1427
|
-
try {
|
|
1428
|
-
localStore.set(name, value);
|
|
1429
|
-
if (value.distinct_id) {
|
|
1430
|
-
cookieStore.set(name, { distinct_id: value.distinct_id });
|
|
1431
|
-
}
|
|
1432
|
-
} catch (err) {
|
|
1433
|
-
localStore.error(err);
|
|
1434
|
-
}
|
|
1435
|
-
},
|
|
1436
|
-
|
|
1437
|
-
remove: function (name) {
|
|
1438
|
-
try {
|
|
1439
|
-
window.localStorage.removeItem(name);
|
|
1440
|
-
cookieStore.remove(name);
|
|
1441
|
-
} catch (err) {
|
|
1442
|
-
localStore.error(err);
|
|
1443
|
-
}
|
|
1444
|
-
},
|
|
1445
|
-
};
|
|
1446
|
-
|
|
1447
|
-
const memoryStorage = {};
|
|
1448
|
-
|
|
1449
|
-
// Storage that only lasts the length of the pageview if we don't want to use cookies
|
|
1450
|
-
const memoryStore = {
|
|
1451
|
-
is_supported: function () {
|
|
1452
|
-
return true
|
|
1453
|
-
},
|
|
1454
|
-
|
|
1455
|
-
error: function (msg) {
|
|
1456
|
-
},
|
|
1457
|
-
|
|
1458
|
-
parse: function (name) {
|
|
1459
|
-
return memoryStorage[name] || null
|
|
1460
|
-
},
|
|
1461
|
-
|
|
1462
|
-
set: function (name, value) {
|
|
1463
|
-
memoryStorage[name] = value;
|
|
1464
|
-
},
|
|
1465
|
-
|
|
1466
|
-
remove: function (name) {
|
|
1467
|
-
delete memoryStorage[name];
|
|
1468
|
-
},
|
|
1469
|
-
};
|
|
1470
|
-
|
|
1471
|
-
// Storage that only lasts the length of a tab/window. Survives page refreshes
|
|
1472
|
-
const sessionStore = {
|
|
1473
|
-
sessionStorageSupported: null,
|
|
1474
|
-
is_supported: function () {
|
|
1475
|
-
if (sessionStore.sessionStorageSupported !== null) {
|
|
1476
|
-
return sessionStore.sessionStorageSupported
|
|
1477
|
-
}
|
|
1478
|
-
sessionStore.sessionStorageSupported = true;
|
|
1479
|
-
if (window) {
|
|
1480
|
-
try {
|
|
1481
|
-
let key = '__support__',
|
|
1482
|
-
val = 'xyz';
|
|
1483
|
-
sessionStore.set(key, val);
|
|
1484
|
-
if (sessionStore.get(key) !== '"xyz"') {
|
|
1485
|
-
sessionStore.sessionStorageSupported = false;
|
|
1486
|
-
}
|
|
1487
|
-
sessionStore.remove(key);
|
|
1488
|
-
} catch (err) {
|
|
1489
|
-
sessionStore.sessionStorageSupported = false;
|
|
1490
|
-
}
|
|
1491
|
-
} else {
|
|
1492
|
-
sessionStore.sessionStorageSupported = false;
|
|
1493
|
-
}
|
|
1494
|
-
return sessionStore.sessionStorageSupported
|
|
1495
|
-
},
|
|
1496
|
-
error: function (msg) {
|
|
1497
|
-
if (Config.DEBUG) ;
|
|
1498
|
-
},
|
|
1499
|
-
|
|
1500
|
-
get: function (name) {
|
|
1501
|
-
try {
|
|
1502
|
-
return window.sessionStorage.getItem(name)
|
|
1503
|
-
} catch (err) {
|
|
1504
|
-
sessionStore.error(err);
|
|
1505
|
-
}
|
|
1506
|
-
return null
|
|
1507
|
-
},
|
|
1508
|
-
|
|
1509
|
-
parse: function (name) {
|
|
1510
|
-
try {
|
|
1511
|
-
return JSON.parse(sessionStore.get(name)) || null
|
|
1512
|
-
} catch (err) {
|
|
1513
|
-
// noop
|
|
1514
|
-
}
|
|
1515
|
-
return null
|
|
1516
|
-
},
|
|
1517
|
-
|
|
1518
|
-
set: function (name, value) {
|
|
1519
|
-
try {
|
|
1520
|
-
window.sessionStorage.setItem(name, JSON.stringify(value));
|
|
1521
|
-
} catch (err) {
|
|
1522
|
-
sessionStore.error(err);
|
|
1523
|
-
}
|
|
1524
|
-
},
|
|
1525
|
-
|
|
1526
|
-
remove: function (name) {
|
|
1527
|
-
try {
|
|
1528
|
-
window.sessionStorage.removeItem(name);
|
|
1529
|
-
} catch (err) {
|
|
1530
|
-
sessionStore.error(err);
|
|
1531
|
-
}
|
|
1532
|
-
},
|
|
1533
|
-
};
|
|
1534
|
-
|
|
1535
|
-
/* eslint camelcase: "off" */
|
|
1536
|
-
|
|
1537
|
-
/*
|
|
1538
|
-
* Constants
|
|
1539
|
-
*/
|
|
1540
|
-
/** @const */ var SET_QUEUE_KEY = '__mps';
|
|
1541
|
-
/** @const */ var SET_ONCE_QUEUE_KEY = '__mpso';
|
|
1542
|
-
/** @const */ var UNSET_QUEUE_KEY = '__mpus';
|
|
1543
|
-
/** @const */ var ADD_QUEUE_KEY = '__mpa';
|
|
1544
|
-
/** @const */ var APPEND_QUEUE_KEY = '__mpap';
|
|
1545
|
-
/** @const */ var REMOVE_QUEUE_KEY = '__mpr';
|
|
1546
|
-
/** @const */ var UNION_QUEUE_KEY = '__mpu';
|
|
1547
|
-
/** @const */ var CAMPAIGN_IDS_KEY = '__cmpns';
|
|
1548
|
-
/** @const */ var EVENT_TIMERS_KEY = '__timers';
|
|
1549
|
-
/** @const */ var SESSION_RECORDING_ENABLED = '$session_recording_enabled';
|
|
1550
|
-
/** @const */ var SESSION_ID = '$sesid';
|
|
1551
|
-
/** @const */ var ENABLED_FEATURE_FLAGS = '$enabled_feature_flags';
|
|
1552
|
-
/** @const */ var RESERVED_PROPERTIES = [
|
|
1553
|
-
SET_QUEUE_KEY,
|
|
1554
|
-
SET_ONCE_QUEUE_KEY,
|
|
1555
|
-
UNSET_QUEUE_KEY,
|
|
1556
|
-
ADD_QUEUE_KEY,
|
|
1557
|
-
APPEND_QUEUE_KEY,
|
|
1558
|
-
REMOVE_QUEUE_KEY,
|
|
1559
|
-
UNION_QUEUE_KEY,
|
|
1560
|
-
CAMPAIGN_IDS_KEY,
|
|
1561
|
-
EVENT_TIMERS_KEY,
|
|
1562
|
-
SESSION_RECORDING_ENABLED,
|
|
1563
|
-
SESSION_ID,
|
|
1564
|
-
ENABLED_FEATURE_FLAGS,
|
|
1565
|
-
];
|
|
1566
|
-
|
|
1567
|
-
/**
|
|
1568
|
-
* UserMaven Persistence Object
|
|
1569
|
-
* @constructor
|
|
1570
|
-
*/
|
|
1571
|
-
var UserMavenPersistence = function (config) {
|
|
1572
|
-
// clean chars that aren't accepted by the http spec for cookie values
|
|
1573
|
-
// https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
|
|
1574
|
-
let token = '';
|
|
1575
|
-
|
|
1576
|
-
if (config['token']) {
|
|
1577
|
-
token = config['token'].replace(/\+/g, 'PL').replace(/\//g, 'SL').replace(/=/g, 'EQ');
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
this['props'] = {};
|
|
1581
|
-
this.campaign_params_saved = false;
|
|
1582
|
-
|
|
1583
|
-
if (config['persistence_name']) {
|
|
1584
|
-
this.name = 'um_' + config['persistence_name'];
|
|
1585
|
-
} else {
|
|
1586
|
-
this.name = 'um_' + token + '_usermaven';
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
var storage_type = config['persistence'];
|
|
1590
|
-
if (storage_type !== 'cookie' && storage_type.indexOf('localStorage') === -1 && storage_type !== 'memory') {
|
|
1591
|
-
console$1.critical('Unknown persistence type ' + storage_type + '; falling back to cookie');
|
|
1592
|
-
storage_type = config['persistence'] = 'cookie';
|
|
1593
|
-
}
|
|
1594
|
-
if (storage_type === 'localStorage' && localStore.is_supported()) {
|
|
1595
|
-
this.storage = localStore;
|
|
1596
|
-
} else if (storage_type === 'localStorage+cookie' && localPlusCookieStore.is_supported()) {
|
|
1597
|
-
this.storage = localPlusCookieStore;
|
|
1598
|
-
} else if (storage_type === 'memory') {
|
|
1599
|
-
this.storage = memoryStore;
|
|
1600
|
-
} else {
|
|
1601
|
-
this.storage = cookieStore;
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
this.load();
|
|
1605
|
-
this.update_config(config);
|
|
1606
|
-
this.save();
|
|
1607
|
-
};
|
|
1608
|
-
|
|
1609
|
-
UserMavenPersistence.prototype.properties = function () {
|
|
1610
|
-
var p = {};
|
|
1611
|
-
// Filter out reserved properties
|
|
1612
|
-
_.each(this['props'], function (v, k) {
|
|
1613
|
-
if (k === ENABLED_FEATURE_FLAGS && typeof v === 'object') {
|
|
1614
|
-
var keys = Object.keys(v);
|
|
1615
|
-
for (var i = 0; i < keys.length; i++) {
|
|
1616
|
-
p[`$feature/${keys[i]}`] = v[keys[i]];
|
|
1617
|
-
}
|
|
1618
|
-
} else if (!_.include(RESERVED_PROPERTIES, k)) {
|
|
1619
|
-
p[k] = v;
|
|
1620
|
-
}
|
|
1621
|
-
});
|
|
1622
|
-
return p
|
|
1623
|
-
};
|
|
1624
|
-
|
|
1625
|
-
UserMavenPersistence.prototype.load = function () {
|
|
1626
|
-
if (this.disabled) {
|
|
1627
|
-
return
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
var entry = this.storage.parse(this.name);
|
|
1631
|
-
|
|
1632
|
-
if (entry) {
|
|
1633
|
-
this['props'] = _.extend({}, entry);
|
|
1634
|
-
}
|
|
1635
|
-
};
|
|
1636
|
-
|
|
1637
|
-
UserMavenPersistence.prototype.save = function () {
|
|
1638
|
-
if (this.disabled) {
|
|
1639
|
-
return
|
|
1640
|
-
}
|
|
1641
|
-
this.storage.set(this.name, this['props'], this.expire_days, this.cross_subdomain, this.secure);
|
|
1642
|
-
};
|
|
1643
|
-
|
|
1644
|
-
UserMavenPersistence.prototype.remove = function () {
|
|
1645
|
-
// remove both domain and subdomain cookies
|
|
1646
|
-
this.storage.remove(this.name, false);
|
|
1647
|
-
this.storage.remove(this.name, true);
|
|
1648
|
-
};
|
|
1649
|
-
|
|
1650
|
-
// removes the storage entry and deletes all loaded data
|
|
1651
|
-
// forced name for tests
|
|
1652
|
-
UserMavenPersistence.prototype.clear = function () {
|
|
1653
|
-
this.remove();
|
|
1654
|
-
this['props'] = {};
|
|
1655
|
-
};
|
|
1656
|
-
|
|
1657
|
-
/**
|
|
1658
|
-
* @param {Object} props
|
|
1659
|
-
* @param {*=} default_value
|
|
1660
|
-
* @param {number=} days
|
|
1661
|
-
*/
|
|
1662
|
-
UserMavenPersistence.prototype.register_once = function (props, default_value, days) {
|
|
1663
|
-
if (_.isObject(props)) {
|
|
1664
|
-
if (typeof default_value === 'undefined') {
|
|
1665
|
-
default_value = 'None';
|
|
1666
|
-
}
|
|
1667
|
-
this.expire_days = typeof days === 'undefined' ? this.default_expiry : days;
|
|
1668
|
-
|
|
1669
|
-
_.each(
|
|
1670
|
-
props,
|
|
1671
|
-
function (val, prop) {
|
|
1672
|
-
if (!this['props'].hasOwnProperty(prop) || this['props'][prop] === default_value) {
|
|
1673
|
-
this['props'][prop] = val;
|
|
1674
|
-
}
|
|
1675
|
-
},
|
|
1676
|
-
this
|
|
1677
|
-
);
|
|
1678
|
-
|
|
1679
|
-
this.save();
|
|
1680
|
-
|
|
1681
|
-
return true
|
|
1682
|
-
}
|
|
1683
|
-
return false
|
|
1684
|
-
};
|
|
1685
|
-
|
|
1686
|
-
/**
|
|
1687
|
-
* @param {Object} props
|
|
1688
|
-
* @param {number=} days
|
|
1689
|
-
*/
|
|
1690
|
-
UserMavenPersistence.prototype.register = function (props, days) {
|
|
1691
|
-
if (_.isObject(props)) {
|
|
1692
|
-
this.expire_days = typeof days === 'undefined' ? this.default_expiry : days;
|
|
1693
|
-
|
|
1694
|
-
_.extend(this['props'], props);
|
|
1695
|
-
|
|
1696
|
-
this.save();
|
|
1697
|
-
|
|
1698
|
-
return true
|
|
1699
|
-
}
|
|
1700
|
-
return false
|
|
1701
|
-
};
|
|
1702
|
-
|
|
1703
|
-
UserMavenPersistence.prototype.unregister = function (prop) {
|
|
1704
|
-
if (prop in this['props']) {
|
|
1705
|
-
delete this['props'][prop];
|
|
1706
|
-
this.save();
|
|
1707
|
-
}
|
|
1708
|
-
};
|
|
1709
|
-
|
|
1710
|
-
UserMavenPersistence.prototype.update_campaign_params = function () {
|
|
1711
|
-
if (!this.campaign_params_saved) {
|
|
1712
|
-
this.register(_.info.campaignParams());
|
|
1713
|
-
this.campaign_params_saved = true;
|
|
1714
|
-
}
|
|
1715
|
-
};
|
|
1716
|
-
|
|
1717
|
-
UserMavenPersistence.prototype.update_search_keyword = function (referrer) {
|
|
1718
|
-
this.register(_.info.searchInfo(referrer));
|
|
1719
|
-
};
|
|
1720
|
-
|
|
1721
|
-
// EXPORTED METHOD, we test this directly.
|
|
1722
|
-
UserMavenPersistence.prototype.update_referrer_info = function (referrer) {
|
|
1723
|
-
// If referrer doesn't exist, we want to note the fact that it was type-in traffic.
|
|
1724
|
-
// Register once, so first touch
|
|
1725
|
-
this.register_once(
|
|
1726
|
-
{
|
|
1727
|
-
$initial_referrer: referrer || '$direct',
|
|
1728
|
-
$initial_referring_domain: _.info.referringDomain(referrer) || '$direct',
|
|
1729
|
-
},
|
|
1730
|
-
''
|
|
1731
|
-
);
|
|
1732
|
-
// Register the current referrer but override if it's different, hence register
|
|
1733
|
-
this.register({
|
|
1734
|
-
$referrer: referrer || this['props']['$referrer'] || '$direct',
|
|
1735
|
-
$referring_domain: _.info.referringDomain(referrer) || this['props']['$referring_domain'] || '$direct',
|
|
1736
|
-
});
|
|
1737
|
-
};
|
|
1738
|
-
|
|
1739
|
-
UserMavenPersistence.prototype.get_referrer_info = function () {
|
|
1740
|
-
return _.strip_empty_properties({
|
|
1741
|
-
$initial_referrer: this['props']['$initial_referrer'],
|
|
1742
|
-
$initial_referring_domain: this['props']['$initial_referring_domain'],
|
|
1743
|
-
})
|
|
1744
|
-
};
|
|
1745
|
-
|
|
1746
|
-
// safely fills the passed in object with stored properties,
|
|
1747
|
-
// does not override any properties defined in both
|
|
1748
|
-
// returns the passed in object
|
|
1749
|
-
UserMavenPersistence.prototype.safe_merge = function (props) {
|
|
1750
|
-
_.each(this['props'], function (val, prop) {
|
|
1751
|
-
if (!(prop in props)) {
|
|
1752
|
-
props[prop] = val;
|
|
1753
|
-
}
|
|
1754
|
-
});
|
|
1755
|
-
|
|
1756
|
-
return props
|
|
1757
|
-
};
|
|
1758
|
-
|
|
1759
|
-
UserMavenPersistence.prototype.update_config = function (config) {
|
|
1760
|
-
this.default_expiry = this.expire_days = config['cookie_expiration'];
|
|
1761
|
-
this.set_disabled(config['disable_persistence']);
|
|
1762
|
-
this.set_cross_subdomain(config['cross_subdomain_cookie']);
|
|
1763
|
-
this.set_secure(config['secure_cookie']);
|
|
1764
|
-
};
|
|
1765
|
-
|
|
1766
|
-
UserMavenPersistence.prototype.set_disabled = function (disabled) {
|
|
1767
|
-
this.disabled = disabled;
|
|
1768
|
-
if (this.disabled) {
|
|
1769
|
-
this.remove();
|
|
1770
|
-
} else {
|
|
1771
|
-
this.save();
|
|
1772
|
-
}
|
|
1773
|
-
};
|
|
1774
|
-
|
|
1775
|
-
UserMavenPersistence.prototype.set_cross_subdomain = function (cross_subdomain) {
|
|
1776
|
-
if (cross_subdomain !== this.cross_subdomain) {
|
|
1777
|
-
this.cross_subdomain = cross_subdomain;
|
|
1778
|
-
this.remove();
|
|
1779
|
-
this.save();
|
|
1780
|
-
}
|
|
1781
|
-
};
|
|
1782
|
-
|
|
1783
|
-
UserMavenPersistence.prototype.get_cross_subdomain = function () {
|
|
1784
|
-
return this.cross_subdomain
|
|
1785
|
-
};
|
|
1786
|
-
|
|
1787
|
-
UserMavenPersistence.prototype.set_secure = function (secure) {
|
|
1788
|
-
if (secure !== this.secure) {
|
|
1789
|
-
this.secure = secure ? true : false;
|
|
1790
|
-
this.remove();
|
|
1791
|
-
this.save();
|
|
547
|
+
// let bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
|
|
548
|
+
var _isFunction = function (f) {
|
|
549
|
+
try {
|
|
550
|
+
return /^\s*\bfunction\b/.test(f);
|
|
551
|
+
}
|
|
552
|
+
catch (x) {
|
|
553
|
+
return false;
|
|
1792
554
|
}
|
|
1793
555
|
};
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
var timers = this['props'][EVENT_TIMERS_KEY] || {};
|
|
1797
|
-
timers[event_name] = timestamp;
|
|
1798
|
-
this['props'][EVENT_TIMERS_KEY] = timers;
|
|
1799
|
-
this.save();
|
|
1800
|
-
};
|
|
1801
|
-
|
|
1802
|
-
UserMavenPersistence.prototype.remove_event_timer = function (event_name) {
|
|
1803
|
-
var timers = this['props'][EVENT_TIMERS_KEY] || {};
|
|
1804
|
-
var timestamp = timers[event_name];
|
|
1805
|
-
if (!_.isUndefined(timestamp)) {
|
|
1806
|
-
delete this['props'][EVENT_TIMERS_KEY][event_name];
|
|
1807
|
-
this.save();
|
|
1808
|
-
}
|
|
1809
|
-
return timestamp
|
|
556
|
+
var _isUndefined = function (obj) {
|
|
557
|
+
return obj === void 0;
|
|
1810
558
|
};
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
559
|
+
var _register_event = (function () {
|
|
560
|
+
// written by Dean Edwards, 2005
|
|
561
|
+
// with input from Tino Zijdel - crisp@xs4all.nl
|
|
562
|
+
// with input from Carl Sverre - mail@carlsverre.com
|
|
563
|
+
// with input from PostHog
|
|
564
|
+
// http://dean.edwards.name/weblog/2005/10/add-event/
|
|
565
|
+
// https://gist.github.com/1930440
|
|
566
|
+
/**
|
|
567
|
+
* @param {Object} element
|
|
568
|
+
* @param {string} type
|
|
569
|
+
* @param {function(...*)} handler
|
|
570
|
+
* @param {boolean=} oldSchool
|
|
571
|
+
* @param {boolean=} useCapture
|
|
572
|
+
*/
|
|
573
|
+
var register_event = function (element, type, handler, oldSchool, useCapture) {
|
|
574
|
+
if (!element) {
|
|
575
|
+
getLogger().error('No valid element provided to register_event');
|
|
576
|
+
return;
|
|
1823
577
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
578
|
+
if (element.addEventListener && !oldSchool) {
|
|
579
|
+
element.addEventListener(type, handler, !!useCapture);
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
var ontype = 'on' + type;
|
|
583
|
+
var old_handler = element[ontype] // can be undefined
|
|
584
|
+
;
|
|
585
|
+
element[ontype] = makeHandler(element, handler, old_handler);
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
function makeHandler(element, new_handler, old_handlers) {
|
|
589
|
+
return function (event) {
|
|
590
|
+
event = event || fixEvent(window.event);
|
|
591
|
+
// this basically happens in firefox whenever another script
|
|
592
|
+
// overwrites the onload callback and doesn't pass the event
|
|
593
|
+
// object to previously defined callbacks. All the browsers
|
|
594
|
+
// that don't define window.event implement addEventListener
|
|
595
|
+
// so the dom_loaded handler will still be fired as usual.
|
|
596
|
+
if (!event) {
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
var ret = true;
|
|
600
|
+
var old_result;
|
|
601
|
+
if (_isFunction(old_handlers)) {
|
|
602
|
+
old_result = old_handlers(event);
|
|
1835
603
|
}
|
|
604
|
+
var new_result = new_handler.call(element, event);
|
|
605
|
+
if (false === old_result || false === new_result) {
|
|
606
|
+
ret = false;
|
|
607
|
+
}
|
|
608
|
+
return ret;
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
function fixEvent(event) {
|
|
612
|
+
if (event) {
|
|
613
|
+
event.preventDefault = fixEvent.preventDefault;
|
|
614
|
+
event.stopPropagation = fixEvent.stopPropagation;
|
|
1836
615
|
}
|
|
616
|
+
return event;
|
|
1837
617
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
618
|
+
fixEvent.preventDefault = function () {
|
|
619
|
+
this.returnValue = false;
|
|
620
|
+
};
|
|
621
|
+
fixEvent.stopPropagation = function () {
|
|
622
|
+
this.cancelBubble = true;
|
|
623
|
+
};
|
|
624
|
+
return register_event;
|
|
625
|
+
})();
|
|
626
|
+
var _safewrap = function (f) {
|
|
627
|
+
return function () {
|
|
628
|
+
var args = [];
|
|
629
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
630
|
+
args[_i] = arguments[_i];
|
|
1842
631
|
}
|
|
1843
|
-
|
|
1844
|
-
|
|
632
|
+
try {
|
|
633
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
634
|
+
// @ts-ignore
|
|
635
|
+
return f.apply(this, args);
|
|
1845
636
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
_setSessionId(sessionId, timestamp) {
|
|
1852
|
-
if (sessionId !== this.sessionId || timestamp !== this.timestamp) {
|
|
1853
|
-
this.timestamp = timestamp;
|
|
1854
|
-
this.sessionId = sessionId;
|
|
1855
|
-
this.persistence.register({ [SESSION_ID]: [timestamp, sessionId] });
|
|
637
|
+
catch (e) {
|
|
638
|
+
getLogger().error('Implementation error. Please turn on debug and contact support@usermaven.com.', e);
|
|
639
|
+
// if (Config.DEBUG) {
|
|
640
|
+
// getLogger.critical(e)
|
|
641
|
+
// }
|
|
1856
642
|
}
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
643
|
+
};
|
|
644
|
+
};
|
|
645
|
+
var _safewrap_instance_methods = function (obj) {
|
|
646
|
+
for (var func in obj) {
|
|
647
|
+
if (typeof obj[func] === 'function') {
|
|
648
|
+
obj[func] = _safewrap(obj[func]);
|
|
1862
649
|
}
|
|
1863
|
-
return this.persistence['props'][SESSION_ID] || [0, null]
|
|
1864
650
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
651
|
+
};
|
|
652
|
+
var COPY_IN_PROGRESS_ATTRIBUTE = typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
|
|
653
|
+
/**
|
|
654
|
+
* Deep copies an object.
|
|
655
|
+
* It handles cycles by replacing all references to them with `undefined`
|
|
656
|
+
* Also supports customizing native values
|
|
657
|
+
*
|
|
658
|
+
* @param value
|
|
659
|
+
* @param customizer
|
|
660
|
+
* @param [key] if provided this is the object key associated with the value to be copied. It allows the customizer function to have context when it runs
|
|
661
|
+
* @returns {{}|undefined|*}
|
|
662
|
+
*/
|
|
663
|
+
function deepCircularCopy(value, customizer, key) {
|
|
664
|
+
if (value !== Object(value))
|
|
665
|
+
return customizer ? customizer(value, key) : value; // primitive value
|
|
666
|
+
if (value[COPY_IN_PROGRESS_ATTRIBUTE])
|
|
667
|
+
return undefined;
|
|
668
|
+
value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
|
|
669
|
+
var result;
|
|
670
|
+
if (_isArray(value)) {
|
|
671
|
+
result = [];
|
|
672
|
+
_eachArray(value, function (it) {
|
|
673
|
+
result.push(deepCircularCopy(it, customizer));
|
|
674
|
+
});
|
|
1870
675
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
timestamp = timestamp || new Date().getTime();
|
|
1888
|
-
|
|
1889
|
-
let [lastTimestamp, sessionId] = this._getSessionId();
|
|
1890
|
-
let windowId = this._getWindowId();
|
|
1891
|
-
|
|
1892
|
-
if (!sessionId || (Math.abs(timestamp - lastTimestamp) > this.session_change_threshold)) {
|
|
1893
|
-
sessionId = _.UUID();
|
|
1894
|
-
windowId = _.UUID();
|
|
1895
|
-
} else if (!windowId) {
|
|
1896
|
-
windowId = _.UUID();
|
|
676
|
+
else {
|
|
677
|
+
result = {};
|
|
678
|
+
_each(value, function (val, key) {
|
|
679
|
+
if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
|
|
680
|
+
result[key] = deepCircularCopy(val, customizer, key);
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
delete value[COPY_IN_PROGRESS_ATTRIBUTE];
|
|
685
|
+
return result;
|
|
686
|
+
}
|
|
687
|
+
var LONG_STRINGS_ALLOW_LIST = ['$performance_raw'];
|
|
688
|
+
function _copyAndTruncateStrings(object, maxStringLength) {
|
|
689
|
+
return deepCircularCopy(object, function (value, key) {
|
|
690
|
+
if (key && LONG_STRINGS_ALLOW_LIST.indexOf(key) > -1) {
|
|
691
|
+
return value;
|
|
1897
692
|
}
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
this._setWindowId(windowId);
|
|
1902
|
-
this._setSessionId(sessionId, newTimestamp);
|
|
1903
|
-
return {
|
|
1904
|
-
session_id: sessionId,
|
|
1905
|
-
window_id: windowId,
|
|
693
|
+
if (typeof value === 'string' && maxStringLength !== null) {
|
|
694
|
+
return value.slice(0, maxStringLength);
|
|
1906
695
|
}
|
|
1907
|
-
|
|
696
|
+
return value;
|
|
697
|
+
});
|
|
1908
698
|
}
|
|
1909
699
|
|
|
1910
700
|
/*
|
|
@@ -1915,15 +705,15 @@ class SessionIdManager {
|
|
|
1915
705
|
function getClassName(el) {
|
|
1916
706
|
switch (typeof el.className) {
|
|
1917
707
|
case 'string':
|
|
1918
|
-
return el.className
|
|
708
|
+
return el.className;
|
|
709
|
+
// TODO: when is this ever used?
|
|
1919
710
|
case 'object': // handle cases where className might be SVGAnimatedString or some other type
|
|
1920
|
-
return el.className.baseVal || el.getAttribute('class') || ''
|
|
711
|
+
return ('baseVal' in el.className ? el.className.baseVal : null) || el.getAttribute('class') || '';
|
|
1921
712
|
default:
|
|
1922
713
|
// future proof
|
|
1923
|
-
return ''
|
|
714
|
+
return '';
|
|
1924
715
|
}
|
|
1925
716
|
}
|
|
1926
|
-
|
|
1927
717
|
/*
|
|
1928
718
|
* Get the direct text content of an element, protecting against sensitive data collection.
|
|
1929
719
|
* Concats textContent of each of the element's text node children; this avoids potential
|
|
@@ -1935,11 +725,10 @@ function getClassName(el) {
|
|
|
1935
725
|
*/
|
|
1936
726
|
function getSafeText(el) {
|
|
1937
727
|
var elText = '';
|
|
1938
|
-
|
|
1939
728
|
if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {
|
|
1940
|
-
|
|
729
|
+
_each(el.childNodes, function (child) {
|
|
1941
730
|
if (isTextNode(child) && child.textContent) {
|
|
1942
|
-
elText +=
|
|
731
|
+
elText += _trim(child.textContent)
|
|
1943
732
|
// scrub potentially sensitive values
|
|
1944
733
|
.split(/(\s+)/)
|
|
1945
734
|
.filter(shouldCaptureValue)
|
|
@@ -1952,19 +741,16 @@ function getSafeText(el) {
|
|
|
1952
741
|
}
|
|
1953
742
|
});
|
|
1954
743
|
}
|
|
1955
|
-
|
|
1956
|
-
return _.trim(elText)
|
|
744
|
+
return _trim(elText);
|
|
1957
745
|
}
|
|
1958
|
-
|
|
1959
746
|
/*
|
|
1960
747
|
* Check whether an element has nodeType Node.ELEMENT_NODE
|
|
1961
748
|
* @param {Element} el - element to check
|
|
1962
749
|
* @returns {boolean} whether el is of the correct nodeType
|
|
1963
750
|
*/
|
|
1964
751
|
function isElementNode(el) {
|
|
1965
|
-
return el && el.nodeType === 1 // Node.ELEMENT_NODE - use integer constant for browser portability
|
|
752
|
+
return !!el && el.nodeType === 1; // Node.ELEMENT_NODE - use integer constant for browser portability
|
|
1966
753
|
}
|
|
1967
|
-
|
|
1968
754
|
/*
|
|
1969
755
|
* Check whether an element is of a given tag type.
|
|
1970
756
|
* Due to potential reference discrepancies (such as the webcomponents.js polyfill),
|
|
@@ -1976,18 +762,24 @@ function isElementNode(el) {
|
|
|
1976
762
|
* @returns {boolean} whether el is of the given tag type
|
|
1977
763
|
*/
|
|
1978
764
|
function isTag(el, tag) {
|
|
1979
|
-
return el && el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()
|
|
765
|
+
return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase();
|
|
1980
766
|
}
|
|
1981
|
-
|
|
1982
767
|
/*
|
|
1983
768
|
* Check whether an element has nodeType Node.TEXT_NODE
|
|
1984
769
|
* @param {Element} el - element to check
|
|
1985
770
|
* @returns {boolean} whether el is of the correct nodeType
|
|
1986
771
|
*/
|
|
1987
772
|
function isTextNode(el) {
|
|
1988
|
-
return el && el.nodeType === 3 // Node.TEXT_NODE - use integer constant for browser portability
|
|
773
|
+
return !!el && el.nodeType === 3; // Node.TEXT_NODE - use integer constant for browser portability
|
|
774
|
+
}
|
|
775
|
+
/*
|
|
776
|
+
* Check whether an element has nodeType Node.DOCUMENT_FRAGMENT_NODE
|
|
777
|
+
* @param {Element} el - element to check
|
|
778
|
+
* @returns {boolean} whether el is of the correct nodeType
|
|
779
|
+
*/
|
|
780
|
+
function isDocumentFragment(el) {
|
|
781
|
+
return !!el && el.nodeType === 11; // Node.DOCUMENT_FRAGMENT_NODE - use integer constant for browser portability
|
|
1989
782
|
}
|
|
1990
|
-
|
|
1991
783
|
var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'];
|
|
1992
784
|
/*
|
|
1993
785
|
* Check whether a DOM event should be "captured" or if it may contain sentitive data
|
|
@@ -1998,60 +790,56 @@ var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'lab
|
|
|
1998
790
|
*/
|
|
1999
791
|
function shouldCaptureDomEvent(el, event) {
|
|
2000
792
|
if (!el || isTag(el, 'html') || !isElementNode(el)) {
|
|
2001
|
-
return false
|
|
793
|
+
return false;
|
|
2002
794
|
}
|
|
2003
|
-
|
|
2004
795
|
var parentIsUsefulElement = false;
|
|
2005
|
-
var targetElementList = [el];
|
|
796
|
+
var targetElementList = [el]; // TODO: remove this var, it's never queried
|
|
2006
797
|
var parentNode = true;
|
|
2007
798
|
var curEl = el;
|
|
2008
799
|
while (curEl.parentNode && !isTag(curEl, 'body')) {
|
|
2009
800
|
// If element is a shadow root, we skip it
|
|
2010
|
-
if (curEl.parentNode
|
|
801
|
+
if (isDocumentFragment(curEl.parentNode)) {
|
|
2011
802
|
targetElementList.push(curEl.parentNode.host);
|
|
2012
803
|
curEl = curEl.parentNode.host;
|
|
2013
|
-
continue
|
|
804
|
+
continue;
|
|
2014
805
|
}
|
|
2015
|
-
parentNode = curEl.parentNode;
|
|
2016
|
-
if (!parentNode)
|
|
806
|
+
parentNode = curEl.parentNode || false;
|
|
807
|
+
if (!parentNode)
|
|
808
|
+
break;
|
|
2017
809
|
if (usefulElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {
|
|
2018
810
|
parentIsUsefulElement = true;
|
|
2019
|
-
}
|
|
2020
|
-
|
|
2021
|
-
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
var compStyles_1 = window.getComputedStyle(parentNode);
|
|
814
|
+
if (compStyles_1 && compStyles_1.getPropertyValue('cursor') === 'pointer') {
|
|
2022
815
|
parentIsUsefulElement = true;
|
|
2023
816
|
}
|
|
2024
817
|
}
|
|
2025
|
-
|
|
2026
818
|
targetElementList.push(parentNode);
|
|
2027
819
|
curEl = parentNode;
|
|
2028
820
|
}
|
|
2029
|
-
|
|
2030
|
-
let compStyles = window.getComputedStyle(el);
|
|
821
|
+
var compStyles = window.getComputedStyle(el);
|
|
2031
822
|
if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {
|
|
2032
|
-
return true
|
|
823
|
+
return true;
|
|
2033
824
|
}
|
|
2034
|
-
|
|
2035
825
|
var tag = el.tagName.toLowerCase();
|
|
2036
826
|
switch (tag) {
|
|
2037
827
|
case 'html':
|
|
2038
|
-
return false
|
|
828
|
+
return false;
|
|
2039
829
|
case 'form':
|
|
2040
|
-
return event.type === 'submit'
|
|
830
|
+
return event.type === 'submit';
|
|
2041
831
|
case 'input':
|
|
2042
|
-
return event.type === 'change' || event.type === 'click'
|
|
832
|
+
return event.type === 'change' || event.type === 'click';
|
|
2043
833
|
case 'select':
|
|
2044
834
|
case 'textarea':
|
|
2045
|
-
return event.type === 'change' || event.type === 'click'
|
|
835
|
+
return event.type === 'change' || event.type === 'click';
|
|
2046
836
|
default:
|
|
2047
|
-
if (parentIsUsefulElement)
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
(usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')
|
|
2051
|
-
)
|
|
837
|
+
if (parentIsUsefulElement)
|
|
838
|
+
return event.type === 'click';
|
|
839
|
+
return (event.type === 'click' &&
|
|
840
|
+
(usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true'));
|
|
2052
841
|
}
|
|
2053
842
|
}
|
|
2054
|
-
|
|
2055
843
|
/*
|
|
2056
844
|
* Check whether a DOM element should be "captured" or if it may contain sentitive data
|
|
2057
845
|
* using a variety of heuristics.
|
|
@@ -2061,40 +849,38 @@ function shouldCaptureDomEvent(el, event) {
|
|
|
2061
849
|
function shouldCaptureElement(el) {
|
|
2062
850
|
for (var curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode) {
|
|
2063
851
|
var classes = getClassName(curEl).split(' ');
|
|
2064
|
-
if (
|
|
2065
|
-
return false
|
|
852
|
+
if (_includes(classes, 'ph-sensitive') || _includes(classes, 'ph-no-capture')) {
|
|
853
|
+
return false;
|
|
2066
854
|
}
|
|
2067
855
|
}
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
return true
|
|
856
|
+
if (_includes(getClassName(el).split(' '), 'ph-include')) {
|
|
857
|
+
return true;
|
|
2071
858
|
}
|
|
2072
|
-
|
|
2073
859
|
// don't include hidden or password fields
|
|
2074
860
|
var type = el.type || '';
|
|
2075
861
|
if (typeof type === 'string') {
|
|
2076
862
|
// it's possible for el.type to be a DOM element if el is a form with a child input[name="type"]
|
|
2077
863
|
switch (type.toLowerCase()) {
|
|
2078
864
|
case 'hidden':
|
|
2079
|
-
return false
|
|
865
|
+
return false;
|
|
2080
866
|
case 'password':
|
|
2081
|
-
return false
|
|
867
|
+
return false;
|
|
2082
868
|
}
|
|
2083
869
|
}
|
|
2084
|
-
|
|
2085
870
|
// filter out data from fields that look like sensitive fields
|
|
2086
871
|
var name = el.name || el.id || '';
|
|
872
|
+
// See https://github.com/posthog/posthog-js/issues/165
|
|
873
|
+
// Under specific circumstances a bug caused .replace to be called on a DOM element
|
|
874
|
+
// instead of a string, removing the element from the page. Ensure this issue is mitigated.
|
|
2087
875
|
if (typeof name === 'string') {
|
|
2088
876
|
// it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name="name"]
|
|
2089
877
|
var sensitiveNameRegex = /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i;
|
|
2090
878
|
if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {
|
|
2091
|
-
return false
|
|
879
|
+
return false;
|
|
2092
880
|
}
|
|
2093
881
|
}
|
|
2094
|
-
|
|
2095
|
-
return true
|
|
882
|
+
return true;
|
|
2096
883
|
}
|
|
2097
|
-
|
|
2098
884
|
/*
|
|
2099
885
|
* Check whether a DOM element is 'sensitive' and we should only capture limited data
|
|
2100
886
|
* @param {Element} el - element to check
|
|
@@ -2103,18 +889,15 @@ function shouldCaptureElement(el) {
|
|
|
2103
889
|
function isSensitiveElement(el) {
|
|
2104
890
|
// don't send data from inputs or similar elements since there will always be
|
|
2105
891
|
// a risk of clientside javascript placing sensitive data in attributes
|
|
2106
|
-
|
|
2107
|
-
if (
|
|
2108
|
-
(isTag(el, 'input') && !allowedInputTypes.includes(el.type)) ||
|
|
892
|
+
var allowedInputTypes = ['button', 'checkbox', 'submit', 'reset'];
|
|
893
|
+
if ((isTag(el, 'input') && !allowedInputTypes.includes(el.type)) ||
|
|
2109
894
|
isTag(el, 'select') ||
|
|
2110
895
|
isTag(el, 'textarea') ||
|
|
2111
|
-
el.getAttribute('contenteditable') === 'true'
|
|
2112
|
-
|
|
2113
|
-
return true
|
|
896
|
+
el.getAttribute('contenteditable') === 'true') {
|
|
897
|
+
return true;
|
|
2114
898
|
}
|
|
2115
|
-
return false
|
|
899
|
+
return false;
|
|
2116
900
|
}
|
|
2117
|
-
|
|
2118
901
|
/*
|
|
2119
902
|
* Check whether a string value should be "captured" or if it may contain sentitive data
|
|
2120
903
|
* using a variety of heuristics.
|
|
@@ -2122,30 +905,25 @@ function isSensitiveElement(el) {
|
|
|
2122
905
|
* @returns {boolean} whether the element should be captured
|
|
2123
906
|
*/
|
|
2124
907
|
function shouldCaptureValue(value) {
|
|
2125
|
-
if (value === null ||
|
|
2126
|
-
return false
|
|
908
|
+
if (value === null || _isUndefined(value)) {
|
|
909
|
+
return false;
|
|
2127
910
|
}
|
|
2128
|
-
|
|
2129
911
|
if (typeof value === 'string') {
|
|
2130
|
-
value =
|
|
2131
|
-
|
|
912
|
+
value = _trim(value);
|
|
2132
913
|
// check to see if input value looks like a credit card number
|
|
2133
914
|
// see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html
|
|
2134
915
|
var ccRegex = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
|
|
2135
916
|
if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {
|
|
2136
|
-
return false
|
|
917
|
+
return false;
|
|
2137
918
|
}
|
|
2138
|
-
|
|
2139
919
|
// check to see if input value looks like a social security number
|
|
2140
920
|
var ssnRegex = /(^\d{3}-?\d{2}-?\d{4}$)/;
|
|
2141
921
|
if (ssnRegex.test(value)) {
|
|
2142
|
-
return false
|
|
922
|
+
return false;
|
|
2143
923
|
}
|
|
2144
924
|
}
|
|
2145
|
-
|
|
2146
|
-
return true
|
|
925
|
+
return true;
|
|
2147
926
|
}
|
|
2148
|
-
|
|
2149
927
|
/*
|
|
2150
928
|
* Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)
|
|
2151
929
|
* These update on each build and lead to noise in the element chain
|
|
@@ -2155,61 +933,58 @@ function shouldCaptureValue(value) {
|
|
|
2155
933
|
*/
|
|
2156
934
|
function isAngularStyleAttr(attributeName) {
|
|
2157
935
|
if (typeof attributeName === 'string') {
|
|
2158
|
-
return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'
|
|
936
|
+
return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost';
|
|
2159
937
|
}
|
|
2160
|
-
return false
|
|
938
|
+
return false;
|
|
2161
939
|
}
|
|
2162
940
|
|
|
2163
941
|
// Naive rage click implementation: If mouse has not moved than RAGE_CLICK_THRESHOLD_PX
|
|
2164
942
|
// over RAGE_CLICK_CLICK_COUNT clicks with max RAGE_CLICK_TIMEOUT_MS between clicks, it's
|
|
2165
943
|
// counted as a rage click
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
944
|
+
var RAGE_CLICK_THRESHOLD_PX = 30;
|
|
945
|
+
var RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
946
|
+
var RAGE_CLICK_CLICK_COUNT = 3;
|
|
947
|
+
var RageClick = /** @class */ (function () {
|
|
948
|
+
function RageClick(instance, enabled) {
|
|
949
|
+
if (enabled === void 0) { enabled = false; }
|
|
2172
950
|
this.clicks = [];
|
|
2173
951
|
this.instance = instance;
|
|
2174
952
|
this.enabled = enabled;
|
|
2175
953
|
}
|
|
2176
|
-
|
|
2177
|
-
click(x, y, timestamp) {
|
|
954
|
+
RageClick.prototype.click = function (x, y, timestamp) {
|
|
2178
955
|
if (!this.enabled) {
|
|
2179
|
-
return
|
|
956
|
+
return;
|
|
2180
957
|
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
if (
|
|
2184
|
-
lastClick &&
|
|
958
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
959
|
+
if (lastClick &&
|
|
2185
960
|
Math.abs(x - lastClick.x) + Math.abs(y - lastClick.y) < RAGE_CLICK_THRESHOLD_PX &&
|
|
2186
|
-
timestamp - lastClick.timestamp < RAGE_CLICK_TIMEOUT_MS
|
|
2187
|
-
|
|
2188
|
-
this.clicks.push({ x, y, timestamp });
|
|
2189
|
-
|
|
961
|
+
timestamp - lastClick.timestamp < RAGE_CLICK_TIMEOUT_MS) {
|
|
962
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
2190
963
|
if (this.clicks.length === RAGE_CLICK_CLICK_COUNT) {
|
|
2191
964
|
this.instance.capture('$rageclick');
|
|
2192
965
|
}
|
|
2193
|
-
} else {
|
|
2194
|
-
this.clicks = [{ x, y, timestamp }];
|
|
2195
966
|
}
|
|
2196
|
-
|
|
2197
|
-
}
|
|
967
|
+
else {
|
|
968
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
return RageClick;
|
|
972
|
+
}());
|
|
2198
973
|
|
|
2199
974
|
var autocapture = {
|
|
2200
975
|
_initializedTokens: [],
|
|
2201
|
-
|
|
2202
976
|
_previousElementSibling: function (el) {
|
|
2203
977
|
if (el.previousElementSibling) {
|
|
2204
|
-
return el.previousElementSibling
|
|
2205
|
-
}
|
|
978
|
+
return el.previousElementSibling;
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
var _el = el;
|
|
2206
982
|
do {
|
|
2207
|
-
|
|
2208
|
-
} while (
|
|
2209
|
-
return
|
|
983
|
+
_el = _el.previousSibling; // resolves to ChildNode->Node, which is Element's parent class
|
|
984
|
+
} while (_el && !isElementNode(_el));
|
|
985
|
+
return _el;
|
|
2210
986
|
}
|
|
2211
987
|
},
|
|
2212
|
-
|
|
2213
988
|
_getPropertiesFromElement: function (elem, maskInputs, maskText) {
|
|
2214
989
|
var tag_name = elem.tagName.toLowerCase();
|
|
2215
990
|
var props = {
|
|
@@ -2218,22 +993,19 @@ var autocapture = {
|
|
|
2218
993
|
if (usefulElements.indexOf(tag_name) > -1 && !maskText) {
|
|
2219
994
|
props['$el_text'] = getSafeText(elem);
|
|
2220
995
|
}
|
|
2221
|
-
|
|
2222
996
|
var classes = getClassName(elem);
|
|
2223
997
|
if (classes.length > 0)
|
|
2224
998
|
props['classes'] = classes.split(' ').filter(function (c) {
|
|
2225
|
-
return c !== ''
|
|
999
|
+
return c !== '';
|
|
2226
1000
|
});
|
|
2227
|
-
|
|
2228
|
-
_.each(elem.attributes, function (attr) {
|
|
1001
|
+
_each(elem.attributes, function (attr) {
|
|
2229
1002
|
// Only capture attributes we know are safe
|
|
2230
|
-
if (isSensitiveElement(elem) && ['name', 'id', 'class'].indexOf(attr.name) === -1)
|
|
2231
|
-
|
|
1003
|
+
if (isSensitiveElement(elem) && ['name', 'id', 'class'].indexOf(attr.name) === -1)
|
|
1004
|
+
return;
|
|
2232
1005
|
if (!maskInputs && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {
|
|
2233
1006
|
props['attr__' + attr.name] = attr.value;
|
|
2234
1007
|
}
|
|
2235
1008
|
});
|
|
2236
|
-
|
|
2237
1009
|
var nthChild = 1;
|
|
2238
1010
|
var nthOfType = 1;
|
|
2239
1011
|
var currentElem = elem;
|
|
@@ -2246,219 +1018,178 @@ var autocapture = {
|
|
|
2246
1018
|
}
|
|
2247
1019
|
props['nth_child'] = nthChild;
|
|
2248
1020
|
props['nth_of_type'] = nthOfType;
|
|
2249
|
-
|
|
2250
|
-
return props
|
|
1021
|
+
return props;
|
|
2251
1022
|
},
|
|
2252
|
-
|
|
2253
1023
|
_getDefaultProperties: function (eventType) {
|
|
2254
1024
|
return {
|
|
2255
1025
|
$event_type: eventType,
|
|
2256
1026
|
$ce_version: 1,
|
|
2257
|
-
}
|
|
1027
|
+
};
|
|
2258
1028
|
},
|
|
2259
|
-
|
|
2260
1029
|
_extractCustomPropertyValue: function (customProperty) {
|
|
2261
1030
|
var propValues = [];
|
|
2262
|
-
|
|
1031
|
+
_each(document.querySelectorAll(customProperty['css_selector']), function (matchedElem) {
|
|
2263
1032
|
var value;
|
|
2264
|
-
|
|
2265
1033
|
if (['input', 'select'].indexOf(matchedElem.tagName.toLowerCase()) > -1) {
|
|
2266
1034
|
value = matchedElem['value'];
|
|
2267
|
-
}
|
|
1035
|
+
}
|
|
1036
|
+
else if (matchedElem['textContent']) {
|
|
2268
1037
|
value = matchedElem['textContent'];
|
|
2269
1038
|
}
|
|
2270
|
-
|
|
2271
1039
|
if (shouldCaptureValue(value)) {
|
|
2272
1040
|
propValues.push(value);
|
|
2273
1041
|
}
|
|
2274
1042
|
});
|
|
2275
|
-
return propValues.join(', ')
|
|
1043
|
+
return propValues.join(', ');
|
|
2276
1044
|
},
|
|
2277
|
-
|
|
1045
|
+
// TODO: delete custom_properties after changeless typescript refactor
|
|
2278
1046
|
_getCustomProperties: function (targetElementList) {
|
|
2279
|
-
var
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
function (
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
}
|
|
2293
|
-
},
|
|
2294
|
-
this
|
|
2295
|
-
);
|
|
2296
|
-
},
|
|
2297
|
-
this
|
|
2298
|
-
);
|
|
2299
|
-
},
|
|
2300
|
-
this
|
|
2301
|
-
);
|
|
2302
|
-
return props
|
|
1047
|
+
var _this = this;
|
|
1048
|
+
var props = {}; // will be deleted
|
|
1049
|
+
_each(this._customProperties, function (customProperty) {
|
|
1050
|
+
_each(customProperty['event_selectors'], function (eventSelector) {
|
|
1051
|
+
var eventElements = document.querySelectorAll(eventSelector);
|
|
1052
|
+
_each(eventElements, function (eventElement) {
|
|
1053
|
+
if (_includes(targetElementList, eventElement) && shouldCaptureElement(eventElement)) {
|
|
1054
|
+
props[customProperty['name']] = _this._extractCustomPropertyValue(customProperty);
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
});
|
|
1058
|
+
});
|
|
1059
|
+
return props;
|
|
2303
1060
|
},
|
|
2304
|
-
|
|
2305
1061
|
_getEventTarget: function (e) {
|
|
1062
|
+
var _a;
|
|
2306
1063
|
// https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes
|
|
2307
1064
|
if (typeof e.target === 'undefined') {
|
|
2308
|
-
return e.srcElement
|
|
2309
|
-
}
|
|
2310
|
-
|
|
2311
|
-
|
|
1065
|
+
return e.srcElement || null;
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
if ((_a = e.target) === null || _a === void 0 ? void 0 : _a.shadowRoot) {
|
|
1069
|
+
return e.composedPath()[0] || null;
|
|
2312
1070
|
}
|
|
2313
|
-
return e.target
|
|
1071
|
+
return e.target || null;
|
|
2314
1072
|
}
|
|
2315
1073
|
},
|
|
2316
|
-
|
|
2317
|
-
|
|
1074
|
+
_captureEvent: function (e, instance, opts) {
|
|
1075
|
+
var _this = this;
|
|
1076
|
+
var _a;
|
|
2318
1077
|
/*** Don't mess with this code without running IE8 tests on it ***/
|
|
2319
1078
|
var target = this._getEventTarget(e);
|
|
2320
1079
|
if (isTextNode(target)) {
|
|
2321
1080
|
// defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)
|
|
2322
|
-
target = target.parentNode;
|
|
1081
|
+
target = (target.parentNode || null);
|
|
2323
1082
|
}
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
this.rageclicks.click(e.clientX, e.clientY, new Date().getTime());
|
|
1083
|
+
if (e.type === 'click' && e instanceof MouseEvent) {
|
|
1084
|
+
(_a = this.rageclicks) === null || _a === void 0 ? void 0 : _a.click(e.clientX, e.clientY, new Date().getTime());
|
|
2327
1085
|
}
|
|
2328
|
-
|
|
2329
|
-
if (shouldCaptureDomEvent(target, e)) {
|
|
1086
|
+
if (target && shouldCaptureDomEvent(target, e)) {
|
|
2330
1087
|
var targetElementList = [target];
|
|
2331
1088
|
var curEl = target;
|
|
2332
1089
|
while (curEl.parentNode && !isTag(curEl, 'body')) {
|
|
2333
|
-
if (curEl.parentNode
|
|
1090
|
+
if (isDocumentFragment(curEl.parentNode)) {
|
|
2334
1091
|
targetElementList.push(curEl.parentNode.host);
|
|
2335
1092
|
curEl = curEl.parentNode.host;
|
|
2336
|
-
continue
|
|
1093
|
+
continue;
|
|
2337
1094
|
}
|
|
2338
1095
|
targetElementList.push(curEl.parentNode);
|
|
2339
1096
|
curEl = curEl.parentNode;
|
|
2340
1097
|
}
|
|
2341
|
-
|
|
2342
|
-
var
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
explicitNoCapture = true;
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
|
-
elementsJson.push(
|
|
2364
|
-
this._getPropertiesFromElement(
|
|
2365
|
-
el,
|
|
2366
|
-
instance.get_config('mask_all_element_attributes'),
|
|
2367
|
-
instance.get_config('mask_all_text')
|
|
2368
|
-
)
|
|
2369
|
-
);
|
|
2370
|
-
},
|
|
2371
|
-
this
|
|
2372
|
-
);
|
|
2373
|
-
|
|
2374
|
-
if (!instance.get_config('mask_all_text')) {
|
|
2375
|
-
elementsJson[0]['$el_text'] = getSafeText(target);
|
|
1098
|
+
var elementsJson_1 = [];
|
|
1099
|
+
var href_1, explicitNoCapture_1 = false;
|
|
1100
|
+
_each(targetElementList, function (el) {
|
|
1101
|
+
var shouldCaptureEl = shouldCaptureElement(el);
|
|
1102
|
+
// if the element or a parent element is an anchor tag
|
|
1103
|
+
// include the href as a property
|
|
1104
|
+
if (el.tagName.toLowerCase() === 'a') {
|
|
1105
|
+
href_1 = el.getAttribute('href');
|
|
1106
|
+
href_1 = shouldCaptureEl && shouldCaptureValue(href_1) && href_1;
|
|
1107
|
+
}
|
|
1108
|
+
// allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'
|
|
1109
|
+
var classes = getClassName(el).split(' ');
|
|
1110
|
+
if (_includes(classes, 'ph-no-capture')) {
|
|
1111
|
+
explicitNoCapture_1 = true;
|
|
1112
|
+
}
|
|
1113
|
+
elementsJson_1.push(_this._getPropertiesFromElement(el, opts === null || opts === void 0 ? void 0 : opts.mask_all_element_attributes, opts === null || opts === void 0 ? void 0 : opts.mask_all_text));
|
|
1114
|
+
});
|
|
1115
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.mask_all_text)) {
|
|
1116
|
+
elementsJson_1[0]['$el_text'] = getSafeText(target);
|
|
2376
1117
|
}
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
elementsJson[0]['attr__href'] = href;
|
|
1118
|
+
if (href_1) {
|
|
1119
|
+
elementsJson_1[0]['attr__href'] = href_1;
|
|
2380
1120
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
return false
|
|
1121
|
+
if (explicitNoCapture_1) {
|
|
1122
|
+
return false;
|
|
2384
1123
|
}
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
{
|
|
2389
|
-
$elements: elementsJson,
|
|
2390
|
-
},
|
|
2391
|
-
this._getCustomProperties(targetElementList)
|
|
2392
|
-
);
|
|
2393
|
-
|
|
1124
|
+
var props = _extend(this._getDefaultProperties(e.type), {
|
|
1125
|
+
$elements: elementsJson_1,
|
|
1126
|
+
}, this._getCustomProperties(targetElementList));
|
|
2394
1127
|
instance.capture('$autocapture', props);
|
|
2395
|
-
return true
|
|
1128
|
+
return true;
|
|
2396
1129
|
}
|
|
2397
1130
|
},
|
|
2398
|
-
|
|
2399
1131
|
// only reason is to stub for unit tests
|
|
2400
1132
|
// since you can't override window.location props
|
|
2401
1133
|
_navigate: function (href) {
|
|
2402
1134
|
window.location.href = href;
|
|
2403
1135
|
},
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
var handler =
|
|
1136
|
+
_addDomEventHandlers: function (instance, opts) {
|
|
1137
|
+
var _this = this;
|
|
1138
|
+
var handler = function (e) {
|
|
2407
1139
|
e = e || window.event;
|
|
2408
|
-
|
|
2409
|
-
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
1140
|
+
_this._captureEvent(e, instance, opts);
|
|
1141
|
+
};
|
|
1142
|
+
_register_event(document, 'submit', handler, false, true);
|
|
1143
|
+
_register_event(document, 'change', handler, false, true);
|
|
1144
|
+
_register_event(document, 'click', handler, false, true);
|
|
2413
1145
|
},
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
if (this._initializedTokens.indexOf(token) > -1) {
|
|
2420
|
-
console.log('autocapture already initialized for token "' + token + '"');
|
|
2421
|
-
return
|
|
2422
|
-
}
|
|
2423
|
-
|
|
2424
|
-
this._initializedTokens.push(token);
|
|
2425
|
-
|
|
2426
|
-
if (instance.get_config('autocapture')) {
|
|
2427
|
-
this._addDomEventHandlers(instance);
|
|
2428
|
-
} else {
|
|
2429
|
-
instance['__autocapture_enabled'] = false;
|
|
2430
|
-
}
|
|
2431
|
-
|
|
1146
|
+
_customProperties: [],
|
|
1147
|
+
rageclicks: null,
|
|
1148
|
+
opts: {},
|
|
1149
|
+
init: function (instance, opts) {
|
|
1150
|
+
var _this = this;
|
|
2432
1151
|
this.rageclicks = new RageClick(instance);
|
|
1152
|
+
this.opts = opts;
|
|
1153
|
+
if (!(document && document.body)) {
|
|
1154
|
+
console.log('document not ready yet, trying again in 500 milliseconds...');
|
|
1155
|
+
setTimeout(function () {
|
|
1156
|
+
_this.readyAutocapture(instance, opts);
|
|
1157
|
+
}, 500);
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
this.readyAutocapture(instance, opts);
|
|
1161
|
+
},
|
|
1162
|
+
readyAutocapture: function (instance, opts) {
|
|
1163
|
+
this._addDomEventHandlers(instance, opts);
|
|
2433
1164
|
},
|
|
2434
|
-
|
|
2435
1165
|
// this is a mechanism to ramp up CE with no server-side interaction.
|
|
2436
1166
|
// when CE is active, every page load results in a decide request. we
|
|
2437
1167
|
// need to gently ramp this up so we don't overload decide. this decides
|
|
2438
1168
|
// deterministically if CE is enabled for this project by modding the char
|
|
2439
1169
|
// value of the project token.
|
|
2440
1170
|
enabledForProject: function (token, numBuckets, numEnabledBuckets) {
|
|
2441
|
-
|
|
2442
|
-
|
|
1171
|
+
if (!token) {
|
|
1172
|
+
return true;
|
|
1173
|
+
}
|
|
1174
|
+
numBuckets = !_isUndefined(numBuckets) ? numBuckets : 10;
|
|
1175
|
+
numEnabledBuckets = !_isUndefined(numEnabledBuckets) ? numEnabledBuckets : 10;
|
|
2443
1176
|
var charCodeSum = 0;
|
|
2444
1177
|
for (var i = 0; i < token.length; i++) {
|
|
2445
1178
|
charCodeSum += token.charCodeAt(i);
|
|
2446
1179
|
}
|
|
2447
|
-
return charCodeSum % numBuckets < numEnabledBuckets
|
|
1180
|
+
return charCodeSum % numBuckets < numEnabledBuckets;
|
|
2448
1181
|
},
|
|
2449
|
-
|
|
2450
1182
|
isBrowserSupported: function () {
|
|
2451
|
-
return
|
|
1183
|
+
return _isFunction(document.querySelectorAll);
|
|
2452
1184
|
},
|
|
2453
1185
|
};
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
_.safewrap_instance_methods(autocapture);
|
|
1186
|
+
_bind_instance_methods(autocapture);
|
|
1187
|
+
_safewrap_instance_methods(autocapture);
|
|
2457
1188
|
|
|
2458
1189
|
var VERSION_INFO = {
|
|
2459
1190
|
env: 'production',
|
|
2460
|
-
date: '2022-
|
|
2461
|
-
version: '1.0
|
|
1191
|
+
date: '2022-09-03T13:48:55.501Z',
|
|
1192
|
+
version: '1.1.0'
|
|
2462
1193
|
};
|
|
2463
1194
|
var USERMAVEN_VERSION = "".concat(VERSION_INFO.version, "/").concat(VERSION_INFO.env, "@").concat(VERSION_INFO.date);
|
|
2464
1195
|
var MAX_AGE_TEN_YEARS = 31622400 * 10;
|
|
@@ -2833,6 +1564,14 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2833
1564
|
this.beaconApi = false;
|
|
2834
1565
|
this.transport = xmlHttpTransport;
|
|
2835
1566
|
this.customHeaders = function () { return ({}); };
|
|
1567
|
+
this.queue = new MemoryQueue();
|
|
1568
|
+
this.maxSendAttempts = 4;
|
|
1569
|
+
this.retryTimeout = [500, 1e12];
|
|
1570
|
+
this.flushing = false;
|
|
1571
|
+
this.attempt = 1;
|
|
1572
|
+
this.propertyBlacklist = [];
|
|
1573
|
+
// public persistence?: UserMavenPersistence;
|
|
1574
|
+
// public sessionManager?: SessionIdManager;
|
|
2836
1575
|
this.__autocapture_enabled = false;
|
|
2837
1576
|
}
|
|
2838
1577
|
// private anonymousId: string = '';
|
|
@@ -2887,6 +1626,24 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2887
1626
|
return this.sendJson(e);
|
|
2888
1627
|
};
|
|
2889
1628
|
UsermavenClientImpl.prototype.sendJson = function (json) {
|
|
1629
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
1630
|
+
return __generator(this, function (_a) {
|
|
1631
|
+
switch (_a.label) {
|
|
1632
|
+
case 0:
|
|
1633
|
+
if (!(this.maxSendAttempts > 1)) return [3 /*break*/, 1];
|
|
1634
|
+
this.queue.push([json, 0]);
|
|
1635
|
+
this.scheduleFlush(0);
|
|
1636
|
+
return [3 /*break*/, 3];
|
|
1637
|
+
case 1: return [4 /*yield*/, this.doSendJson(json)];
|
|
1638
|
+
case 2:
|
|
1639
|
+
_a.sent();
|
|
1640
|
+
_a.label = 3;
|
|
1641
|
+
case 3: return [2 /*return*/];
|
|
1642
|
+
}
|
|
1643
|
+
});
|
|
1644
|
+
});
|
|
1645
|
+
};
|
|
1646
|
+
UsermavenClientImpl.prototype.doSendJson = function (json) {
|
|
2890
1647
|
var _this = this;
|
|
2891
1648
|
var cookiePolicy = this.cookiePolicy !== "keep" ? "&cookie_policy=".concat(this.cookiePolicy) : "";
|
|
2892
1649
|
var ipPolicy = this.ipPolicy !== "keep" ? "&ip_policy=".concat(this.ipPolicy) : "";
|
|
@@ -2901,6 +1658,68 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2901
1658
|
return _this.postHandle(code, body);
|
|
2902
1659
|
});
|
|
2903
1660
|
};
|
|
1661
|
+
UsermavenClientImpl.prototype.scheduleFlush = function (timeout) {
|
|
1662
|
+
var _this = this;
|
|
1663
|
+
if (this.flushing) {
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
this.flushing = true;
|
|
1667
|
+
if (typeof timeout === "undefined") {
|
|
1668
|
+
var random = Math.random() + 1;
|
|
1669
|
+
var factor = Math.pow(2, this.attempt++);
|
|
1670
|
+
timeout = Math.min(this.retryTimeout[0] * random * factor, this.retryTimeout[1]);
|
|
1671
|
+
}
|
|
1672
|
+
getLogger().debug("Scheduling event queue flush in ".concat(timeout, " ms."));
|
|
1673
|
+
setTimeout(function () { return _this.flush(); }, timeout);
|
|
1674
|
+
};
|
|
1675
|
+
UsermavenClientImpl.prototype.flush = function () {
|
|
1676
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
1677
|
+
var queue;
|
|
1678
|
+
var _a;
|
|
1679
|
+
var _this = this;
|
|
1680
|
+
return __generator(this, function (_b) {
|
|
1681
|
+
switch (_b.label) {
|
|
1682
|
+
case 0:
|
|
1683
|
+
if (isWindowAvailable() && !window.navigator.onLine) {
|
|
1684
|
+
this.flushing = false;
|
|
1685
|
+
this.scheduleFlush();
|
|
1686
|
+
}
|
|
1687
|
+
queue = this.queue.flush();
|
|
1688
|
+
this.flushing = false;
|
|
1689
|
+
if (queue.length === 0) {
|
|
1690
|
+
return [2 /*return*/];
|
|
1691
|
+
}
|
|
1692
|
+
_b.label = 1;
|
|
1693
|
+
case 1:
|
|
1694
|
+
_b.trys.push([1, 3, , 4]);
|
|
1695
|
+
return [4 /*yield*/, this.doSendJson(queue.map(function (el) { return el[0]; }))];
|
|
1696
|
+
case 2:
|
|
1697
|
+
_b.sent();
|
|
1698
|
+
this.attempt = 1;
|
|
1699
|
+
getLogger().debug("Successfully flushed ".concat(queue.length, " events from queue"));
|
|
1700
|
+
return [3 /*break*/, 4];
|
|
1701
|
+
case 3:
|
|
1702
|
+
_b.sent();
|
|
1703
|
+
queue = queue.map(function (el) { return [el[0], el[1] + 1]; }).filter(function (el) {
|
|
1704
|
+
if (el[1] >= _this.maxSendAttempts) {
|
|
1705
|
+
getLogger().error("Dropping queued event after ".concat(el[1], " attempts since max send attempts ").concat(_this.maxSendAttempts, " reached. See logs for details"));
|
|
1706
|
+
return false;
|
|
1707
|
+
}
|
|
1708
|
+
return true;
|
|
1709
|
+
});
|
|
1710
|
+
if (queue.length > 0) {
|
|
1711
|
+
(_a = this.queue).push.apply(_a, queue);
|
|
1712
|
+
this.scheduleFlush();
|
|
1713
|
+
}
|
|
1714
|
+
else {
|
|
1715
|
+
this.attempt = 1;
|
|
1716
|
+
}
|
|
1717
|
+
return [3 /*break*/, 4];
|
|
1718
|
+
case 4: return [2 /*return*/];
|
|
1719
|
+
}
|
|
1720
|
+
});
|
|
1721
|
+
});
|
|
1722
|
+
};
|
|
2904
1723
|
UsermavenClientImpl.prototype.postHandle = function (status, response) {
|
|
2905
1724
|
if (this.cookiePolicy === "strict" || this.cookiePolicy === "comply") {
|
|
2906
1725
|
if (status === 200) {
|
|
@@ -2946,10 +1765,9 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2946
1765
|
UsermavenClientImpl.prototype.getCtx = function (env) {
|
|
2947
1766
|
var now = new Date();
|
|
2948
1767
|
var props = env.describeClient() || {};
|
|
2949
|
-
var _a = this.sessionManager.getSessionAndWindowId(), session_id = _a.session_id, window_id = _a.window_id;
|
|
2950
1768
|
var company = this.userProperties['company'] || {};
|
|
2951
1769
|
delete this.userProperties['company'];
|
|
2952
|
-
var payload = __assign(__assign({ event_id: "",
|
|
1770
|
+
var payload = __assign(__assign({ event_id: "", user: __assign({ anonymous_id: this.cookiePolicy !== "strict"
|
|
2953
1771
|
? env.getAnonymousId({
|
|
2954
1772
|
name: this.idCookieName,
|
|
2955
1773
|
domain: this.cookieDomain,
|
|
@@ -2983,7 +1801,7 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2983
1801
|
};
|
|
2984
1802
|
UsermavenClientImpl.prototype.init = function (options) {
|
|
2985
1803
|
var _this = this;
|
|
2986
|
-
var _a, _b;
|
|
1804
|
+
var _a, _b, _c, _d;
|
|
2987
1805
|
if (isWindowAvailable() && !options.force_use_fetch) {
|
|
2988
1806
|
if (options.fetch) {
|
|
2989
1807
|
getLogger().warn("Custom fetch implementation is provided to Usermaven. However, it will be ignored since Usermaven runs in browser");
|
|
@@ -3070,21 +1888,17 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3070
1888
|
}
|
|
3071
1889
|
getLogger().debug("Restored persistent properties", this.permanentProperties);
|
|
3072
1890
|
}
|
|
3073
|
-
|
|
1891
|
+
this.propertyBlacklist = options.property_blacklist && options.property_blacklist.length > 0 ? options.property_blacklist : [];
|
|
1892
|
+
// // Added these configuration for session management + autocapture
|
|
3074
1893
|
var defaultConfig = {
|
|
3075
|
-
persistence: 'cookie',
|
|
3076
|
-
persistence_name: 'session',
|
|
3077
1894
|
autocapture: false,
|
|
3078
|
-
capture_pageview: true,
|
|
3079
|
-
store_google: false,
|
|
3080
|
-
save_referrer: false,
|
|
3081
1895
|
properties_string_max_length: null,
|
|
3082
1896
|
property_blacklist: [],
|
|
3083
1897
|
sanitize_properties: null
|
|
3084
1898
|
};
|
|
3085
|
-
this.config =
|
|
1899
|
+
this.config = _extend({}, defaultConfig, options || {}, this.config || {}, { token: this.apiKey });
|
|
3086
1900
|
getLogger().debug('Default Configuration', this.config);
|
|
3087
|
-
this.manageSession(this.config);
|
|
1901
|
+
// this.manageSession(this.config);
|
|
3088
1902
|
this.manageAutoCapture(this.config);
|
|
3089
1903
|
if (options.capture_3rd_party_cookies === false) {
|
|
3090
1904
|
this._3pCookies = {};
|
|
@@ -3104,9 +1918,21 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3104
1918
|
if (options.segment_hook) {
|
|
3105
1919
|
interceptSegmentCalls(this);
|
|
3106
1920
|
}
|
|
1921
|
+
if (isWindowAvailable()) {
|
|
1922
|
+
if (!options.disable_event_persistence) {
|
|
1923
|
+
this.queue = new LocalStorageQueue("jitsu-event-queue");
|
|
1924
|
+
this.scheduleFlush(0);
|
|
1925
|
+
}
|
|
1926
|
+
window.addEventListener("beforeunload", function () { return _this.flush(); });
|
|
1927
|
+
}
|
|
1928
|
+
this.retryTimeout = [
|
|
1929
|
+
(_c = options.min_send_timeout) !== null && _c !== void 0 ? _c : this.retryTimeout[0],
|
|
1930
|
+
(_d = options.max_send_timeout) !== null && _d !== void 0 ? _d : this.retryTimeout[1],
|
|
1931
|
+
];
|
|
1932
|
+
if (!!options.max_send_attempts) {
|
|
1933
|
+
this.maxSendAttempts = options.max_send_attempts;
|
|
1934
|
+
}
|
|
3107
1935
|
this.initialized = true;
|
|
3108
|
-
// Set up the window close event handler "unload"
|
|
3109
|
-
window.addEventListener && window.addEventListener('unload', this._handle_unload.bind(this));
|
|
3110
1936
|
};
|
|
3111
1937
|
UsermavenClientImpl.prototype.interceptAnalytics = function (analytics) {
|
|
3112
1938
|
var _this = this;
|
|
@@ -3186,30 +2012,6 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3186
2012
|
this.propsPersistance.save(this.permanentProperties);
|
|
3187
2013
|
}
|
|
3188
2014
|
};
|
|
3189
|
-
/**
|
|
3190
|
-
* Manage session capability
|
|
3191
|
-
* @param options
|
|
3192
|
-
*/
|
|
3193
|
-
UsermavenClientImpl.prototype.manageSession = function (options) {
|
|
3194
|
-
getLogger().debug('Options', options);
|
|
3195
|
-
options = options || {};
|
|
3196
|
-
getLogger().debug('Options', options);
|
|
3197
|
-
// cross_subdomain_cookie: whether to keep cookie across domains and subdomains
|
|
3198
|
-
var defaultConfig = {
|
|
3199
|
-
persistence: options.persistence || 'cookie',
|
|
3200
|
-
persistence_name: options.persistence_name || 'session',
|
|
3201
|
-
cross_subdomain_cookie: options.cross_subdomain_cookie || true
|
|
3202
|
-
};
|
|
3203
|
-
// TODO: Default session name would be session_
|
|
3204
|
-
this.config = _.extend(defaultConfig, this.config || {}, {
|
|
3205
|
-
token: this.apiKey,
|
|
3206
|
-
});
|
|
3207
|
-
getLogger().debug('Default Configuration', this.config);
|
|
3208
|
-
this.persistence = new UserMavenPersistence(this.config);
|
|
3209
|
-
getLogger().debug('Persistence Configuration', this.persistence);
|
|
3210
|
-
this.sessionManager = new SessionIdManager(this.config, this.persistence);
|
|
3211
|
-
getLogger().debug('Session Configuration', this.sessionManager);
|
|
3212
|
-
};
|
|
3213
2015
|
/**
|
|
3214
2016
|
* Manage auto-capturing
|
|
3215
2017
|
* @param options
|
|
@@ -3224,14 +2026,17 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3224
2026
|
var num_enabled_buckets = 100;
|
|
3225
2027
|
if (!autocapture.enabledForProject(this.apiKey, num_buckets, num_enabled_buckets)) {
|
|
3226
2028
|
this.config['autocapture'] = false;
|
|
2029
|
+
this.__autocapture_enabled = false;
|
|
3227
2030
|
console.log('Not in active bucket: disabling Automatic Event Collection.');
|
|
3228
2031
|
}
|
|
3229
2032
|
else if (!autocapture.isBrowserSupported()) {
|
|
3230
2033
|
this.config['autocapture'] = false;
|
|
2034
|
+
this.__autocapture_enabled = false;
|
|
3231
2035
|
console.log('Disabling Automatic Event Collection because this browser is not supported');
|
|
3232
2036
|
}
|
|
3233
2037
|
else {
|
|
3234
|
-
|
|
2038
|
+
console.log('Autocapture enabled...');
|
|
2039
|
+
autocapture.init(this, options);
|
|
3235
2040
|
}
|
|
3236
2041
|
};
|
|
3237
2042
|
/**
|
|
@@ -3239,12 +2044,7 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3239
2044
|
* frequently used usermaven function.
|
|
3240
2045
|
*
|
|
3241
2046
|
* ### Usage:
|
|
3242
|
-
*
|
|
3243
|
-
* // capture an event named 'Registered'
|
|
3244
|
-
* usermaven.capture('Registered', {'Gender': 'Male', 'Age': 21});
|
|
3245
|
-
*
|
|
3246
|
-
* // capture an event using navigator.sendBeacon
|
|
3247
|
-
* usermaven.capture('Left page', {'duration_seconds': 35}, {transport: 'sendBeacon'});
|
|
2047
|
+
* usermaven.capture('Registered', {'Gender': 'Male', 'Age': 21}, {});
|
|
3248
2048
|
*
|
|
3249
2049
|
* @param {String} event_name The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', 'Item Purchased', etc.
|
|
3250
2050
|
* @param {Object} [properties] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
@@ -3258,63 +2058,39 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3258
2058
|
console.error('Trying to capture event before initialization');
|
|
3259
2059
|
return;
|
|
3260
2060
|
}
|
|
3261
|
-
|
|
3262
|
-
|
|
2061
|
+
console.log(properties);
|
|
2062
|
+
if (_isUndefined(event_name) || typeof event_name !== 'string') {
|
|
2063
|
+
console.error('No event name provided to usermaven.capture');
|
|
3263
2064
|
return;
|
|
3264
2065
|
}
|
|
3265
|
-
if (_.isBlockedUA(userAgent)) {
|
|
3266
|
-
|
|
3267
|
-
}
|
|
3268
|
-
var start_timestamp = this['persistence'].remove_event_timer(event_name);
|
|
3269
|
-
// update persistence
|
|
3270
|
-
this['persistence'].update_search_keyword(document.referrer);
|
|
3271
|
-
if (this.get_config('store_google')) {
|
|
3272
|
-
this['persistence'].update_campaign_params();
|
|
3273
|
-
}
|
|
3274
|
-
if (this.get_config('save_referrer')) {
|
|
3275
|
-
this['persistence'].update_referrer_info(document.referrer);
|
|
3276
|
-
}
|
|
2066
|
+
// if (_.isBlockedUA(userAgent)) {
|
|
2067
|
+
// return
|
|
2068
|
+
// }
|
|
3277
2069
|
var data = {
|
|
3278
2070
|
event: event_name + (properties['$event_type'] ? '_' + properties['$event_type'] : ''),
|
|
3279
|
-
properties: this._calculate_event_properties(event_name, properties
|
|
2071
|
+
properties: this._calculate_event_properties(event_name, properties),
|
|
3280
2072
|
};
|
|
3281
|
-
data =
|
|
3282
|
-
// send
|
|
2073
|
+
data = _copyAndTruncateStrings(data, this.get_config('properties_string_max_length'));
|
|
2074
|
+
// send event if there is a tagname available
|
|
3283
2075
|
if ((_b = (_a = data.properties) === null || _a === void 0 ? void 0 : _a.autocapture_attributes) === null || _b === void 0 ? void 0 : _b.tag_name) {
|
|
3284
2076
|
this.track("$autocapture", data.properties);
|
|
3285
2077
|
// this.track(data.event, data.properties)
|
|
3286
2078
|
}
|
|
3287
2079
|
};
|
|
3288
|
-
UsermavenClientImpl.prototype._calculate_event_properties = function (event_name, event_properties
|
|
2080
|
+
UsermavenClientImpl.prototype._calculate_event_properties = function (event_name, event_properties) {
|
|
3289
2081
|
var _a, _b;
|
|
3290
2082
|
// set defaults
|
|
3291
2083
|
var properties = event_properties || {};
|
|
3292
2084
|
if (event_name === '$snapshot') {
|
|
3293
2085
|
return properties;
|
|
3294
2086
|
}
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
var duration_in_ms = new Date().getTime() - start_timestamp;
|
|
3298
|
-
properties['$duration'] = parseFloat((duration_in_ms / 1000).toFixed(3));
|
|
3299
|
-
}
|
|
3300
|
-
// note: extend writes to the first object, so lets make sure we
|
|
3301
|
-
// don't write to the persistence properties object and info
|
|
3302
|
-
// properties object by passing in a new object
|
|
3303
|
-
// update properties with pageview info and super-properties
|
|
3304
|
-
// exlude , _.info.properties()
|
|
3305
|
-
properties = _.extend({}, this['persistence'].properties(), properties);
|
|
3306
|
-
var property_blacklist = this.get_config('property_blacklist');
|
|
3307
|
-
if (_.isArray(property_blacklist)) {
|
|
3308
|
-
_.each(property_blacklist, function (blacklisted_prop) {
|
|
2087
|
+
if (_isArray(this.propertyBlacklist)) {
|
|
2088
|
+
_each(this.propertyBlacklist, function (blacklisted_prop) {
|
|
3309
2089
|
delete properties[blacklisted_prop];
|
|
3310
2090
|
});
|
|
3311
2091
|
}
|
|
3312
2092
|
else {
|
|
3313
|
-
console.error('Invalid value for property_blacklist config: ' +
|
|
3314
|
-
}
|
|
3315
|
-
var sanitize_properties = this.get_config('sanitize_properties');
|
|
3316
|
-
if (sanitize_properties) {
|
|
3317
|
-
properties = sanitize_properties(properties, event_name);
|
|
2093
|
+
console.error('Invalid value for property_blacklist config: ' + this.propertyBlacklist);
|
|
3318
2094
|
}
|
|
3319
2095
|
// assign first element from $elements only
|
|
3320
2096
|
var attributes = {};
|
|
@@ -3325,24 +2101,15 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3325
2101
|
properties['autocapture_attributes'] = attributes;
|
|
3326
2102
|
properties['autocapture_attributes']["el_text"] = (_a = properties['autocapture_attributes']["$el_text"]) !== null && _a !== void 0 ? _a : "";
|
|
3327
2103
|
properties['autocapture_attributes']["event_type"] = (_b = properties["$event_type"]) !== null && _b !== void 0 ? _b : "";
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
delete properties['$initial_referring_domain'];
|
|
3332
|
-
delete properties['$referrer'];
|
|
3333
|
-
delete properties['$referring_domain'];
|
|
3334
|
-
delete properties['$elements'];
|
|
2104
|
+
['$ce_version', "$event_type", "$initial_referrer", "$initial_referring_domain", "$referrer", "$referring_domain", "$elements"].forEach(function (key) {
|
|
2105
|
+
delete properties[key];
|
|
2106
|
+
});
|
|
3335
2107
|
// TODO: later remove this from the autotrack code.
|
|
3336
2108
|
delete properties['autocapture_attributes']["$el_text"];
|
|
3337
2109
|
delete properties['autocapture_attributes']["nth_child"];
|
|
3338
2110
|
delete properties['autocapture_attributes']["nth_of_type"];
|
|
3339
2111
|
return properties;
|
|
3340
2112
|
};
|
|
3341
|
-
UsermavenClientImpl.prototype._handle_unload = function () {
|
|
3342
|
-
if (this.get_config('capture_pageview')) {
|
|
3343
|
-
this.capture('$pageleave');
|
|
3344
|
-
}
|
|
3345
|
-
};
|
|
3346
2113
|
return UsermavenClientImpl;
|
|
3347
2114
|
}());
|
|
3348
2115
|
function interceptSegmentCalls(t) {
|