diff --git a/CHANGELOG.md b/CHANGELOG.md index c2362bff..948a8c1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Updated our [UA-parser-js](https://github.com/amplitude/ua-parser-js) fork to properly parse the version number for Chrome Mobile browsers. + ### 3.3.1 (October 26, 2016) * Fix bug where tracking UTM params and referrer drops unsent events that have been saved to localStorage. diff --git a/amplitude.js b/amplitude.js index a184ca45..870cd2e5 100644 --- a/amplitude.js +++ b/amplitude.js @@ -4292,7 +4292,7 @@ module.exports = Revenue; ], [[NAME, /_/g, ' '], VERSION], [ /((?:android.+)crmo|crios)\/([\w\.]+)/i, - /android.+chrome\/([\w\.]+)\s+(?:mobile\s?safari)/i // Chrome for Android/iOS + /android.+(chrome)\/([\w\.]+)\s+(?:mobile\s?safari)/i // Chrome for Android/iOS ], [[NAME, 'Chrome Mobile'], VERSION], [ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i, diff --git a/amplitude.min.js b/amplitude.min.js index 1a91b119..9a52f840 100644 --- a/amplitude.min.js +++ b/amplitude.min.js @@ -1,3 +1,3 @@ (function umd(require){if("object"==typeof exports){module.exports=require("1")}else if("function"==typeof define&&define.amd){define(function(){return require("1")})}else{this["amplitude"]=require("1")}})(function outer(modules,cache,entries){var global=function(){return this}();function require(name,jumped){if(cache[name])return cache[name].exports;if(modules[name])return call(name,require);throw new Error('cannot find module "'+name+'"')}function call(id,require){var m=cache[id]={exports:{}};var mod=modules[id];var name=mod[2];var fn=mod[0];fn.call(m.exports,function(req){var dep=modules[id][1][req];return require(dep?dep:req)},m,m.exports,outer,modules,cache,entries);if(name)cache[name]=cache[id];return cache[id].exports}for(var id in entries){if(entries[id]){global[entries[id]]=require(id)}else{require(id)}}require.duo=true;require.cache=cache;require.modules=modules;return require}({1:[function(require,module,exports){var Amplitude=require("./amplitude");var old=window.amplitude||{};var newInstance=new Amplitude;newInstance._q=old._q||[];for(var instance in old._iq){if(old._iq.hasOwnProperty(instance)){newInstance.getInstance(instance)._q=old._iq[instance]._q||[]}}module.exports=newInstance},{"./amplitude":2}],2:[function(require,module,exports){var AmplitudeClient=require("./amplitude-client");var Constants=require("./constants");var Identify=require("./identify");var object=require("object");var Revenue=require("./revenue");var type=require("./type");var utils=require("./utils");var version=require("./version");var DEFAULT_OPTIONS=require("./options");var Amplitude=function Amplitude(){this.options=object.merge({},DEFAULT_OPTIONS);this._q=[];this._instances={}};Amplitude.prototype.Identify=Identify;Amplitude.prototype.Revenue=Revenue;Amplitude.prototype.getInstance=function getInstance(instance){instance=utils.isEmptyString(instance)?Constants.DEFAULT_INSTANCE:instance.toLowerCase();var client=this._instances[instance];if(client===undefined){client=new AmplitudeClient(instance);this._instances[instance]=client}return client};Amplitude.prototype.init=function init(apiKey,opt_userId,opt_config,opt_callback){this.getInstance().init(apiKey,opt_userId,opt_config,function(instance){this.options=instance.options;if(type(opt_callback)==="function"){opt_callback(instance)}}.bind(this))};Amplitude.prototype.runQueuedFunctions=function(){for(var i=0;ithis.options.sessionTimeout){this._newSession=true;this._sessionId=now;if(this.options.saveParamsReferrerOncePerSession){this._trackParamsAndReferrer()}}if(!this.options.saveParamsReferrerOncePerSession){this._trackParamsAndReferrer()}this._lastEventTime=now;_saveCookieData(this);this._sendEventsIfReady()}catch(e){utils.log(e)}finally{if(type(opt_callback)==="function"){opt_callback(this)}}};AmplitudeClient.prototype._trackParamsAndReferrer=function _trackParamsAndReferrer(){if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveReferrer(this._getReferrer())}if(this.options.includeGclid){this._saveGclid(this._getUrlParams())}};var _parseConfig=function _parseConfig(options,config){if(type(config)!=="object"){return}var parseValidateAndLoad=function parseValidateAndLoad(key){if(!DEFAULT_OPTIONS.hasOwnProperty(key)){return}var inputValue=config[key];var expectedType=type(DEFAULT_OPTIONS[key]);if(!utils.validateInput(inputValue,key+" option",expectedType)){return}if(expectedType==="boolean"){options[key]=!!inputValue}else if(expectedType==="string"&&!utils.isEmptyString(inputValue)||expectedType==="number"&&inputValue>0){options[key]=inputValue}};for(var key in config){if(config.hasOwnProperty(key)){parseValidateAndLoad(key)}}};AmplitudeClient.prototype.runQueuedFunctions=function(){for(var i=0;i=this.options.eventUploadThreshold){this.sendEvents(callback);return true}if(!this._updateScheduled){this._updateScheduled=true;setTimeout(function(){this._updateScheduled=false;this.sendEvents()}.bind(this),this.options.eventUploadPeriodMillis)}return false};AmplitudeClient.prototype._getFromStorage=function _getFromStorage(storage,key){return storage.getItem(key+this._storageSuffix)};AmplitudeClient.prototype._setInStorage=function _setInStorage(storage,key,value){storage.setItem(key+this._storageSuffix,value)};var _upgradeCookeData=function _upgradeCookeData(scope){var cookieData=scope.cookieStorage.get(scope.options.cookieName);if(type(cookieData)==="object"&&cookieData.deviceId&&cookieData.sessionId&&cookieData.lastEventTime){return}var _getAndRemoveFromLocalStorage=function _getAndRemoveFromLocalStorage(key){var value=localStorage.getItem(key);localStorage.removeItem(key);return value};var apiKeySuffix=type(scope.options.apiKey)==="string"&&"_"+scope.options.apiKey.slice(0,6)||"";var localStorageDeviceId=_getAndRemoveFromLocalStorage(Constants.DEVICE_ID+apiKeySuffix);var localStorageUserId=_getAndRemoveFromLocalStorage(Constants.USER_ID+apiKeySuffix);var localStorageOptOut=_getAndRemoveFromLocalStorage(Constants.OPT_OUT+apiKeySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorageOptOut=String(localStorageOptOut)==="true"}var localStorageSessionId=parseInt(_getAndRemoveFromLocalStorage(Constants.SESSION_ID));var localStorageLastEventTime=parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_EVENT_TIME));var localStorageEventId=parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_EVENT_ID));var localStorageIdentifyId=parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_IDENTIFY_ID));var localStorageSequenceNumber=parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_SEQUENCE_NUMBER));var _getFromCookie=function _getFromCookie(key){return type(cookieData)==="object"&&cookieData[key]};scope.options.deviceId=_getFromCookie("deviceId")||localStorageDeviceId;scope.options.userId=_getFromCookie("userId")||localStorageUserId;scope._sessionId=_getFromCookie("sessionId")||localStorageSessionId||scope._sessionId;scope._lastEventTime=_getFromCookie("lastEventTime")||localStorageLastEventTime||scope._lastEventTime;scope._eventId=_getFromCookie("eventId")||localStorageEventId||scope._eventId;scope._identifyId=_getFromCookie("identifyId")||localStorageIdentifyId||scope._identifyId;scope._sequenceNumber=_getFromCookie("sequenceNumber")||localStorageSequenceNumber||scope._sequenceNumber;scope.options.optOut=localStorageOptOut||false;if(cookieData&&cookieData.optOut!==undefined&&cookieData.optOut!==null){scope.options.optOut=String(cookieData.optOut)==="true"}_saveCookieData(scope)};var _loadCookieData=function _loadCookieData(scope){var cookieData=scope.cookieStorage.get(scope.options.cookieName+scope._storageSuffix);if(type(cookieData)==="object"){if(cookieData.deviceId){scope.options.deviceId=cookieData.deviceId}if(cookieData.userId){scope.options.userId=cookieData.userId}if(cookieData.optOut!==null&&cookieData.optOut!==undefined){scope.options.optOut=cookieData.optOut}if(cookieData.sessionId){scope._sessionId=parseInt(cookieData.sessionId)}if(cookieData.lastEventTime){scope._lastEventTime=parseInt(cookieData.lastEventTime)}if(cookieData.eventId){scope._eventId=parseInt(cookieData.eventId)}if(cookieData.identifyId){scope._identifyId=parseInt(cookieData.identifyId)}if(cookieData.sequenceNumber){scope._sequenceNumber=parseInt(cookieData.sequenceNumber)}}};var _saveCookieData=function _saveCookieData(scope){scope.cookieStorage.set(scope.options.cookieName+scope._storageSuffix,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut,sessionId:scope._sessionId,lastEventTime:scope._lastEventTime,eventId:scope._eventId,identifyId:scope._identifyId,sequenceNumber:scope._sequenceNumber})};AmplitudeClient.prototype._initUtmData=function _initUtmData(queryParams,cookieParams){queryParams=queryParams||this._getUrlParams();cookieParams=cookieParams||this.cookieStorage.get("__utmz");var utmProperties=getUtmData(cookieParams,queryParams);_sendParamsReferrerUserProperties(this,utmProperties)};var _sendParamsReferrerUserProperties=function _sendParamsReferrerUserProperties(scope,userProperties){if(type(userProperties)!=="object"||Object.keys(userProperties).length===0){return}var identify=new Identify;for(var key in userProperties){if(userProperties.hasOwnProperty(key)){identify.setOnce("initial_"+key,userProperties[key]);identify.set(key,userProperties[key])}}scope.identify(identify)};AmplitudeClient.prototype._getReferrer=function _getReferrer(){return document.referrer};AmplitudeClient.prototype._getUrlParams=function _getUrlParams(){return location.search};AmplitudeClient.prototype._saveGclid=function _saveGclid(urlParams){var gclid=utils.getQueryParam("gclid",urlParams);if(utils.isEmptyString(gclid)){return}var gclidProperties={gclid:gclid};_sendParamsReferrerUserProperties(this,gclidProperties)};AmplitudeClient.prototype._getReferringDomain=function _getReferringDomain(referrer){if(utils.isEmptyString(referrer)){return null}var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return null};AmplitudeClient.prototype._saveReferrer=function _saveReferrer(referrer){if(utils.isEmptyString(referrer)){return}var referrerInfo={referrer:referrer,referring_domain:this._getReferringDomain(referrer)};_sendParamsReferrerUserProperties(this,referrerInfo)};AmplitudeClient.prototype.saveEvents=function saveEvents(){try{this._setInStorage(localStorage,this.options.unsentKey,JSON.stringify(this._unsentEvents))}catch(e){}try{this._setInStorage(localStorage,this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};AmplitudeClient.prototype.setDomain=function setDomain(domain){if(!utils.validateInput(domain,"domain","string")){return}try{this.cookieStorage.options({domain:domain});this.options.domain=this.cookieStorage.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){utils.log(e)}};AmplitudeClient.prototype.setUserId=function setUserId(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){utils.log(e)}};AmplitudeClient.prototype.setGroup=function(groupType,groupName){if(!this._apiKeySet("setGroup()")||!utils.validateInput(groupType,"groupType","string")||utils.isEmptyString(groupType)){return}var groups={};groups[groupType]=groupName;var identify=(new Identify).set(groupType,groupName);this._logEvent(Constants.IDENTIFY_EVENT,null,null,identify.userPropertiesOperations,groups,null)};AmplitudeClient.prototype.setOptOut=function setOptOut(enable){if(!utils.validateInput(enable,"enable","boolean")){return}try{this.options.optOut=enable;_saveCookieData(this)}catch(e){utils.log(e)}};AmplitudeClient.prototype.regenerateDeviceId=function regenerateDeviceId(){this.setDeviceId(UUID()+"R")};AmplitudeClient.prototype.setDeviceId=function setDeviceId(deviceId){if(!utils.validateInput(deviceId,"deviceId","string")){return}try{if(!utils.isEmptyString(deviceId)){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){utils.log(e)}};AmplitudeClient.prototype.setUserProperties=function setUserProperties(userProperties){if(!this._apiKeySet("setUserProperties()")||!utils.validateInput(userProperties,"userProperties","object")){return}var sanitized=utils.truncate(utils.validateProperties(userProperties));if(Object.keys(sanitized).length===0){return}var identify=new Identify;for(var property in sanitized){if(sanitized.hasOwnProperty(property)){identify.set(property,sanitized[property])}}this.identify(identify)};AmplitudeClient.prototype.clearUserProperties=function clearUserProperties(){if(!this._apiKeySet("clearUserProperties()")){return}var identify=new Identify;identify.clearAll();this.identify(identify)};var _convertProxyObjectToRealObject=function _convertProxyObjectToRealObject(instance,proxy){for(var i=0;i0){return this._logEvent(Constants.IDENTIFY_EVENT,null,null,identify_obj.userPropertiesOperations,null,opt_callback)}}else{utils.log("Invalid identify input type. Expected Identify object but saw "+type(identify_obj))}if(type(opt_callback)==="function"){opt_callback(0,"No request sent")}};AmplitudeClient.prototype.setVersionName=function setVersionName(versionName){if(!utils.validateInput(versionName,"versionName","string")){return}this.options.versionName=versionName};AmplitudeClient.prototype._logEvent=function _logEvent(eventType,eventProperties,apiProperties,userProperties,groups,callback){_loadCookieData(this);if(!eventType||this.options.optOut){if(type(callback)==="function"){callback(0,"No request sent")}return}try{var eventId;if(eventType===Constants.IDENTIFY_EVENT){eventId=this.nextIdentifyId()}else{eventId=this.nextEventId()}var sequenceNumber=this.nextSequenceNumber();var eventTime=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime}this._lastEventTime=eventTime;_saveCookieData(this);userProperties=userProperties||{};apiProperties=apiProperties||{};eventProperties=eventProperties||{};groups=groups||{};var event={device_id:this.options.deviceId,user_id:this.options.userId,timestamp:eventTime,event_id:eventId,session_id:this._sessionId||-1,event_type:eventType,version_name:this.options.versionName||null,platform:this.options.platform,os_name:this._ua.browser.name||null,os_version:this._ua.browser.major||null,device_model:this._ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:utils.truncate(utils.validateProperties(eventProperties)),user_properties:utils.truncate(utils.validateProperties(userProperties)),uuid:UUID(),library:{name:"amplitude-js",version:version},sequence_number:sequenceNumber,groups:utils.truncate(utils.validateGroups(groups)),user_agent:this._userAgent};if(eventType===Constants.IDENTIFY_EVENT){this._unsentIdentifys.push(event);this._limitEventsQueued(this._unsentIdentifys)}else{this._unsentEvents.push(event);this._limitEventsQueued(this._unsentEvents)}if(this.options.saveEvents){this.saveEvents()}if(!this._sendEventsIfReady(callback)&&type(callback)==="function"){callback(0,"No request sent")}return eventId}catch(e){utils.log(e)}};AmplitudeClient.prototype._limitEventsQueued=function _limitEventsQueued(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};AmplitudeClient.prototype.logEvent=function logEvent(eventType,eventProperties,opt_callback){if(!this._apiKeySet("logEvent()")||!utils.validateInput(eventType,"eventType","string")||utils.isEmptyString(eventType)){if(type(opt_callback)==="function"){opt_callback(0,"No request sent")}return-1}return this._logEvent(eventType,eventProperties,null,null,null,opt_callback)};AmplitudeClient.prototype.logEventWithGroups=function(eventType,eventProperties,groups,opt_callback){if(!this._apiKeySet("logEventWithGroup()")||!utils.validateInput(eventType,"eventType","string")){if(type(opt_callback)==="function"){opt_callback(0,"No request sent")}return-1}return this._logEvent(eventType,eventProperties,null,null,groups,opt_callback)};var _isNumber=function _isNumber(n){return!isNaN(parseFloat(n))&&isFinite(n)};AmplitudeClient.prototype.logRevenueV2=function logRevenueV2(revenue_obj){if(!this._apiKeySet("logRevenueV2()")){return}if(type(revenue_obj)==="object"&&revenue_obj.hasOwnProperty("_q")){revenue_obj=_convertProxyObjectToRealObject(new Revenue,revenue_obj)}if(revenue_obj instanceof Revenue){if(revenue_obj&&revenue_obj._isValidRevenue()){return this.logEvent(Constants.REVENUE_EVENT,revenue_obj._toJSONObject())}}else{utils.log("Invalid revenue input type. Expected Revenue object but saw "+type(revenue_obj))}};AmplitudeClient.prototype.logRevenue=function logRevenue(price,quantity,product){if(!this._apiKeySet("logRevenue()")||!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return-1}return this._logEvent(Constants.REVENUE_EVENT,{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price},null,null,null)};AmplitudeClient.prototype.removeEvents=function removeEvents(maxEventId,maxIdentifyId){_removeEvents(this,"_unsentEvents",maxEventId);_removeEvents(this,"_unsentIdentifys",maxIdentifyId)};var _removeEvents=function _removeEvents(scope,eventQueue,maxId){if(maxId<0){return}var filteredEvents=[];for(var i=0;imaxId){filteredEvents.push(scope[eventQueue][i])}}scope[eventQueue]=filteredEvents};AmplitudeClient.prototype.sendEvents=function sendEvents(callback){if(!this._apiKeySet("sendEvents()")||this._sending||this.options.optOut||this._unsentCount()===0){if(type(callback)==="function"){callback(0,"No request sent")}return}this._sending=true;var protocol=this.options.forceHttps?"https":"https:"===window.location.protocol?"https":"http";var url=protocol+"://"+this.options.apiEndpoint+"/";var numEvents=Math.min(this._unsentCount(),this.options.uploadBatchSize);var mergedEvents=this._mergeEventsAndIdentifys(numEvents);var maxEventId=mergedEvents.maxEventId;var maxIdentifyId=mergedEvents.maxIdentifyId;var events=JSON.stringify(mergedEvents.eventsToSend);var uploadTime=(new Date).getTime();var data={client:this.options.apiKey,e:events,v:Constants.API_VERSION,upload_time:uploadTime,checksum:md5(Constants.API_VERSION+this.options.apiKey+events+uploadTime)};var scope=this;new Request(url,data).send(function(status,response){scope._sending=false;try{if(status===200&&response==="success"){scope.removeEvents(maxEventId,maxIdentifyId);if(scope.options.saveEvents){scope.saveEvents()}if(!scope._sendEventsIfReady(callback)&&type(callback)==="function"){callback(status,response)}}else if(status===413){if(scope.options.uploadBatchSize===1){scope.removeEvents(maxEventId,maxIdentifyId)}scope.options.uploadBatchSize=Math.ceil(numEvents/2);scope.sendEvents(callback)}else if(type(callback)==="function"){callback(status,response)}}catch(e){}})};AmplitudeClient.prototype._mergeEventsAndIdentifys=function _mergeEventsAndIdentifys(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length;var noEvents=eventIndex>=this._unsentEvents.length;if(noEvents&&noIdentifys){utils.log("Merging Events and Identifys, less events and identifys than expected");break}else if(noIdentifys){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(noEvents){event=this._unsentIdentifys[identifyIndex++];maxIdentifyId=event.event_id}else{if(!("sequence_number"in this._unsentEvents[eventIndex])||this._unsentEvents[eventIndex].sequence_number>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+Base64._keyStr.charAt(enc1)+Base64._keyStr.charAt(enc2)+Base64._keyStr.charAt(enc3)+Base64._keyStr.charAt(enc4)}return output},decode:function(input){try{if(window.btoa&&window.atob){return decodeURIComponent(escape(window.atob(input)))}}catch(e){}return Base64._decode(input)},_decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}output=UTF8.decode(output);return output}};module.exports=Base64},{"./utf8":23}],23:[function(require,module,exports){var UTF8={encode:function(s){var utftext="";for(var n=0;n127&&c<2048){utftext+=String.fromCharCode(c>>6|192);utftext+=String.fromCharCode(c&63|128)}else{utftext+=String.fromCharCode(c>>12|224);utftext+=String.fromCharCode(c>>6&63|128);utftext+=String.fromCharCode(c&63|128)}}return utftext},decode:function(utftext){var s="";var i=0;var c=0,c1=0,c2=0;while(i191&&c<224){c1=utftext.charCodeAt(i+1);s+=String.fromCharCode((c&31)<<6|c1&63);i+=2}else{c1=utftext.charCodeAt(i+1);c2=utftext.charCodeAt(i+2);s+=String.fromCharCode((c&15)<<12|(c1&63)<<6|c2&63);i+=3}}return s}};module.exports=UTF8},{}],14:[function(require,module,exports){var json=window.JSON||{};var stringify=json.stringify;var parse=json.parse;module.exports=parse&&stringify?JSON:require("json-fallback")},{"json-fallback":24}],24:[function(require,module,exports){(function(){"use strict";var JSON=module.exports={};function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;iconstants.MAX_STRING_LENGTH?value.substring(0,constants.MAX_STRING_LENGTH):value}return value};var validateInput=function validateInput(input,name,expectedType){if(type(input)!==expectedType){log("Invalid "+name+" input type. Expected "+expectedType+" but received "+type(input));return false}return true};var validateProperties=function validateProperties(properties){var propsType=type(properties);if(propsType!=="object"){log("Error: invalid properties format. Expecting Javascript object, received "+propsType+", ignoring");return{}}if(Object.keys(properties).length>constants.MAX_PROPERTY_KEYS){log("Error: too many properties (more than 1000), ignoring");return{}}var copy={};for(var property in properties){if(!properties.hasOwnProperty(property)){continue}var key=property;var keyType=type(key);if(keyType!=="string"){key=String(key);log("WARNING: Non-string property key, received type "+keyType+', coercing to string "'+key+'"')}var value=validatePropertyValue(key,properties[property]);if(value===null){continue}copy[key]=value}return copy};var invalidValueTypes=["null","nan","undefined","function","arguments","regexp","element"];var validatePropertyValue=function validatePropertyValue(key,value){var valueType=type(value);if(invalidValueTypes.indexOf(valueType)!==-1){log('WARNING: Property key "'+key+'" with invalid value type '+valueType+", ignoring");value=null}else if(valueType==="error"){value=String(value);log('WARNING: Property key "'+key+'" with value type error, coercing to '+value)}else if(valueType==="array"){var arrayCopy=[];for(var i=0;i0){if(!this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)){utils.log("Need to send $clearAll on its own Identify object without any other operations, skipping $clearAll")}return this}this.userPropertiesOperations[AMP_OP_CLEAR_ALL]="-";return this};Identify.prototype.prepend=function(property,value){this._addOperation(AMP_OP_PREPEND,property,value);return this};Identify.prototype.set=function(property,value){this._addOperation(AMP_OP_SET,property,value);return this};Identify.prototype.setOnce=function(property,value){this._addOperation(AMP_OP_SET_ONCE,property,value);return this};Identify.prototype.unset=function(property){this._addOperation(AMP_OP_UNSET,property,"-");return this};Identify.prototype._addOperation=function(operation,property,value){if(this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)){utils.log("This identify already contains a $clearAll operation, skipping operation "+operation);return}if(this.properties.indexOf(property)!==-1){utils.log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!this.userPropertiesOperations.hasOwnProperty(operation)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":8,"./utils":9}],16:[function(require,module,exports){(function($){"use strict";function safe_add(x,y){var lsw=(x&65535)+(y&65535),msw=(x>>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}function bit_rol(num,cnt){return num<>>32-cnt}function md5_cmn(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b)}function md5_ff(a,b,c,d,x,s,t){return md5_cmn(b&c|~b&d,a,b,x,s,t)}function md5_gg(a,b,c,d,x,s,t){return md5_cmn(b&d|c&~d,a,b,x,s,t)}function md5_hh(a,b,c,d,x,s,t){return md5_cmn(b^c^d,a,b,x,s,t)}function md5_ii(a,b,c,d,x,s,t){return md5_cmn(c^(b|~d),a,b,x,s,t)}function binl_md5(x,len){x[len>>5]|=128<>>9<<4)+14]=len;var i,olda,oldb,oldc,oldd,a=1732584193,b=-271733879,c=-1732584194,d=271733878;for(i=0;i>5]>>>i%32&255)}return output}function rstr2binl(input){var i,output=[];output[(input.length>>2)-1]=undefined;for(i=0;i>5]|=(input.charCodeAt(i/8)&255)<16){bkey=binl_md5(bkey,key.length*8)}for(i=0;i<16;i+=1){ipad[i]=bkey[i]^909522486;opad[i]=bkey[i]^1549556828}hash=binl_md5(ipad.concat(rstr2binl(data)),512+data.length*8);return binl2rstr(binl_md5(opad.concat(hash),512+128))}function rstr2hex(input){var hex_tab="0123456789abcdef",output="",x,i;for(i=0;i>>4&15)+hex_tab.charAt(x&15)}return output}function str2rstr_utf8(input){return unescape(encodeURIComponent(input))}function raw_md5(s){return rstr_md5(str2rstr_utf8(s))}function hex_md5(s){return rstr2hex(raw_md5(s))}function raw_hmac_md5(k,d){return rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d))}function hex_hmac_md5(k,d){return rstr2hex(raw_hmac_md5(k,d))}function md5(string,key,raw){if(!key){if(!raw){return hex_md5(string)}return raw_md5(string)}if(!raw){return hex_hmac_md5(key,string)}return raw_hmac_md5(key,string)}if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=md5}exports.md5=md5}else{if(typeof define==="function"&&define.amd){define(function(){return md5})}else{$.md5=md5}}})(this)},{}],6:[function(require,module,exports){var has=Object.prototype.hasOwnProperty;exports.keys=Object.keys||function(obj){var keys=[];for(var key in obj){if(has.call(obj,key)){keys.push(key)}}return keys};exports.values=function(obj){var vals=[];for(var key in obj){if(has.call(obj,key)){vals.push(obj[key])}}return vals};exports.merge=function(a,b){for(var key in b){if(has.call(b,key)){a[key]=b[key]}}return a};exports.length=function(obj){return exports.keys(obj).length};exports.isEmpty=function(obj){return 0==exports.length(obj)}},{}],17:[function(require,module,exports){var querystring=require("querystring");var Request=function(url,data){this.url=url;this.data=data||{}};Request.prototype.send=function(callback){var isIE=window.XDomainRequest?true:false;if(isIE){var xdr=new window.XDomainRequest;xdr.open("POST",this.url,true);xdr.onload=function(){callback(200,xdr.responseText)};xdr.onerror=function(){if(xdr.responseText==="Request Entity Too Large"){callback(413,xdr.responseText)}else{callback(500,xdr.responseText)}};xdr.ontimeout=function(){};xdr.onprogress=function(){};xdr.send(querystring.stringify(this.data))}else{var xhr=new XMLHttpRequest;xhr.open("POST",this.url,true);xhr.onreadystatechange=function(){if(xhr.readyState===4){callback(xhr.status,xhr.responseText)}};xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");xhr.send(querystring.stringify(this.data))}};module.exports=Request},{querystring:26}],26:[function(require,module,exports){var encode=encodeURIComponent;var decode=decodeURIComponent;var trim=require("trim");var type=require("type");exports.parse=function(str){if("string"!=typeof str)return{};str=trim(str);if(""==str)return{};if("?"==str.charAt(0))str=str.slice(1);var obj={};var pairs=str.split("&");for(var i=0;i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){result[q[0]]=q[1].call(this,match)}else{result[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){result[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{result[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){result[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{result[q]=match?match:undefined}}}}i+=2}return result},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+Base64._keyStr.charAt(enc1)+Base64._keyStr.charAt(enc2)+Base64._keyStr.charAt(enc3)+Base64._keyStr.charAt(enc4)}return output},decode:function(input){try{if(window.btoa&&window.atob){return decodeURIComponent(escape(window.atob(input)))}}catch(e){}return Base64._decode(input)},_decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}output=UTF8.decode(output);return output}};module.exports=Base64},{"./utf8":23}],23:[function(require,module,exports){var UTF8={encode:function(s){var utftext="";for(var n=0;n127&&c<2048){utftext+=String.fromCharCode(c>>6|192);utftext+=String.fromCharCode(c&63|128)}else{utftext+=String.fromCharCode(c>>12|224);utftext+=String.fromCharCode(c>>6&63|128);utftext+=String.fromCharCode(c&63|128)}}return utftext},decode:function(utftext){var s="";var i=0;var c=0,c1=0,c2=0;while(i191&&c<224){c1=utftext.charCodeAt(i+1);s+=String.fromCharCode((c&31)<<6|c1&63);i+=2}else{c1=utftext.charCodeAt(i+1);c2=utftext.charCodeAt(i+2);s+=String.fromCharCode((c&15)<<12|(c1&63)<<6|c2&63);i+=3}}return s}};module.exports=UTF8},{}],14:[function(require,module,exports){var json=window.JSON||{};var stringify=json.stringify;var parse=json.parse;module.exports=parse&&stringify?JSON:require("json-fallback")},{"json-fallback":24}],24:[function(require,module,exports){(function(){"use strict";var JSON=module.exports={};function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;iconstants.MAX_STRING_LENGTH?value.substring(0,constants.MAX_STRING_LENGTH):value}return value};var validateInput=function validateInput(input,name,expectedType){if(type(input)!==expectedType){log("Invalid "+name+" input type. Expected "+expectedType+" but received "+type(input));return false}return true};var validateProperties=function validateProperties(properties){var propsType=type(properties);if(propsType!=="object"){log("Error: invalid properties format. Expecting Javascript object, received "+propsType+", ignoring");return{}}if(Object.keys(properties).length>constants.MAX_PROPERTY_KEYS){log("Error: too many properties (more than 1000), ignoring");return{}}var copy={};for(var property in properties){if(!properties.hasOwnProperty(property)){continue}var key=property;var keyType=type(key);if(keyType!=="string"){key=String(key);log("WARNING: Non-string property key, received type "+keyType+', coercing to string "'+key+'"')}var value=validatePropertyValue(key,properties[property]);if(value===null){continue}copy[key]=value}return copy};var invalidValueTypes=["null","nan","undefined","function","arguments","regexp","element"];var validatePropertyValue=function validatePropertyValue(key,value){var valueType=type(value);if(invalidValueTypes.indexOf(valueType)!==-1){log('WARNING: Property key "'+key+'" with invalid value type '+valueType+", ignoring");value=null}else if(valueType==="error"){value=String(value);log('WARNING: Property key "'+key+'" with value type error, coercing to '+value)}else if(valueType==="array"){var arrayCopy=[];for(var i=0;i0){if(!this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)){utils.log("Need to send $clearAll on its own Identify object without any other operations, skipping $clearAll")}return this}this.userPropertiesOperations[AMP_OP_CLEAR_ALL]="-";return this};Identify.prototype.prepend=function(property,value){this._addOperation(AMP_OP_PREPEND,property,value);return this};Identify.prototype.set=function(property,value){this._addOperation(AMP_OP_SET,property,value);return this};Identify.prototype.setOnce=function(property,value){this._addOperation(AMP_OP_SET_ONCE,property,value);return this};Identify.prototype.unset=function(property){this._addOperation(AMP_OP_UNSET,property,"-");return this};Identify.prototype._addOperation=function(operation,property,value){if(this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)){utils.log("This identify already contains a $clearAll operation, skipping operation "+operation);return}if(this.properties.indexOf(property)!==-1){utils.log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!this.userPropertiesOperations.hasOwnProperty(operation)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":8,"./utils":9}],16:[function(require,module,exports){(function($){"use strict";function safe_add(x,y){var lsw=(x&65535)+(y&65535),msw=(x>>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}function bit_rol(num,cnt){return num<>>32-cnt}function md5_cmn(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b)}function md5_ff(a,b,c,d,x,s,t){return md5_cmn(b&c|~b&d,a,b,x,s,t)}function md5_gg(a,b,c,d,x,s,t){return md5_cmn(b&d|c&~d,a,b,x,s,t)}function md5_hh(a,b,c,d,x,s,t){return md5_cmn(b^c^d,a,b,x,s,t)}function md5_ii(a,b,c,d,x,s,t){return md5_cmn(c^(b|~d),a,b,x,s,t)}function binl_md5(x,len){x[len>>5]|=128<>>9<<4)+14]=len;var i,olda,oldb,oldc,oldd,a=1732584193,b=-271733879,c=-1732584194,d=271733878;for(i=0;i>5]>>>i%32&255)}return output}function rstr2binl(input){var i,output=[];output[(input.length>>2)-1]=undefined;for(i=0;i>5]|=(input.charCodeAt(i/8)&255)<16){bkey=binl_md5(bkey,key.length*8)}for(i=0;i<16;i+=1){ipad[i]=bkey[i]^909522486;opad[i]=bkey[i]^1549556828}hash=binl_md5(ipad.concat(rstr2binl(data)),512+data.length*8);return binl2rstr(binl_md5(opad.concat(hash),512+128))}function rstr2hex(input){var hex_tab="0123456789abcdef",output="",x,i;for(i=0;i>>4&15)+hex_tab.charAt(x&15)}return output}function str2rstr_utf8(input){return unescape(encodeURIComponent(input))}function raw_md5(s){return rstr_md5(str2rstr_utf8(s))}function hex_md5(s){return rstr2hex(raw_md5(s))}function raw_hmac_md5(k,d){return rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d))}function hex_hmac_md5(k,d){return rstr2hex(raw_hmac_md5(k,d))}function md5(string,key,raw){if(!key){if(!raw){return hex_md5(string)}return raw_md5(string)}if(!raw){return hex_hmac_md5(key,string)}return raw_hmac_md5(key,string)}if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=md5}exports.md5=md5}else{if(typeof define==="function"&&define.amd){define(function(){return md5})}else{$.md5=md5}}})(this)},{}],6:[function(require,module,exports){var has=Object.prototype.hasOwnProperty;exports.keys=Object.keys||function(obj){var keys=[];for(var key in obj){if(has.call(obj,key)){keys.push(key)}}return keys};exports.values=function(obj){var vals=[];for(var key in obj){if(has.call(obj,key)){vals.push(obj[key])}}return vals};exports.merge=function(a,b){for(var key in b){if(has.call(b,key)){a[key]=b[key]}}return a};exports.length=function(obj){return exports.keys(obj).length};exports.isEmpty=function(obj){return 0==exports.length(obj)}},{}],17:[function(require,module,exports){var querystring=require("querystring");var Request=function(url,data){this.url=url;this.data=data||{}};Request.prototype.send=function(callback){var isIE=window.XDomainRequest?true:false;if(isIE){var xdr=new window.XDomainRequest;xdr.open("POST",this.url,true);xdr.onload=function(){callback(200,xdr.responseText)};xdr.onerror=function(){if(xdr.responseText==="Request Entity Too Large"){callback(413,xdr.responseText)}else{callback(500,xdr.responseText)}};xdr.ontimeout=function(){};xdr.onprogress=function(){};xdr.send(querystring.stringify(this.data))}else{var xhr=new XMLHttpRequest;xhr.open("POST",this.url,true);xhr.onreadystatechange=function(){if(xhr.readyState===4){callback(xhr.status,xhr.responseText)}};xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");xhr.send(querystring.stringify(this.data))}};module.exports=Request},{querystring:26}],26:[function(require,module,exports){var encode=encodeURIComponent;var decode=decodeURIComponent;var trim=require("trim");var type=require("type");exports.parse=function(str){if("string"!=typeof str)return{};str=trim(str);if(""==str)return{};if("?"==str.charAt(0))str=str.slice(1);var obj={};var pairs=str.split("&");for(var i=0;i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){result[q[0]]=q[1].call(this,match)}else{result[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){result[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{result[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){result[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{result[q]=match?match:undefined}}}}i+=2}return result},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,uuid)};module.exports=uuid},{}],10:[function(require,module,exports){module.exports="3.3.1"},{}],11:[function(require,module,exports){var language=require("./language");module.exports={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:"",includeReferrer:false,includeUtm:false,language:language.language,optOut:false,platform:"Web",savedMaxCount:1e3,saveEvents:true,sessionTimeout:30*60*1e3,unsentKey:"amplitude_unsent",unsentIdentifyKey:"amplitude_unsent_identify",uploadBatchSize:100,batchEvents:false,eventUploadThreshold:30,eventUploadPeriodMillis:30*1e3,forceHttps:false,includeGclid:false,saveParamsReferrerOncePerSession:true}},{"./language":29}],29:[function(require,module,exports){var getLanguage=function(){return navigator&&(navigator.languages&&navigator.languages[0]||navigator.language||navigator.userLanguage)||undefined};module.exports={language:getLanguage()}},{}]},{},{1:""})); \ No newline at end of file diff --git a/component.json b/component.json index 8b0d696e..eec872c6 100644 --- a/component.json +++ b/component.json @@ -9,7 +9,7 @@ "amplitude" ], "dependencies": { - "amplitude/ua-parser-js": "fbdb1dc", + "amplitude/ua-parser-js": "ed538f1", "amplitude/JavaScript-MD5": "2350ea9", "component/object": "0.0.3", "component/querystring": "1.3.0", diff --git a/test/ua-parser.js b/test/ua-parser.js index 221795e7..54a56bd3 100644 --- a/test/ua-parser.js +++ b/test/ua-parser.js @@ -40,10 +40,10 @@ var browsers = [ ["Android 2.2 - Samsung Galaxy - Mobile Safari 533.1","Mozilla/5.0 (Linux; U; Android 2.2; en-ca; GT-P1000M Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1","Android Browser","4","Android","2.2"], ["Android 4.0.3 - Mobile Safari 534.30 - HTC Sensation","Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","Android Browser","4","Android","4.0.3"], ["Android 4.0.3 - Mobile Safari 534.30 - Samsung Galaxy S II","Mozilla/5.0 (Linux; U; Android 4.0.3; de-de; Galaxy S II Build/GRJ22) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","Android Browser","4","Android","4.0.3"], -["Android 4.1.2 - Chrome 30.0","Mozilla/5.0 (Linux; Android 4.1.2; SHV-E250S Build/JZO54K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.82 Mobile Safari/537.36","Chrome Mobile",undefined,"Android","4.1.2"], +["Android 4.1.2 - Chrome 30.0","Mozilla/5.0 (Linux; Android 4.1.2; SHV-E250S Build/JZO54K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.82 Mobile Safari/537.36","Chrome Mobile","30","Android","4.1.2"], ["Android 4.2 - Firefox 19.0","Mozilla/5.0 (Android 4.2; rv:19.0) Gecko/20121129 Firefox/19.0","Firefox","19","Android","4.2"], ["Android 4.3 - AppleWebKit/536.23","Mozilla/5.0 (Linux; U; Android 4.3; en-us; sdk Build/MR1) AppleWebKit/536.23 (KHTML, like Gecko) Version/4.3 Mobile Safari/536.23","Android Browser","4","Android","4.3"], -["Android 4.4 - (Nexus 5) - AppleWebKit/536.23","Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36","Chrome Mobile",undefined,"Android","4.4"], +["Android 4.4 - (Nexus 5) - AppleWebKit/536.23","Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36","Chrome Mobile","30","Android","4.4"], ["Android 4.4.2 - Chrome 35.0.1916.141","Mozilla/5.0 (Linux; Android 4.4.2; SAMSUNG-SM-T537A Build/KOT49H) AppleWebKit/537.36 (KHTML like Gecko) Chrome/35.0.1916.141 Safari/537.36","Chrome","35","Android","4.4.2"], ["Android SDK - Android 1.5 - Mobile Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.5; en-us; sdk Build/CUPCAKE) AppleWebkit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1","Android Browser","3","Android","1.5"], ["Apple iPad - iOS - Puffin/3.9174IT (IT=ios tablet)","Mozilla/5.0 (X11; U; Linux x86_64; en-AU) AppleWebKit/534.35 (KHTML, like Gecko) Chrome/11.0.696.65 Safari/534.35 Puffin/3.9174IT","Chrome","11","Linux","x86_64"], @@ -194,7 +194,7 @@ var browsers = [ ["Galaxy (Verizon) - Android 2.2 - Mobile Safari 533.1","Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1","Android Browser","4","Android","2.2"], ["Galaxy - Android 1.5 - Mobile Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.5; de-de; Galaxy Build/CUPCAKE) AppleWebKit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1","Android Browser","3","Android","1.5"], ["Galaxy - Android 2.2 - Mobile Safari 533.1","Mozilla/5.0 (Linux; U; Android 2.2; en-ca; GT-P1000M Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1","Android Browser","4","Android","2.2"], -["Galaxy S 3 (SPH-L710) - Android 4.3 - Chrome 32.0.1700.99","Mozilla/5.0 (Linux; Android 4.3; SPH-L710 Build/JSS15J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Mobile Safari/537.36","Chrome Mobile",undefined,"Android","4.3"], +["Galaxy S 3 (SPH-L710) - Android 4.3 - Chrome 32.0.1700.99","Mozilla/5.0 (Linux; Android 4.3; SPH-L710 Build/JSS15J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Mobile Safari/537.36","Chrome Mobile","32","Android","4.3"], ["Galaxy S II - Android 4.0.3 - Mobile Safari 534.30","Mozilla/5.0 (Linux; U; Android 4.0.3; de-de; Galaxy S II Build/GRJ22) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","Android Browser","4","Android","4.0.3"], ["Google AdsBot 1.0","AdsBot-Google ( http://www.google.com/adsbot.html)",undefined,undefined,undefined,undefined], ["Google Feed Fetcher","FeedFetcher-Google; ( http://www.google.com/feedfetcher.html)",undefined,undefined,undefined,undefined], @@ -239,7 +239,7 @@ var browsers = [ ["iPod Touch - iOS 3_1_1 - Safari 528.16","Mozilla/5.0 (iPod; U; CPU iPhone OS 3_1_1 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Mobile/7C145","WebKit","528","iPhone","3.1.1"], ["iPod Touch - iOS 7_1 - Safari 7.0/537.51.2","Mozilla/5.0 (iPod touch; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML like Gecko) Version/7.0 Mobile/11D167 Safari/123E71C","Mobile Safari","7","iPhone","7.1"], ["Motorola Xoom - Android 3.0.1 - Mobile Safari 523.12","Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2","Android Browser","3","Android","3.0"], -["Nexus 5 - Android 4.4 - AppleWebKit/536.23","Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36","Chrome Mobile",undefined,"Android","4.4"], +["Nexus 5 - Android 4.4 - AppleWebKit/536.23","Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36","Chrome Mobile","30","Android","4.4"], ["Nexus 7 - Android 4.4.4 - AppleWebKit/537.36","Mozilla/5.0 (Linux; Android 4.4.4; Nexus 7 Build/KTU84P) AppleWebKit/537.36 (KHTML like Gecko) Chrome/36.0.1985.135 Safari/537.36","Chrome","36","Android","4.4.4"], ["Nexus One - Android 2.1 - Mobile Safari 530.17","Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17","Android Browser","4","Android","2.1"], ["Nexus One - Android 2.2 - Mobile Safari 533.1","Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1","Android Browser","4","Android","2.2"], @@ -270,6 +270,7 @@ var browsers = [ ["Samsung Galaxy - Android 1.5 - Mobile Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.5; de-de; Galaxy Build/CUPCAKE) AppleWebKit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1","Android Browser","3","Android","1.5"], ["Samsung Galaxy - Android 2.2 - Mobile Safari 533.1","Mozilla/5.0 (Linux; U; Android 2.2; en-ca; GT-P1000M Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1","Android Browser","4","Android","2.2"], ["Samsung GT-P7100 - Android 3.0.1 - AppleWebKit 534.13","Mozilla/5.0 (Linux; U; Android 3.0.1; en-us; GT-P7100 Build/HRI83) AppleWebkit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13","Android Browser","4","Android","3.0.1"], +["Samsung Galaxy - Android 6.0.1 - Mobile Safari 537.36", "Mozilla/5.0 (Linux; Android 6.0.1; SAMSUNG SM-G920I Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36","Chrome Mobile","44","Android","6.0.1"], ["T-Mobile G1 - Android 1.0 - Mobile Safari 523.12.2","Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2","Android Browser","3","Android","1.0"], ["T-Mobile G1 - Android 1.5 - Mobile Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.5; en-us; T-Mobile G1 Build/CRB43) AppleWebKit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari 525.20.1","Android Browser","3","Android","1.5"], ["T-Mobile G2 - Android 1.5 - Mobile Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.5; en-gb; T-Mobile_G2_Touch Build/CUPCAKE) AppleWebKit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1","Android Browser","3","Android","1.5"], @@ -286,4 +287,4 @@ var browsers = [ ["Wget 1.9.1","Wget/1.9.1",undefined,undefined,undefined,undefined], ["X10 - Android 1.6 - Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.6; es-es; SonyEricssonX10i Build/R1FA016) AppleWebKit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1","Android Browser","3","Android","1.6"], ["X10i - Android 1.6 - Mobile Safari 525.20.1","Mozilla/5.0 (Linux; U; Android 1.6; en-us; SonyEricssonX10i Build/R1AA056) AppleWebKit/528.5 (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1","Android Browser","3","Android","1.6"], -]; \ No newline at end of file +];