You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flagon.apache.org by po...@apache.org on 2019/12/15 06:17:52 UTC

[incubator-flagon-useralejs] branch FLAGON-469 updated: [FLAGON-475] added browser type and version to logs, and new customIndex config key:value

This is an automated email from the ASF dual-hosted git repository.

poorejc pushed a commit to branch FLAGON-469
in repository https://gitbox.apache.org/repos/asf/incubator-flagon-useralejs.git


The following commit(s) were added to refs/heads/FLAGON-469 by this push:
     new 22d1aba  [FLAGON-475] added browser type and version to logs, and new customIndex config key:value
22d1aba is described below

commit 22d1aba736f1104b3afe02dd05ff229e333cb3ad
Author: poorejc <po...@apache.org>
AuthorDate: Sun Dec 15 01:17:32 2019 -0500

    [FLAGON-475] added browser type and version to logs, and new customIndex config key:value
---
 build/UserAleWebExtension/background.js | 220 ++++++++++++++++++++++++++++++--
 build/UserAleWebExtension/content.js    | 212 +++++++++++++++++++++++++++++-
 build/userale-2.0.2.js                  | 205 ++++++++++++++++++++++++++++-
 build/userale-2.0.2.min.js              |   2 +-
 gulpfile.js                             |  20 ++-
 package-lock.json                       | 187 +++++++++++++++++++++++----
 package.json                            |  17 ++-
 src/getInitialSettings.js               |   2 +-
 src/packageLogs.js                      |  12 +-
 test/main_spec.js                       |   1 +
 10 files changed, 820 insertions(+), 58 deletions(-)

diff --git a/build/UserAleWebExtension/background.js b/build/UserAleWebExtension/background.js
index 44af556..288c3df 100644
--- a/build/UserAleWebExtension/background.js
+++ b/build/UserAleWebExtension/background.js
@@ -102,6 +102,199 @@ function timeStampScale(e) {
   return tsScaler;
 }
 
+var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+function unwrapExports (x) {
+	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
+}
+
+function createCommonjsModule(fn, module) {
+	return module = { exports: {} }, fn(module, module.exports), module.exports;
+}
+
+var detectBrowser = createCommonjsModule(function (module, exports) {
+var __spreadArrays = (commonjsGlobal && commonjsGlobal.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var BrowserInfo = /** @class */ (function () {
+    function BrowserInfo(name, version, os) {
+        this.name = name;
+        this.version = version;
+        this.os = os;
+    }
+    return BrowserInfo;
+}());
+exports.BrowserInfo = BrowserInfo;
+var NodeInfo = /** @class */ (function () {
+    function NodeInfo(version) {
+        this.version = version;
+        this.name = 'node';
+        this.os = process.platform;
+    }
+    return NodeInfo;
+}());
+exports.NodeInfo = NodeInfo;
+var BotInfo = /** @class */ (function () {
+    function BotInfo() {
+        this.bot = true; // NOTE: deprecated test name instead
+        this.name = 'bot';
+        this.version = null;
+        this.os = null;
+    }
+    return BotInfo;
+}());
+exports.BotInfo = BotInfo;
+// tslint:disable-next-line:max-line-length
+var SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/;
+var SEARCHBOT_OS_REGEX = /(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/;
+var REQUIRED_VERSION_PARTS = 3;
+var userAgentRules = [
+    ['aol', /AOLShield\/([0-9\._]+)/],
+    ['edge', /Edge\/([0-9\._]+)/],
+    ['edge-ios', /EdgiOS\/([0-9\._]+)/],
+    ['yandexbrowser', /YaBrowser\/([0-9\._]+)/],
+    ['vivaldi', /Vivaldi\/([0-9\.]+)/],
+    ['kakaotalk', /KAKAOTALK\s([0-9\.]+)/],
+    ['samsung', /SamsungBrowser\/([0-9\.]+)/],
+    ['silk', /\bSilk\/([0-9._-]+)\b/],
+    ['miui', /MiuiBrowser\/([0-9\.]+)$/],
+    ['beaker', /BeakerBrowser\/([0-9\.]+)/],
+    ['edge-chromium', /Edg\/([0-9\.]+)/],
+    [
+        'chromium-webview',
+        /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/,
+    ],
+    ['chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
+    ['phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/],
+    ['crios', /CriOS\/([0-9\.]+)(:?\s|$)/],
+    ['firefox', /Firefox\/([0-9\.]+)(?:\s|$)/],
+    ['fxios', /FxiOS\/([0-9\.]+)/],
+    ['opera-mini', /Opera Mini.*Version\/([0-9\.]+)/],
+    ['opera', /Opera\/([0-9\.]+)(?:\s|$)/],
+    ['opera', /OPR\/([0-9\.]+)(:?\s|$)/],
+    ['ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
+    ['ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
+    ['ie', /MSIE\s(7\.0)/],
+    ['bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/],
+    ['android', /Android\s([0-9\.]+)/],
+    ['ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/],
+    ['safari', /Version\/([0-9\._]+).*Safari/],
+    ['facebook', /FBAV\/([0-9\.]+)/],
+    ['instagram', /Instagram\s([0-9\.]+)/],
+    ['ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/],
+    ['ios-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
+    ['searchbot', SEARCHBOX_UA_REGEX],
+];
+var operatingSystemRules = [
+    ['iOS', /iP(hone|od|ad)/],
+    ['Android OS', /Android/],
+    ['BlackBerry OS', /BlackBerry|BB10/],
+    ['Windows Mobile', /IEMobile/],
+    ['Amazon OS', /Kindle/],
+    ['Windows 3.11', /Win16/],
+    ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/],
+    ['Windows 98', /(Windows 98)|(Win98)/],
+    ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/],
+    ['Windows XP', /(Windows NT 5.1)|(Windows XP)/],
+    ['Windows Server 2003', /(Windows NT 5.2)/],
+    ['Windows Vista', /(Windows NT 6.0)/],
+    ['Windows 7', /(Windows NT 6.1)/],
+    ['Windows 8', /(Windows NT 6.2)/],
+    ['Windows 8.1', /(Windows NT 6.3)/],
+    ['Windows 10', /(Windows NT 10.0)/],
+    ['Windows ME', /Windows ME/],
+    ['Open BSD', /OpenBSD/],
+    ['Sun OS', /SunOS/],
+    ['Chrome OS', /CrOS/],
+    ['Linux', /(Linux)|(X11)/],
+    ['Mac OS', /(Mac_PowerPC)|(Macintosh)/],
+    ['QNX', /QNX/],
+    ['BeOS', /BeOS/],
+    ['OS/2', /OS\/2/],
+    ['Search Bot', SEARCHBOT_OS_REGEX],
+];
+function detect(userAgent) {
+    if (!!userAgent) {
+        return parseUserAgent(userAgent);
+    }
+    if (typeof navigator !== 'undefined') {
+        return parseUserAgent(navigator.userAgent);
+    }
+    return getNodeVersion();
+}
+exports.detect = detect;
+function parseUserAgent(ua) {
+    // opted for using reduce here rather than Array#first with a regex.test call
+    // this is primarily because using the reduce we only perform the regex
+    // execution once rather than once for the test and for the exec again below
+    // probably something that needs to be benchmarked though
+    var matchedRule = ua !== '' &&
+        userAgentRules.reduce(function (matched, _a) {
+            var browser = _a[0], regex = _a[1];
+            if (matched) {
+                return matched;
+            }
+            var uaMatch = regex.exec(ua);
+            return !!uaMatch && [browser, uaMatch];
+        }, false);
+    if (!matchedRule) {
+        return null;
+    }
+    var name = matchedRule[0], match = matchedRule[1];
+    if (name === 'searchbot') {
+        return new BotInfo();
+    }
+    var versionParts = match[1] && match[1].split(/[._]/).slice(0, 3);
+    if (versionParts) {
+        if (versionParts.length < REQUIRED_VERSION_PARTS) {
+            versionParts = __spreadArrays(versionParts, createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length));
+        }
+    }
+    else {
+        versionParts = [];
+    }
+    return new BrowserInfo(name, versionParts.join('.'), detectOS(ua));
+}
+exports.parseUserAgent = parseUserAgent;
+function detectOS(ua) {
+    for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) {
+        var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1];
+        var match = regex.test(ua);
+        if (match) {
+            return os;
+        }
+    }
+    return null;
+}
+exports.detectOS = detectOS;
+function getNodeVersion() {
+    var isNode = typeof process !== 'undefined' && process.version;
+    return isNode ? new NodeInfo(process.version.slice(1)) : null;
+}
+exports.getNodeVersion = getNodeVersion;
+function createVersionParts(count) {
+    var output = [];
+    for (var ii = 0; ii < count; ii++) {
+        output.push('0');
+    }
+    return output;
+}
+});
+
+unwrapExports(detectBrowser);
+var detectBrowser_1 = detectBrowser.BrowserInfo;
+var detectBrowser_2 = detectBrowser.NodeInfo;
+var detectBrowser_3 = detectBrowser.BotInfo;
+var detectBrowser_4 = detectBrowser.detect;
+var detectBrowser_5 = detectBrowser.parseUserAgent;
+var detectBrowser_6 = detectBrowser.detectOS;
+var detectBrowser_7 = detectBrowser.getNodeVersion;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -118,6 +311,7 @@ function timeStampScale(e) {
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+var browser = detectBrowser_4();
 
 /**
  * Extract the millisecond and microsecond portions of a timestamp.
@@ -264,7 +458,7 @@ function sendLogs(logs, config, retries) {
 // the 'chrome' global instead. Let's map it to browser so we don't have
 // to have if-conditions all over the place.
 
-var browser = browser || chrome;
+var browser$1 = browser$1 || chrome;
 var logs = [];
 var config = {
   autostart: true,
@@ -283,9 +477,9 @@ var getTimestamp = ((typeof performance !== 'undefined') && (typeof performance.
   ? function () { return performance.now() + performance.timing.navigationStart; }
   : Date.now;
 
-browser.storage.local.set({ sessionId: sessionId });
+browser$1.storage.local.set({ sessionId: sessionId });
 
-var store = browser.storage.local.get({
+var store = browser$1.storage.local.get({
   userAleHost: userAleHost,
   userAleScript: userAleScript,
   toolUser: toolUser,
@@ -305,9 +499,9 @@ function storeCallback(item) {
 }
 
 function dispatchTabMessage(message) {
-  browser.tabs.query({}, function (tabs) {
+  browser$1.tabs.query({}, function (tabs) {
     tabs.forEach(function (tab) {
-      browser.tabs.sendMessage(tab.id, message);
+      browser$1.tabs.sendMessage(tab.id, message);
     });
   });
 }
@@ -333,7 +527,7 @@ function packageBrowserLog(type, logDetail) {
   });
 }
 
-browser.runtime.onMessage.addListener(function (message) {
+browser$1.runtime.onMessage.addListener(function (message) {
   switch (message.type) {
     case CONFIG_CHANGE:
       (function () {
@@ -360,7 +554,7 @@ browser.runtime.onMessage.addListener(function (message) {
 });
 
 function getTabDetailById(tabId, onReady) {
-  browser.tabs.get(tabId, function (tab) {
+  browser$1.tabs.get(tabId, function (tab) {
     onReady({
       active: tab.active,
       audible: tab.audible,
@@ -377,13 +571,13 @@ function getTabDetailById(tabId, onReady) {
   });
 }
 
-browser.tabs.onActivated.addListener(function (e) {
+browser$1.tabs.onActivated.addListener(function (e) {
   getTabDetailById(e.tabId, function (detail) {
     packageBrowserLog('tabs.onActivated', detail);
   });
 });
 
-browser.tabs.onCreated.addListener(function (tab, e) {
+browser$1.tabs.onCreated.addListener(function (tab, e) {
   packageBrowserLog('tabs.onCreated', {
     active: tab.active,
     audible: tab.audible,
@@ -399,23 +593,23 @@ browser.tabs.onCreated.addListener(function (tab, e) {
   });
 });
 
-browser.tabs.onDetached.addListener(function (tabId) {
+browser$1.tabs.onDetached.addListener(function (tabId) {
   getTabDetailById(tabId, function (detail) {
     packageBrowserLog('tabs.onDetached', detail);
   });
 });
 
-browser.tabs.onMoved.addListener(function (tabId) {
+browser$1.tabs.onMoved.addListener(function (tabId) {
   getTabDetailById(tabId, function (detail) {
     packageBrowserLog('tabs.onMoved', detail);
   });
 });
 
-browser.tabs.onRemoved.addListener(function (tabId) {
+browser$1.tabs.onRemoved.addListener(function (tabId) {
   packageBrowserLog('tabs.onRemoved', { tabId: tabId });
 });
 
-browser.tabs.onZoomChange.addListener(function (e) {
+browser$1.tabs.onZoomChange.addListener(function (e) {
   getTabDetailById(e.tabId, function (detail) {
     packageBrowserLog('tabs.onZoomChange', Object.assign({}, {
       oldZoomFactor: e.oldZoomFactor,
diff --git a/build/UserAleWebExtension/content.js b/build/UserAleWebExtension/content.js
index 24fd407..2ce13ba 100644
--- a/build/UserAleWebExtension/content.js
+++ b/build/UserAleWebExtension/content.js
@@ -100,7 +100,7 @@ function getInitialSettings() {
   settings.time = timeStampScale(document.createEvent('CustomEvent'));
   settings.sessionID = get('data-session') || sessionId;
   settings.authHeader = get ('data-auth') || null;
-
+  settings.custIndex = get ('data-index') || null;
   return settings;
 }
 
@@ -208,6 +208,199 @@ function getUserIdFromParams(param) {
   }
 }
 
+var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+function unwrapExports (x) {
+	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
+}
+
+function createCommonjsModule(fn, module) {
+	return module = { exports: {} }, fn(module, module.exports), module.exports;
+}
+
+var detectBrowser = createCommonjsModule(function (module, exports) {
+var __spreadArrays = (commonjsGlobal && commonjsGlobal.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var BrowserInfo = /** @class */ (function () {
+    function BrowserInfo(name, version, os) {
+        this.name = name;
+        this.version = version;
+        this.os = os;
+    }
+    return BrowserInfo;
+}());
+exports.BrowserInfo = BrowserInfo;
+var NodeInfo = /** @class */ (function () {
+    function NodeInfo(version) {
+        this.version = version;
+        this.name = 'node';
+        this.os = process.platform;
+    }
+    return NodeInfo;
+}());
+exports.NodeInfo = NodeInfo;
+var BotInfo = /** @class */ (function () {
+    function BotInfo() {
+        this.bot = true; // NOTE: deprecated test name instead
+        this.name = 'bot';
+        this.version = null;
+        this.os = null;
+    }
+    return BotInfo;
+}());
+exports.BotInfo = BotInfo;
+// tslint:disable-next-line:max-line-length
+var SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/;
+var SEARCHBOT_OS_REGEX = /(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/;
+var REQUIRED_VERSION_PARTS = 3;
+var userAgentRules = [
+    ['aol', /AOLShield\/([0-9\._]+)/],
+    ['edge', /Edge\/([0-9\._]+)/],
+    ['edge-ios', /EdgiOS\/([0-9\._]+)/],
+    ['yandexbrowser', /YaBrowser\/([0-9\._]+)/],
+    ['vivaldi', /Vivaldi\/([0-9\.]+)/],
+    ['kakaotalk', /KAKAOTALK\s([0-9\.]+)/],
+    ['samsung', /SamsungBrowser\/([0-9\.]+)/],
+    ['silk', /\bSilk\/([0-9._-]+)\b/],
+    ['miui', /MiuiBrowser\/([0-9\.]+)$/],
+    ['beaker', /BeakerBrowser\/([0-9\.]+)/],
+    ['edge-chromium', /Edg\/([0-9\.]+)/],
+    [
+        'chromium-webview',
+        /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/,
+    ],
+    ['chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
+    ['phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/],
+    ['crios', /CriOS\/([0-9\.]+)(:?\s|$)/],
+    ['firefox', /Firefox\/([0-9\.]+)(?:\s|$)/],
+    ['fxios', /FxiOS\/([0-9\.]+)/],
+    ['opera-mini', /Opera Mini.*Version\/([0-9\.]+)/],
+    ['opera', /Opera\/([0-9\.]+)(?:\s|$)/],
+    ['opera', /OPR\/([0-9\.]+)(:?\s|$)/],
+    ['ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
+    ['ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
+    ['ie', /MSIE\s(7\.0)/],
+    ['bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/],
+    ['android', /Android\s([0-9\.]+)/],
+    ['ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/],
+    ['safari', /Version\/([0-9\._]+).*Safari/],
+    ['facebook', /FBAV\/([0-9\.]+)/],
+    ['instagram', /Instagram\s([0-9\.]+)/],
+    ['ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/],
+    ['ios-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
+    ['searchbot', SEARCHBOX_UA_REGEX],
+];
+var operatingSystemRules = [
+    ['iOS', /iP(hone|od|ad)/],
+    ['Android OS', /Android/],
+    ['BlackBerry OS', /BlackBerry|BB10/],
+    ['Windows Mobile', /IEMobile/],
+    ['Amazon OS', /Kindle/],
+    ['Windows 3.11', /Win16/],
+    ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/],
+    ['Windows 98', /(Windows 98)|(Win98)/],
+    ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/],
+    ['Windows XP', /(Windows NT 5.1)|(Windows XP)/],
+    ['Windows Server 2003', /(Windows NT 5.2)/],
+    ['Windows Vista', /(Windows NT 6.0)/],
+    ['Windows 7', /(Windows NT 6.1)/],
+    ['Windows 8', /(Windows NT 6.2)/],
+    ['Windows 8.1', /(Windows NT 6.3)/],
+    ['Windows 10', /(Windows NT 10.0)/],
+    ['Windows ME', /Windows ME/],
+    ['Open BSD', /OpenBSD/],
+    ['Sun OS', /SunOS/],
+    ['Chrome OS', /CrOS/],
+    ['Linux', /(Linux)|(X11)/],
+    ['Mac OS', /(Mac_PowerPC)|(Macintosh)/],
+    ['QNX', /QNX/],
+    ['BeOS', /BeOS/],
+    ['OS/2', /OS\/2/],
+    ['Search Bot', SEARCHBOT_OS_REGEX],
+];
+function detect(userAgent) {
+    if (!!userAgent) {
+        return parseUserAgent(userAgent);
+    }
+    if (typeof navigator !== 'undefined') {
+        return parseUserAgent(navigator.userAgent);
+    }
+    return getNodeVersion();
+}
+exports.detect = detect;
+function parseUserAgent(ua) {
+    // opted for using reduce here rather than Array#first with a regex.test call
+    // this is primarily because using the reduce we only perform the regex
+    // execution once rather than once for the test and for the exec again below
+    // probably something that needs to be benchmarked though
+    var matchedRule = ua !== '' &&
+        userAgentRules.reduce(function (matched, _a) {
+            var browser = _a[0], regex = _a[1];
+            if (matched) {
+                return matched;
+            }
+            var uaMatch = regex.exec(ua);
+            return !!uaMatch && [browser, uaMatch];
+        }, false);
+    if (!matchedRule) {
+        return null;
+    }
+    var name = matchedRule[0], match = matchedRule[1];
+    if (name === 'searchbot') {
+        return new BotInfo();
+    }
+    var versionParts = match[1] && match[1].split(/[._]/).slice(0, 3);
+    if (versionParts) {
+        if (versionParts.length < REQUIRED_VERSION_PARTS) {
+            versionParts = __spreadArrays(versionParts, createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length));
+        }
+    }
+    else {
+        versionParts = [];
+    }
+    return new BrowserInfo(name, versionParts.join('.'), detectOS(ua));
+}
+exports.parseUserAgent = parseUserAgent;
+function detectOS(ua) {
+    for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) {
+        var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1];
+        var match = regex.test(ua);
+        if (match) {
+            return os;
+        }
+    }
+    return null;
+}
+exports.detectOS = detectOS;
+function getNodeVersion() {
+    var isNode = typeof process !== 'undefined' && process.version;
+    return isNode ? new NodeInfo(process.version.slice(1)) : null;
+}
+exports.getNodeVersion = getNodeVersion;
+function createVersionParts(count) {
+    var output = [];
+    for (var ii = 0; ii < count; ii++) {
+        output.push('0');
+    }
+    return output;
+}
+});
+
+unwrapExports(detectBrowser);
+var detectBrowser_1 = detectBrowser.BrowserInfo;
+var detectBrowser_2 = detectBrowser.NodeInfo;
+var detectBrowser_3 = detectBrowser.BotInfo;
+var detectBrowser_4 = detectBrowser.detect;
+var detectBrowser_5 = detectBrowser.parseUserAgent;
+var detectBrowser_6 = detectBrowser.detectOS;
+var detectBrowser_7 = detectBrowser.getNodeVersion;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -224,6 +417,7 @@ function getUserIdFromParams(param) {
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+var browser = detectBrowser_4();
 
 var logs;
 var config;
@@ -292,6 +486,7 @@ function packageLog(e, detailFcn) {
     'pageUrl': window.location.href,
     'pageTitle': document.title,
     'pageReferrer': document.referrer,
+    'browser': detectBrowser$1(),
     'clientTime' : timeFields.milli,
     'microTime' : timeFields.micro,
     'location' : getLocation(e),
@@ -362,6 +557,7 @@ function packageIntervalLog(e) {
             'pageUrl': window.location.href,
             'pageTitle': document.title,
             'pageReferrer': document.referrer,
+            'browser': detectBrowser$1(),
             'count': intervalCounter,
             'duration': timestamp - intervalTimer,  // microseconds
             'startTime': intervalTimer,
@@ -383,7 +579,7 @@ function packageIntervalLog(e) {
         }
 
         if (typeof mapHandler === 'function') {
-          intervalLog = mapHandler(intervalLog);
+          intervalLog = mapHandler(intervalLog, e);
         }
 
         logs.push(intervalLog);
@@ -473,6 +669,10 @@ function selectorizePath(path) {
   return pathSelectors;
 }
 
+function detectBrowser$1() {
+    return {'browser': browser.name, 'version': browser.version};
+}
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -816,11 +1016,11 @@ function options(newConfig) {
 // the 'chrome' global instead. Let's map it to browser so we don't have
 // to have if-conditions all over the place.
 
-var browser = browser || chrome;
+var browser$1 = browser$1 || chrome;
 
 // creates a Future for retrieval of the named keys
 // the value specified is the default value if one doesn't exist in the storage
-let store = browser.storage.local.get({
+let store = browser$1.storage.local.get({
   sessionId: null,
   userAleHost: userAleHost,
   userAleScript: userAleScript,
@@ -840,7 +1040,7 @@ function storeCallback(item) {
 }
 
 function queueLog(log) {
-  browser.runtime.sendMessage({ type: ADD_LOG, payload: log });
+  browser$1.runtime.sendMessage({ type: ADD_LOG, payload: log });
 }
 
 function injectScript(config) {
@@ -854,7 +1054,7 @@ function injectScript(config) {
   });
 }
 
-browser.runtime.onMessage.addListener(function (message) {
+browser$1.runtime.onMessage.addListener(function (message) {
   if (message.type === CONFIG_CHANGE) {
     options({
       url: message.payload.userAleHost,
diff --git a/build/userale-2.0.2.js b/build/userale-2.0.2.js
index 033412a..0bdd463 100644
--- a/build/userale-2.0.2.js
+++ b/build/userale-2.0.2.js
@@ -71,7 +71,7 @@ var userale = (function (exports) {
     settings.time = timeStampScale(document.createEvent('CustomEvent'));
     settings.sessionID = get('data-session') || sessionId;
     settings.authHeader = get ('data-auth') || null;
-
+    settings.custIndex = get ('data-index') || null;
     return settings;
   }
 
@@ -179,6 +179,199 @@ var userale = (function (exports) {
     }
   }
 
+  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+  function unwrapExports (x) {
+  	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
+  }
+
+  function createCommonjsModule(fn, module) {
+  	return module = { exports: {} }, fn(module, module.exports), module.exports;
+  }
+
+  var detectBrowser = createCommonjsModule(function (module, exports) {
+  var __spreadArrays = (commonjsGlobal && commonjsGlobal.__spreadArrays) || function () {
+      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+      for (var r = Array(s), k = 0, i = 0; i < il; i++)
+          for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+              r[k] = a[j];
+      return r;
+  };
+  Object.defineProperty(exports, "__esModule", { value: true });
+  var BrowserInfo = /** @class */ (function () {
+      function BrowserInfo(name, version, os) {
+          this.name = name;
+          this.version = version;
+          this.os = os;
+      }
+      return BrowserInfo;
+  }());
+  exports.BrowserInfo = BrowserInfo;
+  var NodeInfo = /** @class */ (function () {
+      function NodeInfo(version) {
+          this.version = version;
+          this.name = 'node';
+          this.os = process.platform;
+      }
+      return NodeInfo;
+  }());
+  exports.NodeInfo = NodeInfo;
+  var BotInfo = /** @class */ (function () {
+      function BotInfo() {
+          this.bot = true; // NOTE: deprecated test name instead
+          this.name = 'bot';
+          this.version = null;
+          this.os = null;
+      }
+      return BotInfo;
+  }());
+  exports.BotInfo = BotInfo;
+  // tslint:disable-next-line:max-line-length
+  var SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/;
+  var SEARCHBOT_OS_REGEX = /(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/;
+  var REQUIRED_VERSION_PARTS = 3;
+  var userAgentRules = [
+      ['aol', /AOLShield\/([0-9\._]+)/],
+      ['edge', /Edge\/([0-9\._]+)/],
+      ['edge-ios', /EdgiOS\/([0-9\._]+)/],
+      ['yandexbrowser', /YaBrowser\/([0-9\._]+)/],
+      ['vivaldi', /Vivaldi\/([0-9\.]+)/],
+      ['kakaotalk', /KAKAOTALK\s([0-9\.]+)/],
+      ['samsung', /SamsungBrowser\/([0-9\.]+)/],
+      ['silk', /\bSilk\/([0-9._-]+)\b/],
+      ['miui', /MiuiBrowser\/([0-9\.]+)$/],
+      ['beaker', /BeakerBrowser\/([0-9\.]+)/],
+      ['edge-chromium', /Edg\/([0-9\.]+)/],
+      [
+          'chromium-webview',
+          /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/,
+      ],
+      ['chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
+      ['phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/],
+      ['crios', /CriOS\/([0-9\.]+)(:?\s|$)/],
+      ['firefox', /Firefox\/([0-9\.]+)(?:\s|$)/],
+      ['fxios', /FxiOS\/([0-9\.]+)/],
+      ['opera-mini', /Opera Mini.*Version\/([0-9\.]+)/],
+      ['opera', /Opera\/([0-9\.]+)(?:\s|$)/],
+      ['opera', /OPR\/([0-9\.]+)(:?\s|$)/],
+      ['ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
+      ['ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
+      ['ie', /MSIE\s(7\.0)/],
+      ['bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/],
+      ['android', /Android\s([0-9\.]+)/],
+      ['ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/],
+      ['safari', /Version\/([0-9\._]+).*Safari/],
+      ['facebook', /FBAV\/([0-9\.]+)/],
+      ['instagram', /Instagram\s([0-9\.]+)/],
+      ['ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/],
+      ['ios-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
+      ['searchbot', SEARCHBOX_UA_REGEX],
+  ];
+  var operatingSystemRules = [
+      ['iOS', /iP(hone|od|ad)/],
+      ['Android OS', /Android/],
+      ['BlackBerry OS', /BlackBerry|BB10/],
+      ['Windows Mobile', /IEMobile/],
+      ['Amazon OS', /Kindle/],
+      ['Windows 3.11', /Win16/],
+      ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/],
+      ['Windows 98', /(Windows 98)|(Win98)/],
+      ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/],
+      ['Windows XP', /(Windows NT 5.1)|(Windows XP)/],
+      ['Windows Server 2003', /(Windows NT 5.2)/],
+      ['Windows Vista', /(Windows NT 6.0)/],
+      ['Windows 7', /(Windows NT 6.1)/],
+      ['Windows 8', /(Windows NT 6.2)/],
+      ['Windows 8.1', /(Windows NT 6.3)/],
+      ['Windows 10', /(Windows NT 10.0)/],
+      ['Windows ME', /Windows ME/],
+      ['Open BSD', /OpenBSD/],
+      ['Sun OS', /SunOS/],
+      ['Chrome OS', /CrOS/],
+      ['Linux', /(Linux)|(X11)/],
+      ['Mac OS', /(Mac_PowerPC)|(Macintosh)/],
+      ['QNX', /QNX/],
+      ['BeOS', /BeOS/],
+      ['OS/2', /OS\/2/],
+      ['Search Bot', SEARCHBOT_OS_REGEX],
+  ];
+  function detect(userAgent) {
+      if (!!userAgent) {
+          return parseUserAgent(userAgent);
+      }
+      if (typeof navigator !== 'undefined') {
+          return parseUserAgent(navigator.userAgent);
+      }
+      return getNodeVersion();
+  }
+  exports.detect = detect;
+  function parseUserAgent(ua) {
+      // opted for using reduce here rather than Array#first with a regex.test call
+      // this is primarily because using the reduce we only perform the regex
+      // execution once rather than once for the test and for the exec again below
+      // probably something that needs to be benchmarked though
+      var matchedRule = ua !== '' &&
+          userAgentRules.reduce(function (matched, _a) {
+              var browser = _a[0], regex = _a[1];
+              if (matched) {
+                  return matched;
+              }
+              var uaMatch = regex.exec(ua);
+              return !!uaMatch && [browser, uaMatch];
+          }, false);
+      if (!matchedRule) {
+          return null;
+      }
+      var name = matchedRule[0], match = matchedRule[1];
+      if (name === 'searchbot') {
+          return new BotInfo();
+      }
+      var versionParts = match[1] && match[1].split(/[._]/).slice(0, 3);
+      if (versionParts) {
+          if (versionParts.length < REQUIRED_VERSION_PARTS) {
+              versionParts = __spreadArrays(versionParts, createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length));
+          }
+      }
+      else {
+          versionParts = [];
+      }
+      return new BrowserInfo(name, versionParts.join('.'), detectOS(ua));
+  }
+  exports.parseUserAgent = parseUserAgent;
+  function detectOS(ua) {
+      for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) {
+          var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1];
+          var match = regex.test(ua);
+          if (match) {
+              return os;
+          }
+      }
+      return null;
+  }
+  exports.detectOS = detectOS;
+  function getNodeVersion() {
+      var isNode = typeof process !== 'undefined' && process.version;
+      return isNode ? new NodeInfo(process.version.slice(1)) : null;
+  }
+  exports.getNodeVersion = getNodeVersion;
+  function createVersionParts(count) {
+      var output = [];
+      for (var ii = 0; ii < count; ii++) {
+          output.push('0');
+      }
+      return output;
+  }
+  });
+
+  unwrapExports(detectBrowser);
+  var detectBrowser_1 = detectBrowser.BrowserInfo;
+  var detectBrowser_2 = detectBrowser.NodeInfo;
+  var detectBrowser_3 = detectBrowser.BotInfo;
+  var detectBrowser_4 = detectBrowser.detect;
+  var detectBrowser_5 = detectBrowser.parseUserAgent;
+  var detectBrowser_6 = detectBrowser.detectOS;
+  var detectBrowser_7 = detectBrowser.getNodeVersion;
+
   /*
    * Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
@@ -195,6 +388,7 @@ var userale = (function (exports) {
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
+  var browser = detectBrowser_4();
 
   var logs;
   var config;
@@ -271,6 +465,7 @@ var userale = (function (exports) {
       'pageUrl': window.location.href,
       'pageTitle': document.title,
       'pageReferrer': document.referrer,
+      'browser': detectBrowser$1(),
       'clientTime' : timeFields.milli,
       'microTime' : timeFields.micro,
       'location' : getLocation(e),
@@ -321,6 +516,7 @@ var userale = (function (exports) {
           'pageUrl': window.location.href,
           'pageTitle': document.title,
           'pageReferrer': document.referrer,
+          'browser': detectBrowser$1(),
           'clientTime' : timeFields.milli,
           'microTime' : timeFields.micro,
           'logType': 'custom',
@@ -391,6 +587,7 @@ var userale = (function (exports) {
               'pageUrl': window.location.href,
               'pageTitle': document.title,
               'pageReferrer': document.referrer,
+              'browser': detectBrowser$1(),
               'count': intervalCounter,
               'duration': timestamp - intervalTimer,  // microseconds
               'startTime': intervalTimer,
@@ -412,7 +609,7 @@ var userale = (function (exports) {
           }
 
           if (typeof mapHandler === 'function') {
-            intervalLog = mapHandler(intervalLog);
+            intervalLog = mapHandler(intervalLog, e);
           }
 
           logs.push(intervalLog);
@@ -502,6 +699,10 @@ var userale = (function (exports) {
     return pathSelectors;
   }
 
+  function detectBrowser$1() {
+      return {'browser': browser.name, 'version': browser.version};
+  }
+
   /*
    * Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
diff --git a/build/userale-2.0.2.min.js b/build/userale-2.0.2.min.js
index 021123f..e78a68c 100644
--- a/build/userale-2.0.2.min.js
+++ b/build/userale-2.0.2.min.js
@@ -15,4 +15,4 @@
  * limitations under the License.
  * @preserved
  */
-var userale=function(n){"use strict";var u,l,i,a,s,c,d,f,e="2.0.2",r=null;function t(n,o){Object.keys(o).forEach(function(e){if("userFromParams"===e){var t=function(e){var t=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)"),n=window.location.href.match(t);return n&&n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):null}(o[e]);t&&(n.userId=t)}n[e]=o[e]})}var m=null,g=null;function o(e,t){if(!l.on)return!1;var n=null;t&&(n=t(e));var o=p(e.timeStamp&&0<e.timeStamp?l.time(e.timeStamp):Date.now()),r={t [...]
\ No newline at end of file
+var userale=function(t){"use strict";var e="2.0.2",r=null;function n(t,o){Object.keys(o).forEach(function(e){if("userFromParams"===e){var n=function(e){var n=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)"),t=window.location.href.match(n);return t&&t[2]?decodeURIComponent(t[2].replace(/\+/g," ")):null}(o[e]);n&&(t.userId=n)}t[e]=o[e]})}var f="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var o,i,a=(fu [...]
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 9a2641c..770d93f 100755
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -20,7 +20,9 @@ var del = require('del');
 var eslint = require('gulp-eslint');
 var log = require('gulplog');
 var rollup = require('rollup').rollup;
-var json = require('rollup-plugin-json');
+var json = require('@rollup/plugin-json');
+var resolve = require('@rollup/plugin-node-resolve');
+var commonjs = require('rollup-plugin-commonjs');
 var uglify = require('gulp-uglify');
 var rename = require('gulp-rename');
 var mocha = require('gulp-mocha');
@@ -62,7 +64,9 @@ gulp.task('rollup', function() {
               'limitations under the License.' +
               '\n@preserved'
         }),
-      json()
+        json(),
+        resolve(),
+        commonjs()
     ]
   })
   .then(function(bundle) {
@@ -80,7 +84,9 @@ gulp.task('rollup-web-ext-content', function() {
   return rollup({
     input : 'src/' + userAleWebExtDirName + '/content.js',
     plugins : [
-      json()
+      json(),
+      resolve(),
+      commonjs()
     ]
   })
   .then(function(bundle) {
@@ -97,7 +103,9 @@ gulp.task('rollup-web-ext-background', function() {
   return rollup({
     input : 'src/' + userAleWebExtDirName + '/background.js',
     plugins : [
-      json()
+      json(),
+      resolve(),
+      commonjs()
     ]
   })
   .then(function(bundle) {
@@ -114,7 +122,9 @@ gulp.task('rollup-web-ext-options', function() {
   return rollup({
     input : 'src/' + userAleWebExtDirName + '/options.js',
     plugins : [
-      json()
+      json(),
+      resolve(),
+      commonjs()
     ]
   })
   .then(function(bundle) {
diff --git a/package-lock.json b/package-lock.json
index ac1eb67..ba1b8c9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -61,6 +61,37 @@
         }
       }
     },
+    "@rollup/plugin-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.0.0.tgz",
+      "integrity": "sha512-Z65CtEVWv40+ri4CvmswyhtuUtki9yP5p0UJN/GyCKKyU4jRuDS9CG0ZuV7/XuS7zGkoajyE7E4XBEaC4GW62A==",
+      "dev": true,
+      "requires": {
+        "rollup-pluginutils": "^2.5.0"
+      }
+    },
+    "@rollup/plugin-node-resolve": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-6.0.0.tgz",
+      "integrity": "sha512-GqWz1CfXOsqpeVMcoM315+O7zMxpRsmhWyhJoxLFHVSp9S64/u02i7len/FnbTNbmgYs+sZyilasijH8UiuboQ==",
+      "dev": true,
+      "requires": {
+        "@rollup/pluginutils": "^3.0.0",
+        "@types/resolve": "0.0.8",
+        "builtin-modules": "^3.1.0",
+        "is-module": "^1.0.0",
+        "resolve": "^1.11.1"
+      }
+    },
+    "@rollup/pluginutils": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.0.tgz",
+      "integrity": "sha512-qBbGQQaUUiId/lBU9VMeYlVLOoRNvz1fV8HWY5tiGDpI2gdPZHbmOfCjzSdXPhdq3XOfyWvXEBlIPbnM3+9ogQ==",
+      "dev": true,
+      "requires": {
+        "estree-walker": "^0.6.1"
+      }
+    },
     "@sinonjs/commons": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz",
@@ -106,9 +137,9 @@
       "dev": true
     },
     "@types/estree": {
-      "version": "0.0.39",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
-      "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+      "version": "0.0.40",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.40.tgz",
+      "integrity": "sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA==",
       "dev": true
     },
     "@types/node": {
@@ -117,6 +148,15 @@
       "integrity": "sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw==",
       "dev": true
     },
+    "@types/resolve": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
+      "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "abab": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
@@ -1447,6 +1487,12 @@
       "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
       "dev": true
     },
+    "builtin-modules": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
+      "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
+      "dev": true
+    },
     "bytes": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@@ -2096,6 +2142,12 @@
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
       "dev": true
     },
+    "detect-browser": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-4.8.0.tgz",
+      "integrity": "sha512-f4h2dFgzHUIpjpBLjhnDIteXv8VQiUm8XzAuzQtYUqECX/eKh67ykuiVoyb7Db7a0PUSmJa3OGXStG0CbQFUVw==",
+      "dev": true
+    },
     "detect-file": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
@@ -4494,6 +4546,12 @@
         "is-path-inside": "^1.0.0"
       }
     },
+    "is-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+      "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
+      "dev": true
+    },
     "is-negated-glob": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
@@ -4577,6 +4635,23 @@
       "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
       "dev": true
     },
+    "is-reference": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz",
+      "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==",
+      "dev": true,
+      "requires": {
+        "@types/estree": "0.0.39"
+      },
+      "dependencies": {
+        "@types/estree": {
+          "version": "0.0.39",
+          "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+          "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+          "dev": true
+        }
+      }
+    },
     "is-relative": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
@@ -4926,9 +5001,9 @@
       }
     },
     "magic-string": {
-      "version": "0.25.3",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz",
-      "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==",
+      "version": "0.25.4",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz",
+      "integrity": "sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==",
       "dev": true,
       "requires": {
         "sourcemap-codec": "^1.4.4"
@@ -6341,36 +6416,67 @@
       }
     },
     "rollup": {
-      "version": "1.19.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.19.4.tgz",
-      "integrity": "sha512-G24w409GNj7i/Yam2cQla6qV2k6Nug8bD2DZg9v63QX/cH/dEdbNJg8H4lUm5M1bRpPKRUC465Rm9H51JTKOfQ==",
+      "version": "1.27.13",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.13.tgz",
+      "integrity": "sha512-hDi7M07MpmNSDE8YVwGVFA8L7n8jTLJ4lG65nMAijAyqBe//rtu4JdxjUBE7JqXfdpqxqDTbCDys9WcqdpsQvw==",
       "dev": true,
       "requires": {
-        "@types/estree": "0.0.39",
-        "@types/node": "^12.6.9",
-        "acorn": "^6.2.1"
+        "@types/estree": "*",
+        "@types/node": "*",
+        "acorn": "^7.1.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
+          "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
+          "dev": true
+        }
       }
     },
-    "rollup-plugin-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz",
-      "integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==",
+    "rollup-plugin-commonjs": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
+      "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==",
       "dev": true,
       "requires": {
-        "rollup-pluginutils": "^2.5.0"
+        "estree-walker": "^0.6.1",
+        "is-reference": "^1.1.2",
+        "magic-string": "^0.25.2",
+        "resolve": "^1.11.0",
+        "rollup-pluginutils": "^2.8.1"
       }
     },
     "rollup-plugin-license": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/rollup-plugin-license/-/rollup-plugin-license-0.10.0.tgz",
-      "integrity": "sha512-DjoT3eQbTfTbRn1iobWjXZjDGpSGLQRXUNgxiIg5HZ4WvH4Z9eX4dR40k/Y2uHO/MJAebYh0QaZiyqHQyYHSJg==",
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/rollup-plugin-license/-/rollup-plugin-license-0.13.0.tgz",
+      "integrity": "sha512-K1At1InQufYagn1zNTikWG6NorVjdBBoKtJdHqbyV/Z1ksM3wHtWlR/4rqdKxyZjTXNTDzM7mxn7j/HERexLFw==",
       "dev": true,
       "requires": {
         "commenting": "1.1.0",
+        "glob": "7.1.6",
         "lodash": "4.17.15",
-        "magic-string": "0.25.3",
+        "magic-string": "0.25.4",
         "mkdirp": "0.5.1",
-        "moment": "2.24.0"
+        "moment": "2.24.0",
+        "spdx-expression-validate": "2.0.0",
+        "spdx-satisfies": "5.0.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        }
       }
     },
     "rollup-pluginutils": {
@@ -6761,6 +6867,17 @@
       "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
       "dev": true
     },
+    "spdx-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz",
+      "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==",
+      "dev": true,
+      "requires": {
+        "array-find-index": "^1.0.2",
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-ranges": "^2.0.0"
+      }
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -6787,12 +6904,38 @@
         "spdx-license-ids": "^3.0.0"
       }
     },
+    "spdx-expression-validate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz",
+      "integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
     "spdx-license-ids": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
       "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
       "dev": true
     },
+    "spdx-ranges": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz",
+      "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==",
+      "dev": true
+    },
+    "spdx-satisfies": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-5.0.0.tgz",
+      "integrity": "sha512-/hGhwh20BeGmkA+P/lm06RvXD94JduwNxtx/oX3B5ClPt1/u/m5MCaDNo1tV3Y9laLkQr/NRde63b9lLMhlNfw==",
+      "dev": true,
+      "requires": {
+        "spdx-compare": "^1.0.0",
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-ranges": "^2.0.0"
+      }
+    },
     "split-string": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
diff --git a/package.json b/package.json
index 2335be3..203547d 100755
--- a/package.json
+++ b/package.json
@@ -42,15 +42,18 @@
     "npm": "6.4.1 || 6.7.0 - 6.9.0"
   },
   "devDependencies": {
+    "@rollup/plugin-json": "^4.0.0",
+    "@rollup/plugin-node-resolve": "^6.0.0",
     "babel-preset-env": "^1.7.0",
     "babel-register": "^6.11.6",
     "body-parser": "^1.15.0",
     "chai": "^3.5.0",
+    "composer": "^4.1.0",
     "del": "^2.2.2",
+    "detect-browser": "^4.8.0",
     "dom-storage": "2.0.2",
     "express": "^4.13.4",
     "gulp": "^4.0.2",
-    "gulplog": "^1.0.0",
     "gulp-eslint": "^5.0.0",
     "gulp-filter": "^5.0.0",
     "gulp-json-modify": "^1.0.2",
@@ -58,15 +61,15 @@
     "gulp-rename": "^1.2.2",
     "gulp-replace": "^0.5.4",
     "gulp-uglify": "^3.0.1",
+    "gulplog": "^1.0.0",
     "jsdom": "^9.12.0",
     "jsdom-global": "^2.1.1",
     "nodemon": "^1.19.1",
-    "rollup": "^1.17.0",
-    "rollup-plugin-json": "^4.0.0",
-    "rollup-plugin-license": "^0.10.0",
+    "pump": "^3.0.0",
+    "rollup": "^1.27.13",
+    "rollup-plugin-commonjs": "^10.1.0",
+    "rollup-plugin-license": "^0.13.0",
     "sinon": "^7.3.2",
-    "uglify-es": "^3.3.9",
-    "composer": "^4.1.0",
-    "pump": "^3.0.0"
+    "uglify-es": "^3.3.9"
   }
 }
diff --git a/src/getInitialSettings.js b/src/getInitialSettings.js
index fa89b45..7982846 100644
--- a/src/getInitialSettings.js
+++ b/src/getInitialSettings.js
@@ -48,7 +48,7 @@ export function getInitialSettings() {
   settings.time = timeStampScale(document.createEvent('CustomEvent'));
   settings.sessionID = get('data-session') || sessionId;
   settings.authHeader = get ('data-auth') || null;
-
+  settings.custIndex = get ('data-index') || null;
   return settings;
 }
 
diff --git a/src/packageLogs.js b/src/packageLogs.js
index 2010ca4..36cb9d2 100644
--- a/src/packageLogs.js
+++ b/src/packageLogs.js
@@ -15,6 +15,9 @@
  * limitations under the License.
  */
 
+import { detect } from 'detect-browser';
+var browser = detect();
+
 export var logs;
 var config;
 
@@ -90,6 +93,7 @@ export function packageLog(e, detailFcn) {
     'pageUrl': window.location.href,
     'pageTitle': document.title,
     'pageReferrer': document.referrer,
+    'browser': detectBrowser(),
     'clientTime' : timeFields.milli,
     'microTime' : timeFields.micro,
     'location' : getLocation(e),
@@ -140,6 +144,7 @@ export function packageCustomLog(customLog, detailFcn, userAction) {
         'pageUrl': window.location.href,
         'pageTitle': document.title,
         'pageReferrer': document.referrer,
+        'browser': detectBrowser(),
         'clientTime' : timeFields.milli,
         'microTime' : timeFields.micro,
         'logType': 'custom',
@@ -210,6 +215,7 @@ export function packageIntervalLog(e) {
             'pageUrl': window.location.href,
             'pageTitle': document.title,
             'pageReferrer': document.referrer,
+            'browser': detectBrowser(),
             'count': intervalCounter,
             'duration': timestamp - intervalTimer,  // microseconds
             'startTime': intervalTimer,
@@ -231,7 +237,7 @@ export function packageIntervalLog(e) {
         }
 
         if (typeof mapHandler === 'function') {
-          intervalLog = mapHandler(intervalLog);
+          intervalLog = mapHandler(intervalLog, e);
         }
 
         logs.push(intervalLog);
@@ -319,4 +325,8 @@ export function selectorizePath(path) {
     ++i;
   }
   return pathSelectors;
+}
+
+export function detectBrowser() {
+    return {'browser': browser.name, 'version': browser.version};
 }
\ No newline at end of file
diff --git a/test/main_spec.js b/test/main_spec.js
index 3240825..0b6ac44 100644
--- a/test/main_spec.js
+++ b/test/main_spec.js
@@ -48,6 +48,7 @@ describe('Userale API', () => {
         'userFromParams',
         'time',
         'authHeader',
+        'custIndex'
       ]);
       window.close();
       done();