From 9013b15eee535ccf98404ab47f609e0520d675cc Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Mon, 16 Nov 2015 12:33:05 -0800 Subject: [PATCH 1/7] save initial referrer --- CHANGELOG.md | 2 + amplitude.js | 40 +++++++++++-- amplitude.min.js | 4 +- src/amplitude.js | 40 +++++++++++-- test/amplitude.js | 38 ++++++++++++ test/browser/amplitudejs.html | 5 +- test/browser/amplitudejs2.html | 102 +++++++++++++++++++++++++++++++++ 7 files changed, 215 insertions(+), 16 deletions(-) create mode 100644 test/browser/amplitudejs2.html diff --git a/CHANGELOG.md b/CHANGELOG.md index daabb6dc..ec9a34a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Add initial_referrer and initial_referring_domain user properties, which persist the initial referrer for the duration of the user's session. + ## 2.6.1 (November 6, 2015) * Localstorage is not persisted across subdomains, reverting cookie data migration and adding a reverse migration path for users already on 2.6.0. diff --git a/amplitude.js b/amplitude.js index 10eae763..330792cb 100644 --- a/amplitude.js +++ b/amplitude.js @@ -152,7 +152,9 @@ var LocalStorageKeys = { DEVICE_ID: 'amplitude_deviceId', USER_ID: 'amplitude_userId', - OPT_OUT: 'amplitude_optOut' + OPT_OUT: 'amplitude_optOut', + + INITIAL_REFERRER: 'amplitude_initialReferrer' }; /* @@ -243,6 +245,10 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) { this._initUtmData(); } + if (this.options.includeReferrer) { + this._saveInitialReferrer(document.referrer); + } + this._lastEventTime = parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME)) || null; this._sessionId = parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID)) || null; this._eventId = localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID) || 0; @@ -433,12 +439,30 @@ Amplitude.prototype._getReferrer = function() { return document.referrer; }; -Amplitude.prototype._getReferringDomain = function() { - var parts = this._getReferrer().split("/"); +Amplitude.prototype._getReferringDomain = function(referrer) { + var parts = referrer.split('/'); if (parts.length >= 3) { return parts[2]; } - return ""; + return ''; +}; + +Amplitude.prototype._saveInitialReferrer = function(initialReferrer) { + if (initialReferrer === '') { + return; + } + var hasSessionStorage = window.sessionStorage ? true : false; + if (hasSessionStorage && !window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)) { + window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER, initialReferrer); + } +}; + +Amplitude.prototype._getInitialReferrer = function() { + var hasSessionStorage = window.sessionStorage ? true : false; + if (hasSessionStorage) { + return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER) || ''; + } + return ''; }; Amplitude.prototype.saveEvents = function() { @@ -599,9 +623,13 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti // Add referral info onto the user properties if (this.options.includeReferrer) { + var referrer = this._getReferrer(); + var initialReferrer = this._getInitialReferrer(); object.merge(userProperties, { - 'referrer': this._getReferrer(), - 'referring_domain': this._getReferringDomain() + 'referrer': referrer, + 'referring_domain': this._getReferringDomain(referrer), + 'initial_referrer': initialReferrer, + 'initial_referring_domain': this._getReferringDomain(initialReferrer) }); } } diff --git a/amplitude.min.js b/amplitude.min.js index 97046088..aa30bce9 100644 --- a/amplitude.min.js +++ b/amplitude.min.js @@ -1,2 +1,2 @@ -(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(){var parts=this._getReferrer().split("/");if(parts.length>=3){return parts[2]}return""};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties);if(this.options.includeReferrer){object.merge(userProperties,{referrer:this._getReferrer(),referring_domain:this._getReferringDomain()})}}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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(xdr.responseText)};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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.1"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file +(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut",INITIAL_REFERRER:"amplitude_initialReferrer"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveInitialReferrer(document.referrer)}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return""};Amplitude.prototype._saveInitialReferrer=function(initialReferrer){if(initialReferrer===""){return}var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)){window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER,initialReferrer)}};Amplitude.prototype._getInitialReferrer=function(){var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage){return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)||""}return""};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties);if(this.options.includeReferrer){var referrer=this._getReferrer();var initialReferrer=this._getInitialReferrer();object.merge(userProperties,{referrer:referrer,referring_domain:this._getReferringDomain(referrer),initial_referrer:initialReferrer,initial_referring_domain:this._getReferringDomain(initialReferrer)})}}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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(xdr.responseText)};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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.1"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file diff --git a/src/amplitude.js b/src/amplitude.js index f9f4b440..60ad8e7f 100644 --- a/src/amplitude.js +++ b/src/amplitude.js @@ -46,7 +46,9 @@ var LocalStorageKeys = { DEVICE_ID: 'amplitude_deviceId', USER_ID: 'amplitude_userId', - OPT_OUT: 'amplitude_optOut' + OPT_OUT: 'amplitude_optOut', + + INITIAL_REFERRER: 'amplitude_initialReferrer' }; /* @@ -137,6 +139,10 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) { this._initUtmData(); } + if (this.options.includeReferrer) { + this._saveInitialReferrer(document.referrer); + } + this._lastEventTime = parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME)) || null; this._sessionId = parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID)) || null; this._eventId = localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID) || 0; @@ -327,12 +333,30 @@ Amplitude.prototype._getReferrer = function() { return document.referrer; }; -Amplitude.prototype._getReferringDomain = function() { - var parts = this._getReferrer().split("/"); +Amplitude.prototype._getReferringDomain = function(referrer) { + var parts = referrer.split('/'); if (parts.length >= 3) { return parts[2]; } - return ""; + return ''; +}; + +Amplitude.prototype._saveInitialReferrer = function(initialReferrer) { + if (initialReferrer === '') { + return; + } + var hasSessionStorage = window.sessionStorage ? true : false; + if (hasSessionStorage && !window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)) { + window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER, initialReferrer); + } +}; + +Amplitude.prototype._getInitialReferrer = function() { + var hasSessionStorage = window.sessionStorage ? true : false; + if (hasSessionStorage) { + return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER) || ''; + } + return ''; }; Amplitude.prototype.saveEvents = function() { @@ -493,9 +517,13 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti // Add referral info onto the user properties if (this.options.includeReferrer) { + var referrer = this._getReferrer(); + var initialReferrer = this._getInitialReferrer(); object.merge(userProperties, { - 'referrer': this._getReferrer(), - 'referring_domain': this._getReferringDomain() + 'referrer': referrer, + 'referring_domain': this._getReferringDomain(referrer), + 'initial_referrer': initialReferrer, + 'initial_referring_domain': this._getReferringDomain(initialReferrer) }); } } diff --git a/test/amplitude.js b/test/amplitude.js index 8354b3df..180c6a80 100644 --- a/test/amplitude.js +++ b/test/amplitude.js @@ -26,6 +26,7 @@ describe('Amplitude', function() { function reset() { localStorage.clear(); + sessionStorage.clear(); cookie.remove(amplitude.options.cookieName); cookie.reset(); } @@ -1356,6 +1357,8 @@ describe('Amplitude', function() { assert.lengthOf(server.requests, 1); var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); assert.deepEqual(events[0].user_properties, { + initial_referrer: '', + initial_referring_domain: '', referrer: 'https://amplitude.com/contact', referring_domain: 'amplitude.com' }); @@ -1380,10 +1383,45 @@ describe('Amplitude', function() { assert.lengthOf(server.requests, 2); var events = JSON.parse(querystring.parse(server.requests[1].requestBody).e); assert.deepEqual(events[0].user_properties, { + initial_referrer: '', + initial_referring_domain: '', referrer: 'https://amplitude.com/contact', referring_domain: 'amplitude.com' }); }); + + it('should grab initial referrer data from session storage', function() { + reset(); + sessionStorage.setItem('amplitude_initialReferrer', 'https://www.google.com/search?'); + amplitude.init(apiKey, undefined, {includeReferrer: true}); + + amplitude.logEvent('Referrer Test Event', {}); + assert.lengthOf(server.requests, 1); + var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); + assert.deepEqual(events[0].user_properties, { + initial_referrer: 'https://www.google.com/search?', + initial_referring_domain: 'www.google.com', + referrer: 'https://amplitude.com/contact', + referring_domain: 'amplitude.com' + }); + }); + + it('should not override any existing initial referrer values in session storage', function() { + reset(); + sessionStorage.setItem('amplitude_initialReferrer', 'https://www.google.com/search?'); + amplitude.init(apiKey, undefined, {includeReferrer: true}); + amplitude._saveInitialReferrer('https://amplitude.com/contact'); + + amplitude.logEvent('Referrer Test Event', {}); + assert.lengthOf(server.requests, 1); + var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); + assert.deepEqual(events[0].user_properties, { + initial_referrer: 'https://www.google.com/search?', + initial_referring_domain: 'www.google.com', + referrer: 'https://amplitude.com/contact', + referring_domain: 'amplitude.com' + }); + }) }); describe('logRevenue', function() { diff --git a/test/browser/amplitudejs.html b/test/browser/amplitudejs.html index a7eabeba..99d53c56 100644 --- a/test/browser/amplitudejs.html +++ b/test/browser/amplitudejs.html @@ -70,7 +70,7 @@ } + + +

Amplitude JS Test

+
    +
  • Set user ID
  • +
  • Toggle opt out
  • +
  • Log event
  • +
  • Log + event with event properties
  • +
  • Set user properties
  • +
  • Toggle batch events
  • +
  • Set event upload threshold
  • +
  • Click on link A
  • +

    Testing Identify calls
    +
  • Add to photo count
  • +
  • Unset photo count
  • +
  • Set photo count
  • +
  • Set photo count once
  • +
  • Set city via setUserProperties
  • +

    +
  • Go to first page
  • + + From a2838f78550804d4fc0e038d32930a10f647e3a3 Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Mon, 16 Nov 2015 12:36:33 -0800 Subject: [PATCH 2/7] updated tests --- amplitude.js | 2 +- amplitude.min.js | 2 +- src/amplitude.js | 2 +- test/amplitude.js | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/amplitude.js b/amplitude.js index 330792cb..72d43e53 100644 --- a/amplitude.js +++ b/amplitude.js @@ -246,7 +246,7 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) { } if (this.options.includeReferrer) { - this._saveInitialReferrer(document.referrer); + this._saveInitialReferrer(this._getReferrer()); } this._lastEventTime = parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME)) || null; diff --git a/amplitude.min.js b/amplitude.min.js index aa30bce9..fd81fa1b 100644 --- a/amplitude.min.js +++ b/amplitude.min.js @@ -1,2 +1,2 @@ -(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut",INITIAL_REFERRER:"amplitude_initialReferrer"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveInitialReferrer(document.referrer)}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return""};Amplitude.prototype._saveInitialReferrer=function(initialReferrer){if(initialReferrer===""){return}var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)){window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER,initialReferrer)}};Amplitude.prototype._getInitialReferrer=function(){var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage){return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)||""}return""};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties);if(this.options.includeReferrer){var referrer=this._getReferrer();var initialReferrer=this._getInitialReferrer();object.merge(userProperties,{referrer:referrer,referring_domain:this._getReferringDomain(referrer),initial_referrer:initialReferrer,initial_referring_domain:this._getReferringDomain(initialReferrer)})}}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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;ithis.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return""};Amplitude.prototype._saveInitialReferrer=function(initialReferrer){if(initialReferrer===""){return}var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)){window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER,initialReferrer)}};Amplitude.prototype._getInitialReferrer=function(){var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage){return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)||""}return""};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties);if(this.options.includeReferrer){var referrer=this._getReferrer();var initialReferrer=this._getInitialReferrer();object.merge(userProperties,{referrer:referrer,referring_domain:this._getReferringDomain(referrer),initial_referrer:initialReferrer,initial_referring_domain:this._getReferringDomain(initialReferrer)})}}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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(xdr.responseText)};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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.1"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file diff --git a/src/amplitude.js b/src/amplitude.js index 60ad8e7f..86e1a860 100644 --- a/src/amplitude.js +++ b/src/amplitude.js @@ -140,7 +140,7 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) { } if (this.options.includeReferrer) { - this._saveInitialReferrer(document.referrer); + this._saveInitialReferrer(this._getReferrer()); } this._lastEventTime = parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME)) || null; diff --git a/test/amplitude.js b/test/amplitude.js index 180c6a80..883e7c6d 100644 --- a/test/amplitude.js +++ b/test/amplitude.js @@ -1357,8 +1357,8 @@ describe('Amplitude', function() { assert.lengthOf(server.requests, 1); var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); assert.deepEqual(events[0].user_properties, { - initial_referrer: '', - initial_referring_domain: '', + initial_referrer: 'https://amplitude.com/contact', + initial_referring_domain: 'amplitude.com', referrer: 'https://amplitude.com/contact', referring_domain: 'amplitude.com' }); @@ -1383,8 +1383,8 @@ describe('Amplitude', function() { assert.lengthOf(server.requests, 2); var events = JSON.parse(querystring.parse(server.requests[1].requestBody).e); assert.deepEqual(events[0].user_properties, { - initial_referrer: '', - initial_referring_domain: '', + initial_referrer: 'https://amplitude.com/contact', + initial_referring_domain: 'amplitude.com', referrer: 'https://amplitude.com/contact', referring_domain: 'amplitude.com' }); From 57989ae04febe2ad97ff47c9bf964e7f87492c93 Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Tue, 24 Nov 2015 17:34:51 -0800 Subject: [PATCH 3/7] only send referrer once per session and not with events --- amplitude.js | 49 ++++++++++----------- amplitude.min.js | 4 +- src/amplitude.js | 49 ++++++++++----------- test/amplitude.js | 108 ++++++++++++++++++++++++++-------------------- 4 files changed, 109 insertions(+), 101 deletions(-) diff --git a/amplitude.js b/amplitude.js index 72d43e53..8e679286 100644 --- a/amplitude.js +++ b/amplitude.js @@ -154,7 +154,7 @@ var LocalStorageKeys = { USER_ID: 'amplitude_userId', OPT_OUT: 'amplitude_optOut', - INITIAL_REFERRER: 'amplitude_initialReferrer' + REFERRER: 'amplitude_referrer' }; /* @@ -246,7 +246,7 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) { } if (this.options.includeReferrer) { - this._saveInitialReferrer(this._getReferrer()); + this._saveReferrer(this._getReferrer()); } this._lastEventTime = parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME)) || null; @@ -440,29 +440,38 @@ Amplitude.prototype._getReferrer = function() { }; Amplitude.prototype._getReferringDomain = function(referrer) { + if (referrer === null || referrer === undefined || referrer === '') { + return null; + } var parts = referrer.split('/'); if (parts.length >= 3) { return parts[2]; } - return ''; + return null; }; -Amplitude.prototype._saveInitialReferrer = function(initialReferrer) { - if (initialReferrer === '') { +// since user properties are propagated on the server, only send once per session, don't need to send with every event +Amplitude.prototype._saveReferrer = function(referrer) { + if (referrer === null || referrer === undefined || referrer === '') { return; } - var hasSessionStorage = window.sessionStorage ? true : false; - if (hasSessionStorage && !window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)) { - window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER, initialReferrer); - } -}; -Amplitude.prototype._getInitialReferrer = function() { + // always setOnce initial referrer + var referring_domain = this._getReferringDomain(referrer); + var identify = new Identify().setOnce('initial_referrer', referrer); + identify.setOnce('initial_referring_domain', referring_domain); + + // only save referrer if not already in session storage or if storage disabled var hasSessionStorage = window.sessionStorage ? true : false; - if (hasSessionStorage) { - return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER) || ''; + if ((hasSessionStorage && !window.sessionStorage.getItem(LocalStorageKeys.REFERRER)) || !hasSessionStorage) { + identify.set('referrer', referrer).set('referring_domain', referring_domain); + + if (hasSessionStorage) { + window.sessionStorage.setItem(LocalStorageKeys.REFERRER, referrer); + } } - return ''; + + this.identify(identify); }; Amplitude.prototype.saveEvents = function() { @@ -620,18 +629,6 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti // Only add utm properties to user properties for events if (eventType !== IDENTIFY_EVENT) { object.merge(userProperties, this._utmProperties); - - // Add referral info onto the user properties - if (this.options.includeReferrer) { - var referrer = this._getReferrer(); - var initialReferrer = this._getInitialReferrer(); - object.merge(userProperties, { - 'referrer': referrer, - 'referring_domain': this._getReferringDomain(referrer), - 'initial_referrer': initialReferrer, - 'initial_referring_domain': this._getReferringDomain(initialReferrer) - }); - } } apiProperties = apiProperties || {}; diff --git a/amplitude.min.js b/amplitude.min.js index fd81fa1b..13220b3b 100644 --- a/amplitude.min.js +++ b/amplitude.min.js @@ -1,2 +1,2 @@ -(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut",INITIAL_REFERRER:"amplitude_initialReferrer"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveInitialReferrer(this._getReferrer())}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return""};Amplitude.prototype._saveInitialReferrer=function(initialReferrer){if(initialReferrer===""){return}var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)){window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER,initialReferrer)}};Amplitude.prototype._getInitialReferrer=function(){var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage){return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)||""}return""};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties);if(this.options.includeReferrer){var referrer=this._getReferrer();var initialReferrer=this._getInitialReferrer();object.merge(userProperties,{referrer:referrer,referring_domain:this._getReferringDomain(referrer),initial_referrer:initialReferrer,initial_referring_domain:this._getReferringDomain(initialReferrer)})}}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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(xdr.responseText)};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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.1"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file +(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut",REFERRER:"amplitude_referrer"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveReferrer(this._getReferrer())}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return null}var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return null};Amplitude.prototype._saveReferrer=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return}var referring_domain=this._getReferringDomain(referrer);var identify=(new Identify).setOnce("initial_referrer",referrer);identify.setOnce("initial_referring_domain",referring_domain);var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.REFERRER)||!hasSessionStorage){identify.set("referrer",referrer).set("referring_domain",referring_domain);if(hasSessionStorage){window.sessionStorage.setItem(LocalStorageKeys.REFERRER,referrer)}}this.identify(identify)};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties)}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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(xdr.responseText)};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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.1"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file diff --git a/src/amplitude.js b/src/amplitude.js index 86e1a860..a0102785 100644 --- a/src/amplitude.js +++ b/src/amplitude.js @@ -48,7 +48,7 @@ var LocalStorageKeys = { USER_ID: 'amplitude_userId', OPT_OUT: 'amplitude_optOut', - INITIAL_REFERRER: 'amplitude_initialReferrer' + REFERRER: 'amplitude_referrer' }; /* @@ -140,7 +140,7 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) { } if (this.options.includeReferrer) { - this._saveInitialReferrer(this._getReferrer()); + this._saveReferrer(this._getReferrer()); } this._lastEventTime = parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME)) || null; @@ -334,29 +334,38 @@ Amplitude.prototype._getReferrer = function() { }; Amplitude.prototype._getReferringDomain = function(referrer) { + if (referrer === null || referrer === undefined || referrer === '') { + return null; + } var parts = referrer.split('/'); if (parts.length >= 3) { return parts[2]; } - return ''; + return null; }; -Amplitude.prototype._saveInitialReferrer = function(initialReferrer) { - if (initialReferrer === '') { +// since user properties are propagated on the server, only send once per session, don't need to send with every event +Amplitude.prototype._saveReferrer = function(referrer) { + if (referrer === null || referrer === undefined || referrer === '') { return; } - var hasSessionStorage = window.sessionStorage ? true : false; - if (hasSessionStorage && !window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER)) { - window.sessionStorage.setItem(LocalStorageKeys.INITIAL_REFERRER, initialReferrer); - } -}; -Amplitude.prototype._getInitialReferrer = function() { + // always setOnce initial referrer + var referring_domain = this._getReferringDomain(referrer); + var identify = new Identify().setOnce('initial_referrer', referrer); + identify.setOnce('initial_referring_domain', referring_domain); + + // only save referrer if not already in session storage or if storage disabled var hasSessionStorage = window.sessionStorage ? true : false; - if (hasSessionStorage) { - return window.sessionStorage.getItem(LocalStorageKeys.INITIAL_REFERRER) || ''; + if ((hasSessionStorage && !window.sessionStorage.getItem(LocalStorageKeys.REFERRER)) || !hasSessionStorage) { + identify.set('referrer', referrer).set('referring_domain', referring_domain); + + if (hasSessionStorage) { + window.sessionStorage.setItem(LocalStorageKeys.REFERRER, referrer); + } } - return ''; + + this.identify(identify); }; Amplitude.prototype.saveEvents = function() { @@ -514,18 +523,6 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti // Only add utm properties to user properties for events if (eventType !== IDENTIFY_EVENT) { object.merge(userProperties, this._utmProperties); - - // Add referral info onto the user properties - if (this.options.includeReferrer) { - var referrer = this._getReferrer(); - var initialReferrer = this._getInitialReferrer(); - object.merge(userProperties, { - 'referrer': referrer, - 'referring_domain': this._getReferringDomain(referrer), - 'initial_referrer': initialReferrer, - 'initial_referring_domain': this._getReferringDomain(initialReferrer) - }); - } } apiProperties = apiProperties || {}; diff --git a/test/amplitude.js b/test/amplitude.js index 883e7c6d..3f7adecd 100644 --- a/test/amplitude.js +++ b/test/amplitude.js @@ -1349,79 +1349,93 @@ describe('Amplitude', function() { assert.equal(events[0].user_properties.referring_domain, undefined); }); - it('should send referrer data when the includeReferrer flag is true', function() { + it('should only send referrer via identify call when the includeReferrer flag is true', function() { reset(); - amplitude.init(apiKey, undefined, {includeReferrer: true}); - + amplitude.init(apiKey, undefined, {includeReferrer: true, batchEvents: true, eventUploadThreshold: 2}); amplitude.logEvent('Referrer Test Event', {}); assert.lengthOf(server.requests, 1); var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); - assert.deepEqual(events[0].user_properties, { - initial_referrer: 'https://amplitude.com/contact', - initial_referring_domain: 'amplitude.com', - referrer: 'https://amplitude.com/contact', - referring_domain: 'amplitude.com' - }); - }); - - it('should add referrer data to the user properties on events only', function() { - reset(); - amplitude.init(apiKey, undefined, {includeReferrer: true}); + assert.lengthOf(events, 2); - amplitude.setUserProperties({user_prop: true}); - assert.lengthOf(server.requests, 1); - var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); + // first event should be identify with initial_referrer and referrer + assert.equal(events[0].event_type, '$identify'); assert.deepEqual(events[0].user_properties, { - $set: { - 'user_prop': true + '$set': { + 'referrer': 'https://amplitude.com/contact', + 'referring_domain': 'amplitude.com' + }, + '$setOnce': { + 'initial_referrer': 'https://amplitude.com/contact', + 'initial_referring_domain': 'amplitude.com' } }); - server.respondWith('success'); - server.respond(); - amplitude.logEvent('Referrer test event'); - assert.lengthOf(server.requests, 2); - var events = JSON.parse(querystring.parse(server.requests[1].requestBody).e); - assert.deepEqual(events[0].user_properties, { - initial_referrer: 'https://amplitude.com/contact', - initial_referring_domain: 'amplitude.com', - referrer: 'https://amplitude.com/contact', - referring_domain: 'amplitude.com' - }); + // second event should be the test event with no referrer information + assert.equal(events[1].event_type, 'Referrer Test Event'); + assert.deepEqual(events[1].user_properties, {}); + + // referrer should be propagated to session storage + assert.equal(sessionStorage.getItem('amplitude_referrer'), 'https://amplitude.com/contact'); }); - it('should grab initial referrer data from session storage', function() { + it('should not set referrer if referrer data already in session storage', function() { reset(); - sessionStorage.setItem('amplitude_initialReferrer', 'https://www.google.com/search?'); - amplitude.init(apiKey, undefined, {includeReferrer: true}); - + sessionStorage.setItem('amplitude_referrer', 'https://www.google.com/search?'); + amplitude.init(apiKey, undefined, {includeReferrer: true, batchEvents: true, eventUploadThreshold: 2}); amplitude.logEvent('Referrer Test Event', {}); assert.lengthOf(server.requests, 1); var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); + assert.lengthOf(events, 2); + + // first event should be identify with initial_referrer and NO referrer + assert.equal(events[0].event_type, '$identify'); assert.deepEqual(events[0].user_properties, { - initial_referrer: 'https://www.google.com/search?', - initial_referring_domain: 'www.google.com', - referrer: 'https://amplitude.com/contact', - referring_domain: 'amplitude.com' + '$setOnce': { + 'initial_referrer': 'https://amplitude.com/contact', + 'initial_referring_domain': 'amplitude.com' + } }); + + // second event should be the test event with no referrer information + assert.equal(events[1].event_type, 'Referrer Test Event'); + assert.deepEqual(events[1].user_properties, {}); }); it('should not override any existing initial referrer values in session storage', function() { reset(); - sessionStorage.setItem('amplitude_initialReferrer', 'https://www.google.com/search?'); - amplitude.init(apiKey, undefined, {includeReferrer: true}); - amplitude._saveInitialReferrer('https://amplitude.com/contact'); - + sessionStorage.setItem('amplitude_referrer', 'https://www.google.com/search?'); + amplitude.init(apiKey, undefined, {includeReferrer: true, batchEvents: true, eventUploadThreshold: 3}); + amplitude._saveReferrer('https://facebook.com/contact'); amplitude.logEvent('Referrer Test Event', {}); assert.lengthOf(server.requests, 1); var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e); + assert.lengthOf(events, 3); + + // first event should be identify with initial_referrer and NO referrer + assert.equal(events[0].event_type, '$identify'); assert.deepEqual(events[0].user_properties, { - initial_referrer: 'https://www.google.com/search?', - initial_referring_domain: 'www.google.com', - referrer: 'https://amplitude.com/contact', - referring_domain: 'amplitude.com' + '$setOnce': { + 'initial_referrer': 'https://amplitude.com/contact', + 'initial_referring_domain': 'amplitude.com' + } }); - }) + + // second event should be another identify but with the new referrer + assert.equal(events[1].event_type, '$identify'); + assert.deepEqual(events[1].user_properties, { + '$setOnce': { + 'initial_referrer': 'https://facebook.com/contact', + 'initial_referring_domain': 'facebook.com' + } + }); + + // third event should be the test event with no referrer information + assert.equal(events[2].event_type, 'Referrer Test Event'); + assert.deepEqual(events[2].user_properties, {}); + + // existing value persists + assert.equal(sessionStorage.getItem('amplitude_referrer'), 'https://www.google.com/search?'); + }); }); describe('logRevenue', function() { From a2106d62238b7c47d9e29643646aeb6a53af417f Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Tue, 24 Nov 2015 18:56:13 -0800 Subject: [PATCH 4/7] update changelog --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2add4b6..a337f643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,10 @@ ## Unreleased -<<<<<<< HEAD -* Add initial_referrer and initial_referring_domain user properties, which persist the initial referrer for the duration of the user's session. -======= +* Initial_referrer is captured as a setOnce, and referrer is only updated once per session; it is no longer sent with every event. + ## 2.6.2 (November 17, 2015) * Fix bug where response code is not passed to XDomainRequest callback (affects IE versions 10 and lower). ->>>>>>> origin/master ## 2.6.1 (November 6, 2015) From 65ca855dc2dbeac4e4c958919cc04d1508fa39bd Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Tue, 15 Dec 2015 13:43:20 -0800 Subject: [PATCH 5/7] update changelog and readme --- CHANGELOG.md | 2 +- README.md | 10 +++++++--- amplitude.js | 20 +++++++++++++++----- amplitude.min.js | 4 ++-- src/amplitude.js | 6 +++--- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a337f643..21d963de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Unreleased -* Initial_referrer is captured as a setOnce, and referrer is only updated once per session; it is no longer sent with every event. +* Add tracking of each user's initial_referrer property (which is captured as a set once operation). Referrer property captured once per user session. ## 2.6.2 (November 17, 2015) diff --git a/README.md b/README.md index d0eb5036..a77d56e3 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,11 @@ If your app has its own login system that you want to track users with, you can amplitude.setUserId('USER_ID_HERE'); ``` -A user's data will be merged on the backend so that any events up to that point from the same browser will be tracked under the same user. +A user's data will be merged on the backend so that any events up to that point from the same browser will be tracked under the same user. Note: if a user logs out, or you want to log the events under an anonymous user, you may set the userId to `null` like so: + +```javascript +amplitude.setUserId(null); // not string 'null' +``` You can also add the user ID as an argument to the `init` call: @@ -62,7 +66,7 @@ eventProperties.key = 'value'; amplitude.logEvent('EVENT_IDENTIFIER_HERE', eventProperties); ``` -# User Property Operations # +# User Properties and User Property Operations # The SDK supports the operations `set`, `setOnce`, `unset`, and `add` on individual user properties. The operations are declared via a provided `Identify` interface. Multiple operations can be chained together in a single `Identify` object. The `Identify` object is then passed to the Amplitude client to send to the server. The results of the operations will be visible immediately in the dashboard, and take effect for events logged after. @@ -169,7 +173,7 @@ amplitude.init('YOUR_API_KEY_HERE', null, { | savedMaxCount | Maximum number of events to save in localStorage. If more events are logged while offline, old events are removed. | 1000 | | uploadBatchSize | Maximum number of events to send to the server per request. | 100 | | includeUtm | If `true`, finds utm parameters in the query string or the __utmz cookie, parses, and includes them as user propeties on all events uploaded. | `false` | -| includeReferrer | If `true`, includes `referrer` and `referring_domain` as user propeties on all events uploaded. | `false` | +| includeReferrer | If `true`, captures the `referrer` and `referring_domain` for each session, as well as the user's `initial_referrer` and `initial_referring_domain` via a set once operation. | `false` | | batchEvents | If `true`, events are batched together and uploaded only when the number of unsent events is greater than or equal to `eventUploadThreshold` or after `eventUploadPeriodMillis` milliseconds have passed since the first unsent event was logged. | `false` | | eventUploadThreshold | Minimum number of events to batch together per request if `batchEvents` is `true`. | 30 | | eventUploadPeriodMillis | Amount of time in milliseconds that the SDK waits before uploading events if `batchEvents` is `true`. | 30\*1000 (30 sec) | diff --git a/amplitude.js b/amplitude.js index 68b150aa..c176d3b1 100644 --- a/amplitude.js +++ b/amplitude.js @@ -149,12 +149,12 @@ var LocalStorageKeys = { LAST_SEQUENCE_NUMBER: 'amplitude_lastSequenceNumber', LAST_EVENT_TIME: 'amplitude_lastEventTime', SESSION_ID: 'amplitude_sessionId', + REFERRER: 'amplitude_referrer', + // Used in cookie as well DEVICE_ID: 'amplitude_deviceId', USER_ID: 'amplitude_userId', - OPT_OUT: 'amplitude_optOut', - - REFERRER: 'amplitude_referrer' + OPT_OUT: 'amplitude_optOut' }; /* @@ -2441,15 +2441,25 @@ module.exports = function(val){ if (val !== val) return 'nan'; if (val && val.nodeType === 1) return 'element'; - if (typeof Buffer != 'undefined' && Buffer.isBuffer(val)) return 'buffer'; + if (isBuffer(val)) return 'buffer'; val = val.valueOf ? val.valueOf() - : Object.prototype.valueOf.apply(val) + : Object.prototype.valueOf.apply(val); return typeof val; }; +// code borrowed from https://github.com/feross/is-buffer/blob/master/index.js +function isBuffer(obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} + }, {}], 10: [function(require, module, exports) { /* jshint eqeqeq: false, forin: false */ diff --git a/amplitude.min.js b/amplitude.min.js index f6fe79d9..2fa4f467 100644 --- a/amplitude.min.js +++ b/amplitude.min.js @@ -1,2 +1,2 @@ -(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut",REFERRER:"amplitude_referrer"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveReferrer(this._getReferrer())}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return null}var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return null};Amplitude.prototype._saveReferrer=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return}var referring_domain=this._getReferringDomain(referrer);var identify=(new Identify).setOnce("initial_referrer",referrer);identify.setOnce("initial_referring_domain",referring_domain);var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.REFERRER)||!hasSessionStorage){identify.set("referrer",referrer).set("referring_domain",referring_domain);if(hasSessionStorage){window.sessionStorage.setItem(LocalStorageKeys.REFERRER,referrer)}}this.identify(identify)};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties)}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.2"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file +(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 instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var Cookie=require("./cookie");var JSON=require("json");var language=require("./language");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var UAParser=require("ua-parser-js");var UUID=require("./uuid");var version=require("./version");var Identify=require("./identify");var type=require("./type");var log=function(s){console.log("[Amplitude] "+s)};var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var DEFAULT_OPTIONS={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,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};var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",LAST_EVENT_TIME:"amplitude_lastEventTime",SESSION_ID:"amplitude_sessionId",REFERRER:"amplitude_referrer",DEVICE_ID:"amplitude_deviceId",USER_ID:"amplitude_userId",OPT_OUT:"amplitude_optOut"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}Cookie.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=Cookie.options().domain;_migrateLocalStorageDataToCookie(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;_saveCookieData(this);if(this.options.saveEvents){this._loadSavedUnsentEvents(this.options.unsentKey,"_unsentEvents");this._loadSavedUnsentEvents(this.options.unsentIdentifyKey,"_unsentIdentifys")}this._sendEventsIfReady();if(this.options.includeUtm){this._initUtmData()}if(this.options.includeReferrer){this._saveReferrer(this._getReferrer())}this._lastEventTime=parseInt(localStorage.getItem(LocalStorageKeys.LAST_EVENT_TIME))||null;this._sessionId=parseInt(localStorage.getItem(LocalStorageKeys.SESSION_ID))||null;this._eventId=localStorage.getItem(LocalStorageKeys.LAST_EVENT_ID)||0;this._identifyId=localStorage.getItem(LocalStorageKeys.LAST_IDENTIFY_ID)||0;this._sequenceNumber=localStorage.getItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER)||0;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=now;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime)}catch(e){log(e)}if(callback&&type(callback)==="function"){callback()}};Amplitude.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};var _migrateLocalStorageDataToCookie=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId){return}var cookieDeviceId=cookieData&&cookieData.deviceId||null;var cookieUserId=cookieData&&cookieData.userId||null;var cookieOptOut=cookieData&&cookieData.optOut!==null&&cookieData.optOut!==undefined?cookieData.optOut:null;var keySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=localStorage.getItem(LocalStorageKeys.DEVICE_ID+keySuffix);if(localStorageDeviceId){localStorage.removeItem(LocalStorageKeys.DEVICE_ID+keySuffix)}var localStorageUserId=localStorage.getItem(LocalStorageKeys.USER_ID+keySuffix);if(localStorageUserId){localStorage.removeItem(LocalStorageKeys.USER_ID+keySuffix)}var localStorageOptOut=localStorage.getItem(LocalStorageKeys.OPT_OUT+keySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorage.removeItem(LocalStorageKeys.OPT_OUT+keySuffix);localStorageOptOut=String(localStorageOptOut)==="true"}Cookie.set(scope.options.cookieName,{deviceId:cookieDeviceId||localStorageDeviceId,userId:cookieUserId||localStorageUserId,optOut:cookieOptOut!==undefined&&cookieOptOut!==null?cookieOptOut:localStorageOptOut})};var _loadCookieData=function(scope){var cookieData=Cookie.get(scope.options.cookieName);if(cookieData){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}}};var _saveCookieData=function(scope){Cookie.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut})};Amplitude._getUtmParam=function(name,query){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)");var results=regex.exec(query);return results===null?undefined:decodeURIComponent(results[1].replace(/\+/g," "))};Amplitude._getUtmData=function(rawCookie,query){var cookie=rawCookie?"?"+rawCookie.split(".").slice(-1)[0].replace(/\|/g,"&"):"";var fetchParam=function(queryName,query,cookieName,cookie){return Amplitude._getUtmParam(queryName,query)||Amplitude._getUtmParam(cookieName,cookie)};return{utm_source:fetchParam("utm_source",query,"utmcsr",cookie),utm_medium:fetchParam("utm_medium",query,"utmcmd",cookie),utm_campaign:fetchParam("utm_campaign",query,"utmccn",cookie),utm_term:fetchParam("utm_term",query,"utmctr",cookie),utm_content:fetchParam("utm_content",query,"utmcct",cookie)}};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||Cookie.get("__utmz");this._utmProperties=Amplitude._getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return null}var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return null};Amplitude.prototype._saveReferrer=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return}var referring_domain=this._getReferringDomain(referrer);var identify=(new Identify).setOnce("initial_referrer",referrer);identify.setOnce("initial_referring_domain",referring_domain);var hasSessionStorage=window.sessionStorage?true:false;if(hasSessionStorage&&!window.sessionStorage.getItem(LocalStorageKeys.REFERRER)||!hasSessionStorage){identify.set("referrer",referrer).set("referring_domain",referring_domain);if(hasSessionStorage){window.sessionStorage.setItem(LocalStorageKeys.REFERRER,referrer)}}this.identify(identify)};Amplitude.prototype.saveEvents=function(){try{localStorage.setItem(this.options.unsentKey,JSON.stringify(this._unsentEvents));localStorage.setItem(this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){try{Cookie.options({domain:domain});this.options.domain=Cookie.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setUserId=function(userId){try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setOptOut=function(enable){try{this.options.optOut=enable;_saveCookieData(this)}catch(e){log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.identify=function(identify){if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations)}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId();localStorage.setItem(LocalStorageKeys.LAST_IDENTIFY_ID,eventId)}else{eventId=this.nextEventId();localStorage.setItem(LocalStorageKeys.LAST_EVENT_ID,eventId)}var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime;localStorage.setItem(LocalStorageKeys.SESSION_ID,this._sessionId)}this._lastEventTime=eventTime;localStorage.setItem(LocalStorageKeys.LAST_EVENT_TIME,this._lastEventTime);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties)}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,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:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(eventProperties),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:this.__VERSION__},sequence_number:this.nextSequenceNumber()};if(eventType===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)&&callback){callback(0,"No request sent")}return eventId}catch(e){log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+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:API_VERSION,upload_time:uploadTime,checksum:md5(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)&&callback){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(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){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":17}],17:[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},{}],4:[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":18}],18:[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;i>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)},{}],8:[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)}},{}],9:[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:20}],20:[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},{}],12:[function(require,module,exports){module.exports="2.6.2"},{}],13:[function(require,module,exports){var type=require("./type");var AMP_OP_ADD="$add";var AMP_OP_SET="$set";var AMP_OP_SET_ONCE="$setOnce";var AMP_OP_UNSET="$unset";var log=function(s){console.log("[Amplitude] "+s)};var Identify=function(){this.userPropertiesOperations={};this.properties=[]};Identify.prototype.add=function(property,value){if(type(value)==="number"||type(value)==="string"){this._addOperation(AMP_OP_ADD,property,value)}else{log("Unsupported type for value: "+type(value)+", expecting number or string")}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.properties.indexOf(property)!==-1){log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!(operation in this.userPropertiesOperations)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":14}],14:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}]},{},{1:""})); \ No newline at end of file diff --git a/src/amplitude.js b/src/amplitude.js index a0102785..d3bec102 100644 --- a/src/amplitude.js +++ b/src/amplitude.js @@ -43,12 +43,12 @@ var LocalStorageKeys = { LAST_SEQUENCE_NUMBER: 'amplitude_lastSequenceNumber', LAST_EVENT_TIME: 'amplitude_lastEventTime', SESSION_ID: 'amplitude_sessionId', + REFERRER: 'amplitude_referrer', + // Used in cookie as well DEVICE_ID: 'amplitude_deviceId', USER_ID: 'amplitude_userId', - OPT_OUT: 'amplitude_optOut', - - REFERRER: 'amplitude_referrer' + OPT_OUT: 'amplitude_optOut' }; /* From a6bcf1794af1fc073d3297e3208a5e7d801ada2c Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Tue, 15 Dec 2015 14:08:08 -0800 Subject: [PATCH 6/7] update snippet for second test page --- test/browser/amplitudejs2.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/browser/amplitudejs2.html b/test/browser/amplitudejs2.html index 061e630e..7062006a 100644 --- a/test/browser/amplitudejs2.html +++ b/test/browser/amplitudejs2.html @@ -16,7 +16,7 @@ this._q.push([fn].concat(Array.prototype.slice.call(arguments, 0))); return this; }; } - var identifyFuncs = ['add', 'set', 'setOnce', 'unset']; + var identifyFuncs = ['add', 'append', 'set', 'setOnce', 'unset']; for (var i = 0; i < identifyFuncs.length; i++) { proxyIdentify(identifyFuncs[i]); } From 1c041a54736e57cc3d75616b9efb5bf6e017f503 Mon Sep 17 00:00:00 2001 From: Daniel Jih Date: Tue, 15 Dec 2015 14:22:17 -0800 Subject: [PATCH 7/7] update readme --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 6b16a19d..192ae1e9 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,18 @@ var identify = new amplitude.Identify() amplitude.identify(identify); ``` +### Arrays in User Properties ### + +The SDK supports arrays in user properties. Any of the user property operations above (with the exception of `add`) can accept a Javascript array. You can directly `set` arrays, or use `append` to generate an array. + +```javascript +var identify = new amplitude.Identify() + .set('colors', ['rose', 'gold']) + .append('ab-tests', 'campaign_a') + .append('existing_list', [4, 5]); +amplitude.identify(identify); +``` + ### Setting Multiple Properties with `setUserProperties` ### You may use `setUserProperties` shorthand to set multiple user properties at once. This method is simply a wrapper around `Identify.set` and `identify`.