@usermaven/sdk-js 1.0.8 → 1.1.1

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