Skip to content

Instantly share code, notes, and snippets.

@zhangmx
Last active March 20, 2020 06:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhangmx/0927215b4cb4dc3ee1d8ddc81af2a3a3 to your computer and use it in GitHub Desktop.
Save zhangmx/0927215b4cb4dc3ee1d8ddc81af2a3a3 to your computer and use it in GitHub Desktop.
(function () {
//统计请求的地址
var iAnalyseBaseURL = 'www.google-analytics.com';
//脚本加载的地址
var iScriptBaseURL = 'www.google-analytics.com';
//Ad脚本地址
var iAdBaseURL = 'stats.g.doubleclick.net';
//Inpage 脚本地址
var iInpageURL = 'https://www.google.com/analytics/web/inpage/pub/inpage.js?';
//GTM 地址
/**
* 获取GA请求源的地址
*
* 统计代码的地址
*
*
*
*/
var getGAOriginUrl = function () {
//TODO change URL
return (forceHTTPS || isHTTPS() ? "https:" : "http:") + "//" + iAnalyseBaseURL
};
/**
* 记录方法使用情况的类
* @param {Array.<boolean>} umMap 初始的使用情况
*/
var UsageManager = function (umMap) {
this.w = umMap || []
};
/**
* 记录新的使用情况
* @param {number} idx 特殊代码,指定某一种方法或情形的被调用或触发
*/
UsageManager.prototype.set = function (idx) {
this.w[idx] = !0
};
/**
* 生成代表使用情况的字符串传给后端
* @return {string}
*/
UsageManager.prototype.encode = function () {
for (var a = [], b = 0; b < this.w.length; b++)
this.w[b] && (a[Math.floor(b / 6)] ^= 1 << b % 6);
for (b = 0; b < a.length; b++)
a[b] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(a[b] || 0);
return a.join("") + "~"
};
/**
* 解码的函数,是mmzhou所写,非GA源码
* @param {string} um
* @return {Array.<number>}
*/
//$c.prototype.decode = function(um) {
// um = um.slice(0, -1);
// var key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
// var code;
// var binaryCode;
// var reversedbinaryCode;
// var codes = [];
// for (var i = 0; i < um.length; i++) {
// code = key.indexOf(um.charAt(i));
// binaryCode = code.toString(2);
// reversedbinaryCode = binaryCode.split('').reverse();
// // console.log(i + '=' + code + '=' + binaryCode + '=reverse(' + reversedbinaryCode + ')');
// for (var j = 0; j < reversedbinaryCode.length; j++) {
// if (reversedbinaryCode[j] === '1') {
// codes.push(j + 6 * i);
// }
// }
// }
// return codes;
//};
/**
* 全局的记录方法使用情况的对象
*/
var globalUM = new UsageManager;
/**
* 快捷的记录使用情况的方法
* @return {string}
*/
function reg(num) {
globalUM.set(num)
}
/**
* 更新传入配置的 USAGE_MANAGER
*/
var setModelUM = function (model, idx) {
var um = new UsageManager(getCurUM(model));
um.set(idx);
model.set(USAGE_MANAGER, um.w)
};
/**
* 获取指定model里面的 USAGE_MANAGER 值,然后和全局的 globalUM 合并,然后encode
* @return {string}
*/
var mergeAndEncodeUM = function (model) {
var umArray = getCurUM(model);
var modelUM = new UsageManager(umArray);
for (var globalUMCopy = globalUM.w.slice(), i = 0; i < modelUM.w.length; i++)
globalUMCopy[i] = globalUMCopy[i] || modelUM.w[i];
return (new UsageManager(globalUMCopy)).encode()
};
/**
* 获取配置中的USAGE_MANAGER,如果没有则返回空数组
*/
var getCurUM = function (model) {
var umArray = model.get(USAGE_MANAGER);
isArray(umArray) || (umArray = []);
return umArray
};
/**
* isFunction
* */
var isFunction = function (tarIsFunction) {
return "function" == typeof tarIsFunction
};
/**
* isArray
*/
var isArray = function (ar) {
return "[object Array]" == Object.prototype.toString.call(Object(ar))
};
/**
* isString
*/
var isString = function (tarIsString) {
return void 0 != tarIsString && -1 < (tarIsString.constructor + "").indexOf("String")
};
/**
* startWith
*
* @return {boolean}
*/
var startWith = function (str, tar) {
return 0 == str.indexOf(tar)
};
/**
* filter a with space trim
*/
var trim = function (str) {
return str ? str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, "") : ""
};
/**
* create 1*1 img createImg
*/
var createImg = function (imgLink) {
var b = idoc.createElement("img");
b.width = 1;
b.height = 1;
b.src = imgLink;
return b
};
/**
* empty function
* emptyFunction
*/
var emptyFunction = function () {
};
/**
*
* Encodes a text string as a valid component of a Uniform Resource Identifier (URI).
*
* iEncodeURIComponent
*
*/
var iEncodeURIComponent = function (uri) {
if (encodeURIComponent instanceof Function)
return encodeURIComponent(uri);
reg(28);
return uri
};
/**
* 为a添加一个b事件的c方法回调
*
* iAddEventListener
*
*/
var iAddEventListener = function (element, eName, callback, d) {
try {
element.addEventListener ? element.addEventListener(eName, callback, !!d) : element.attachEvent && element.attachEvent("on" + eName, callback)
} catch (e) {
reg(27)
}
};
/**
* reg
*/
var f = /^[\w\-:/.?=&%!]+$/;
/**
* 创建一个脚本在页面上 g.js
*
* loadScript
* url,id,script
*/
var loadScript = function (url, id, c) {
url && (c ?
(
c = "",
id && f.test(id) && (c = ' id="' + id + '"'),
f.test(url) && idoc.write("<script" + c + ' src="' + url + '">\x3c/script>')
) :
(
c = idoc.createElement("script"),
c.type = "text/javascript",
c.async = !0,
c.src = url,
id && (c.id = id),
url = idoc.getElementsByTagName("script")[0],
url.parentNode.insertBefore(c, url)
)
)
};
/**
* check protocol is or not https
*
* isHTTPS
*/
var isHTTPS = function () {
return "https:" == idoc.location.protocol
};
/**
* 返回url中name参数对应的值
* @param url
* @param name
* @returns {string}
*/
var getUrlParamVal = function (url, name) {
var matched = url.match("(?:&|#|\\?)" + iEncodeURIComponent(name).replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") + "=([^&#]*)");
return matched && 2 == matched.length ? matched[1] : ""
};
/**
* 不带 www的域名
* getHostname
*/
var getHostName = function () {
var a = "" + idoc.location.hostname;
return 0 == a.indexOf("www.") ? a.substring(4) : a
};
/**
* get referrer page
*
* getReferrer
*/
var getReferrer = function (a) {
var b = idoc.referrer;
if (/^https?:\/\//i.test(b)) {
if (a)
return b;
a = "//" + idoc.location.hostname;
var c = b.indexOf(a);
if (5 == c || 6 == c)
if (a = b.charAt(c + a.length),
"/" == a || "?" == a || "" == a || ":" == a)
return;
return b
}
};
/**
* 这个函数用于将其他函数的输入转换成一个对象,这个规则适用于GA所有对外的接口API
* transformInput(['a', 'b', 'c'], [1, 2, 3]);
* ==> {a: 1, b: 2, c: 3}
* transformInput(['a', 'b', 'c'], [1, 2, {c: 3, d: 4}]);
* ==> {a: 1, b: 2, c: 3, d: 4}
*
* transformInput
*
* paramNames, args
*/
var transformInput = function (paramNames, args) {
if (1 == args.length && null != args[0] && "object" === typeof args[0])
return args[0];
for (var obj = {}, d = Math.min(paramNames.length + 1, args.length), i = 0; i < d; i++)
if ("object" === typeof args[i]) {
for (var arg in args[i])
args[i].hasOwnProperty(arg) && (obj[arg] = args[i][arg]);
break
} else
i < paramNames.length && (obj[paramNames[i]] = args[i]);
return obj
};
/**
* MAP 数据类,被模型类所使用
*/
var iMAP = function () {
this.keys = [];
this.values = {};
this.m = {}
};
iMAP.prototype.set = function (key, val, isFunc) {
this.keys.push(key);
isFunc ? this.m[":" + key] = val : this.values[":" + key] = val
};
iMAP.prototype.get = function (key) {
return this.m.hasOwnProperty(":" + key) ? this.m[":" + key] : this.values[":" + key]
};
iMAP.prototype.map = function (callback) {
for (var i = 0; i < this.keys.length; i++) {
var key = this.keys[i]
, val = this.get(key);
val && callback(key, val)
}
};
var iwin = window
, idoc = document;
var fwin = window;
/**
* window 中的 ga-disable- 前缀的变量
* Google 开发了一系列插件,安装后可以关掉GA的追踪
* 这里就是获取这些插件的配置,如果开启了,这个函数返回false
* https://tools.google.com/dlpage/gaoptout
*/
var checkGaUserPrefs = function (plugin) {
var gaUserPref = fwin._gaUserPrefs;
if (gaUserPref && gaUserPref.ioo && gaUserPref.ioo() || plugin && !0 === fwin["ga-disable-" + plugin])
return !0;
try {
var c = fwin.external;
if (c && c._gaUserPrefs && "oo" == c._gaUserPrefs)
return !0
} catch (d) {
}
return !1
};
/**
* 从google的cookie中取内容
*
* 获取指定名字的cookie
* 返回的是一个数组
*/
var getCookie = function (key) {
var cookie = []
, cookies = idoc.cookie.split(";");
var keyReg = new RegExp("^\\s*" + key + "=\\s*(.*?)\\s*$");
for (var i = 0; i < cookies.length; i++) {
var e = cookies[i].match(keyReg);
e && cookie.push(e[1])
}
return cookie
};
/**
* set cookie
*
* cookieName, cookieValue, cookiePath, cookieDomain, trackingId, cookieExpires
*
* 返回成功与否
*/
var setCookie = function (cookieName, cookieValue, cookiePath, cookieDomain, trackingId, cookieExpires) {
// 如果用户安装了google的禁止统计的插件,或者在doubleclick页面,或者在google首页
// 那么都是false
trackingId = checkGaUserPrefs(trackingId) ? !1 : doubleclickURLreg.test(idoc.location.hostname) || "/" == cookiePath && googleURLreg.test(cookieDomain) ? !1 : !0;
if (!trackingId)
return !1;
cookieValue && 1200 < cookieValue.length && (cookieValue = cookieValue.substring(0, 1200),
reg(24));
cookiePath = cookieName + "=" + cookieValue + "; path=" + cookiePath + "; ";
cookieExpires && (cookiePath += "expires=" + (new Date((new Date).getTime() + cookieExpires)).toGMTString() + "; ");
cookieDomain && "none" != cookieDomain && (cookiePath += "domain=" + cookieDomain + ";");
cookieDomain = idoc.cookie;
idoc.cookie = cookiePath;
if (!(cookieDomain = cookieDomain != idoc.cookie))
a: {
cookieName = getCookie(cookieName);
for (cookieDomain = 0; cookieDomain < cookieName.length; cookieDomain++)
if (cookieValue == cookieName[cookieDomain]) {
cookieDomain = !0;
break a
}
cookieDomain = !1
}
return cookieDomain
};
/**
* 将a中的内容的 ()转义成 URI 格式
*
*/
var encodeURIComponentWithBrackets = function (a) {
return iEncodeURIComponent(a).replace(/\(/g, "%28").replace(/\)/g, "%29")
};
//googleURLreg
var googleURLreg = /^(www\.)?google(\.com?)?(\.[a-z]{2})?$/;
//doubleclickURLreg
var doubleclickURLreg = /(^|\.)doubleclick\.net$/i;
/**
* 请求长度过长的错误类
*/
var OverLengthError = function (a) {
this.name = "len";
this.message = a + "-8192"
};
/**
* 智能ga请求,依据请求的长度和浏览器特性来决定使用哪种请求方式
*
* 发起 collection 请求
*/
var smartPing = function (a, b, c) {
c = c || emptyFunction;
if (2036 >= b.length)
imgPing(a, b, c);
else if (8192 >= b.length)
beaconPing(a, b, c) || xhrPing(a, b, c) || imgPing(a, b, c);
else
throw errorPing("len", b.length),
new OverLengthError(b.length);
};
/**
* 设置 请求图片的回调方法
*/
var imgPing = function (imgBaseLink, paramstr, callback) {
var d = createImg(imgBaseLink + "?" + paramstr);
var rnd_id = "_img_" + Math.random();
window[rnd_id] = d;
d.onload = d.onerror = function () {
d.onload = null;
d.onerror = null;
window[rnd_id] = null;
callback();
}
};
/**
* 使用跨域xhr来发请求
* Post data by ajax
*/
var xhrPing = function (url, data, callback) {
var d = iwin.XMLHttpRequest;
if (!d)
return !1;
var e = new d;
if (!("withCredentials" in e))
return !1;
e.open("POST", url, !0);
e.withCredentials = !0;
e.setRequestHeader("Content-Type", "text/plain");
e.onreadystatechange = function () {
4 == e.readyState && (callback(),
e = null )
}
;
e.send(data);
return !0
};
/**
* 当图片的参数长度超过2036使用下面的方式发起请求
*
* 使用sendBeacon方法来发请求
*
* http://kaifage.com/notes/76/navigator-sendBeacon.html
*/
var beaconPing = function (a, b, c) {
return iwin.navigator.sendBeacon ? iwin.navigator.sendBeacon(a, b) ? (c(),
!0) : !1 : !1
};
/**
* 如果统计信息发送失败,上报错误
*
* errorType 为 len 或 exc
* len 表示请求长度超长
* exc 表示内部执行出错
*
*/
var errorPing = function (errorType, method, detail) {
1 <= 100 * Math.random() || checkGaUserPrefs("?") || (errorType = ["t=error", "_e=" + errorType, "_v=j47", "sr=1"],
method && errorType.push("_f=" + method),
detail && errorType.push("_m=" + iEncodeURIComponent(detail.substring(0, 100))),
errorType.push("aip=1"),
errorType.push("z=" + _uuid()),
imgPing(getGAOriginUrl() + "/collect", errorType.join("&"), emptyFunction))
};
/**
* 返回 hitcount 点击统计
*
*/
var getHitCountFromBrowser = function (trackId) {
var collectedData = iwin.gaData = iwin.gaData || {};
return collectedData[trackId] = collectedData[trackId] || {}
};
/**
* 函数的名字队列类
*/
var Queue = function () {
this.M = []
};
Queue.prototype.add = function (name) {
this.M.push(name)
};
/**
*
* 执行队列里面的名字指定的函数
* 从model里面拿到名字对应的函数
* 最后会执行hitCallback对应的函数
*
*
* Queue.prototype.exec
*
* model
*/
Queue.prototype.D = function (model) {
try {
for (var i = 0; i < this.M.length; i++) {
var c = model.get(this.M[i]);
c && isFunction(c) && c.call(iwin, model)
}
} catch (d) {
}
var hitCallback = model.get(HIT_CALLBACK);
hitCallback != emptyFunction &&
isFunction(hitCallback) &&
(
model.set(HIT_CALLBACK, emptyFunction, !0),
setTimeout(hitCallback, 10)
)
};
/**
* 判断的是否进行ga的采样
*
* samplerTaskFunc
*
*/
function samplerTaskFunc(model) {
if (100 != model.get(SAMPLE_RATE) && str2Num(getAttrToStr(model, CLIENT_ID)) % 1E4 >= 100 * getAttrToInt(model, SAMPLE_RATE))
throw "abort";
}
/**
* isGAPrefsAllowed
*/
function isGAPrefsAllowed(model) {
if (checkGaUserPrefs(getAttrToStr(model, TRACKING_ID)))
throw "abort";
}
/**
* check url is not http request
*
* notHTTP
*/
function checkProtocol() {
var pro = idoc.location.protocol;
if ("http:" != pro && "https:" != pro)
throw "abort";
}
/**
*
*
* buildHitTaskFunc
*
* model
*
*/
function buildHitTaskFunc(model) {
try {
iwin.navigator.sendBeacon ? reg(42) : iwin.XMLHttpRequest && "withCredentials" in new iwin.XMLHttpRequest && reg(40)
} catch (c) {
}
model.set(USAGE, mergeAndEncodeUM(model), !0);
model.set(_S, getAttrToInt(model, _S) + 1);
var b = [];
hookMap.map(function (c, hook) {
if (hook.F) {
var e = model.get(c);
// 不为空、不是默认值的键值对,才会被上传 // boolean类型转换成数字
void 0 != e && e != hook.defaultValue && ("boolean" == typeof e && (e *= 1),
b.push(hook.F + "=" + iEncodeURIComponent("" + e)))
}
});
b.push("z=" + uuid());
model.set(HIT_PAYLOAD, b.join("&"), !0)
}
/**
* 发送任务的任务
*
*
* sendHitTaskFunc(model)
*/
function sendHitTaskFunc(model) {
var url = getAttrToStr(model, TRANSPORT_URL) || getGAOriginUrl() + "/collect"
, c = getAttrToStr(model, TRANSPORT);
!c && model.get(USE_BEACON) && (c = "beacon");
if (c) {
var d = getAttrToStr(model, HIT_PAYLOAD)
, e = model.get(HIT_CALLBACK)
, e = e || emptyFunction;
"image" == c ? imgPing(url, d, e) : "xhr" == c && xhrPing(url, d, e) || "beacon" == c && beaconPing(url, d, e) || smartPing(url, d, e)
} else
smartPing(url, getAttrToStr(model, HIT_PAYLOAD), model.get(HIT_CALLBACK));
//
var trackId = model.get(TRACKING_ID);
var gaBrowserData = getHitCountFromBrowser(trackId);
c = gaBrowserData.hitcount;
gaBrowserData.hitcount = c ? c + 1 : 1;
trackId = model.get(TRACKING_ID);
delete getHitCountFromBrowser(trackId).pending_experiments;
model.set(HIT_CALLBACK, emptyFunction, !0)
}
/**
*
* 从全局的 gaData 里面获取 expVar 和 expId 的值
*
* ceTaskFunc(model)
*/
function ceTaskFunc(model) {
(iwin.gaData = iwin.gaData || {}).expId && model.set(EXP_ID, (iwin.gaData = iwin.gaData || {}).expId);
(iwin.gaData = iwin.gaData || {}).expVar && model.set(EXP_VAR, (iwin.gaData = iwin.gaData || {}).expVar);
var b;
var c = model.get(TRACKING_ID);
if (c = getHitCountFromBrowser(c).pending_experiments) {
var d = [];
for (b in c)
c.hasOwnProperty(b) && c[b] && d.push(encodeURIComponent(b) + "." + encodeURIComponent(c[b]));
b = d.join("!")
} else
b = void 0;
b && model.set(EXPm, b, !0)
}
/**
* cd
* isPreviewLoad()
*/
function isPreviewLoad() {
if (iwin.navigator && "preview" == iwin.navigator.loadPurpose)
throw "abort";
}
/**
* 从全局的 gaDevIds 里面获取 did 的值
*
* devIdTaskFunc(model)
*/
function devIdTaskFunc(model) {
var devIds = iwin.gaDevIds;
isArray(devIds) && 0 != devIds.length && model.set("&did", devIds.join(","), !0)
}
/**
*
* 验证trackingId是否正确的任务
*
* validationTaskFunc(model)
*/
function validationTaskFunc(model) {
if (!model.get(TRACKING_ID))
throw "abort";
}
/**
* 基本的uuid方法
* _uuid
*/
var _uuid = function () {
return Math.round(2147483647 * Math.random())
};
/**
* 优先使用crypto API来生成uuid
*
* uuid
*/
var uuid = function () {
try {
//an array of 32-bit unsigned integers in the platform byte order
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array
var ar = new Uint32Array(1);
iwin.crypto.getRandomValues(ar);
return ar[0] & 2147483647
} catch (b) {
return _uuid()
}
};
/**
* 这个 task 用于限制发送的频率
*
* 每个 analytics.js 跟踪器对象从 20 次可发送额度开始,并以每秒 2 次额度的速度获得补充。适用于除电子商务(商品或交易)之外的所有匹配
* rtlTaskFunc(model)
*/
function rtlTaskFunc(model) {
// 当前页面的发送总数
var b = getAttrToInt(model, HIT_COUNT);
// 超过500记录下
500 <= b && reg(15);
var c = getAttrToStr(model, HIT_TYPE);
if ("transaction" != c && "item" != c) {
var c = getAttrToInt(model, AVAILABLE_COUNT)
, d = (new Date).getTime()
, e = getAttrToInt(model, LAST_SEND_TIME);
0 == e && model.set(LAST_SEND_TIME, d);
// 每秒 2 次额度的速度获得补充
e = Math.round(2 * (d - e) / 1E3);
// 最多 20 次额度
0 < e && (c = Math.min(c + e, 20),
model.set(LAST_SEND_TIME, d));
// 额度用完,此次发送取消
if (0 >= c)
throw "abort";
// 每次发送消耗掉
model.set(AVAILABLE_COUNT, --c)
}
model.set(HIT_COUNT, ++b)
}
/**
* 全局的Hook配置
* 配置的值是Hook类的对象
*
* hookMap
*/
var hookMap = new iMAP;
// 有些配置的值的计算有特殊方法,这里存储计算规则
// [/^contentGroup([0-9]+)$/, generateFunction]
// generateFunction输入是正则的exec执行结果,输出是Hook类的对象
// 执行结果会被放到hookMap
// specialHooks
var specialHooks = [];
/**
* 模型类
* https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference?hl=zh-cn
*/
var iModel = function () {
this.data = new iMAP
};
/**
* 获取模型中存储的一个字段值。
*/
iModel.prototype.get = function (key) {
var hook = getHook(key)
, c = this.data.get(key);
//// 如果没有则使用默认值
hook && void 0 == c && (c = isFunction(hook.defaultValue) ? hook.defaultValue() : hook.defaultValue);
// 如果有getter,则使用getter来转换
// hook && hook.getter ? hook.getter(this, fieldName, value) : value
return hook && hook.Z ? hook.Z(this, key, c) : c
};
/**
* 在模型上设置一个或一组字段/值对
* 可以传map进去
* temporary 布尔值 默认为否。如果为 true,则在模型上仅对当前匹配设置值。
*
* fieldName, fieldValue, temporary
*/
iModel.prototype.set = function (fieldName, fieldValue, temporary) {
if (fieldName)
if ("object" == typeof fieldName)
for (var d in fieldName)
fieldName.hasOwnProperty(d) && _modelSet(this, d, fieldName[d], temporary);
else
_modelSet(this, fieldName, fieldValue, temporary)
};
/**
* 讲数据模型对应的值初始化为字符串
*
* @param model
* @param key
* @returns {string}
*/
var getAttrToStr = function (model, key) {
var c = model.get(key);
return void 0 == c ? "" : "" + c
};
/**
* 讲数据模型对应的值初始化为整数
*
* @param model
* @param key
* @returns {int}
*/
var getAttrToInt = function (model, key) {
var c = model.get(key);
return void 0 == c || "" === c ? 0 : 1 * c
};
/**
*
* var _modelSet = function(model, fieldName, fieldValue, temporary) {
*
*
*
*/
var _modelSet = function (model, fieldName, fieldValue, temporary) {
if (void 0 != fieldValue)
switch (fieldName) {
case TRACKING_ID:
gaClientIdReg.test(fieldValue)
}
var e = getHook(fieldName);
// 如果有特殊规则,则使用特定规则设置 // 否则设置到模型的data上
e && e.o ? e.o(model, fieldName, fieldValue, temporary) : model.data.set(fieldName, fieldValue, temporary)
};
/**
* Hook类
*
* 设置指定字段相关的hook对象
*
*
* var Hook = function(name, paramName, defaultValue, getter, setter) {
*
*/
var Hook = function (name, paramName, defaultValue, getter, setter) {
this.name = name; // 字段名
this.F = paramName;// F 字段的参数名(传给后端时候的参数名)
this.Z = getter;// Z 获取时候的hook函数
this.o = setter;// o 设置时候的hook函数
this.defaultValue = defaultValue; // 默认值
};
/**
* 获取hookMap中的配置,如果配置不存在,则使用specialHooks中的规则生成
*/
var getHook = function (fieldName) {
var value = hookMap.get(fieldName);
if (!value)
for (var i = 0; i < specialHooks.length; i++) {
var hook = specialHooks[i]
, e = hook[0].exec(fieldName);
if (e) {
value = hook[1](e);
// 生成结果会被放到hookMap中缓存下来
hookMap.set(value.name, value);
break
}
}
return value
};
/**
*
* @param key
* @returns {*}
*/
var getHookFromGlobal = function (key) {
var hook;
hookMap.map(function (c, tarHook) {
tarHook.F == key && (hook = tarHook)
});
return hook && hook.name
};
/**
* 添加hook到hookMap的函数
*
*
* var addHook = function(name, paramName, defaultValue, getter, setter) {
*
*/
var S = function (name, paramName, defaultValue, getter, setter) {
var hook = new Hook(name, paramName, defaultValue, getter, setter);
hookMap.set(hook.name, hook);
return hook.name
};
/**
* 把正则表达式 和目标 string 放入Za 数组
*/
var putHookToQ = function (regStr, callback) {
specialHooks.push([new RegExp("^" + regStr + "$"), callback])
};
/**
* 添加只读的hook到hookMap的函数
*/
var T = function (name, paramName, defaultValue) {
return S(name, paramName, defaultValue, void 0, emptyFunction2)
};
/**
* 空方法
*/
var emptyFunction2 = function () {
};
//GA_HOOK
var GA_HOOK = isString(window.GoogleAnalyticsObject) && trim(window.GoogleAnalyticsObject) || "ga"
, forceHTTPS = !1 //forceHTTPS
, API_VERSION = T("apiVersion", "v") //API_VERSION
, CLIENT_VERSION = T("clientVersion", "_v"); //CLIENT_VERSION
S("anonymizeIp", "aip");
//const AD_SENSE_ID = addHook('adSenseId', 'a');
var AD_SENSE_ID = S("adSenseId", "a") //AD_SENSE_ID
, HIT_TYPE = S("hitType", "t") //HIT_TYPE
, HIT_CALLBACK = S("hitCallback") //HIT_CALLBACK
, HIT_PAYLOAD = S("hitPayload"); //HIT_PAYLOAD
S("nonInteraction", "ni");
S("currencyCode", "cu");
S("dataSource", "ds");
var USE_BEACON = S("useBeacon", void 0, !1) //USE_BEACON
, TRANSPORT = S("transport"); //TRANSPORT
S("sessionControl", "sc", "");
S("sessionGroup", "sg");
S("queueTime", "qt");
var _S = S("_s", "_s");
S("screenName", "cd");
var LOCATION = S("location", "dl", "") //LOCATION
, REFERRER = S("referrer", "dr") //REFERRER
, PAGE = S("page", "dp", ""); //PAGE
S("hostname", "dh");
var LANGUAGE = S("language", "ul") //LANGUAGE
, ENCODING = S("encoding", "de"); //ENCODING
S("title", "dt", function () {
return idoc.title || void 0
});
putHookToQ("contentGroup([0-9]+)", function (a) {
return new Hook(a[0], "cg" + a[1])
});
var SCREEN_COLORS = S("screenColors", "sd") //SCREEN_COLORS
, SCREEN_RESOLUTION = S("screenResolution", "sr") //SCREEN_RESOLUTION
, VIEWPORT_SIZE = S("viewportSize", "vp") //VIEWPORT_SIZE
, JAVA_ENABLED = S("javaEnabled", "je") //JAVA_ENABLED
, FLASH_VERSION = S("flashVersion", "fl"); //FLASH_VERSION
S("campaignId", "ci");
S("campaignName", "cn");
S("campaignSource", "cs");
S("campaignMedium", "cm");
S("campaignKeyword", "ck");
S("campaignContent", "cc");
// 事件相关字段
var EVENT_CATEGORY = S("eventCategory", "ec") //EVENT_CATEGORY
, EVENT_ACTION = S("eventAction", "ea") //EVENT_ACTION
, EVENT_LABEL = S("eventLabel", "el") //EVENT_LABEL
, EVENT_VALUE = S("eventValue", "ev") //EVENT_VALUE
// 社交请求相关字段
, SOCIAL_NETWORK = S("socialNetwork", "sn") //SOCIAL_NETWORK
, SOCIAL_ACTION = S("socialAction", "sa") //SOCIAL_ACTION
, SOCIAL_TARGET = S("socialTarget", "st") //SOCIAL_TARGET
, L1 = S("l1", "plt")
, L2 = S("l2", "pdt")
, L3 = S("l3", "dns")
, L4 = S("l4", "rrt")
, L5 = S("l5", "srt")
, L6 = S("l6", "tcp")
, L7 = S("l7", "dit")
, L8 = S("l8", "clt")
// 计时器相关字段
, TIMING_CATEGORY = S("timingCategory", "utc") //TIMING_CATEGORY
, TIMING_VAR = S("timingVar", "utv") //TIMING_VAR
, TIMING_LABEL = S("timingLabel", "utl") //TIMING_LABEL
, TIMING_VALUE = S("timingValue", "utt"); //TIMING_VALUE
// 应用名称
S("appName", "an");
S("appVersion", "av", "");// 应用版本
S("appId", "aid", "");// 应用名称
S("appInstallerId", "aiid", "");// 应用安装程序 ID
S("exDescription", "exd");// 异常说明
S("exFatal", "exf");// 异常是否严重?
// 实验 ID
var EXP_ID = S("expId", "xid") //EXP_ID
// 实验变体
, EXP_VAR = S("expVar", "xvar")//EXP_VAR
, EXPm = S("exp", "exp")
, _UTMA = S("_utma", "_utma") //_UTMA
, _UTMZ = S("_utmz", "_utmz") //_UTMZ
, _UTMHT = S("_utmht", "_utmht") //_UTMHT
, HIT_COUNT = S("_hc", void 0, 0) //HIT_COUNT
, LAST_SEND_TIME = S("_ti", void 0, 0) //LAST_SEND_TIME
, AVAILABLE_COUNT = S("_to", void 0, 20); //AVAILABLE_COUNT
putHookToQ("dimension([0-9]+)", function (a) {
return new Hook(a[0], "cd" + a[1])
});
putHookToQ("metric([0-9]+)", function (a) {
return new Hook(a[0], "cm" + a[1])
});
S("linkerParam", void 0, void 0, linkerParamGetter, emptyFunction2);
var USAGE = S("usage", "_u")
var USAGE_MANAGER = S("_um");
S("forceSSL", void 0, void 0, function () {
return forceHTTPS
}, function (a, b, c) {
reg(34);
forceHTTPS = !!c
});
var JID = S("_j1", "jid");
putHookToQ("\\&(.*)", function (a) {
var hook = new Hook(a[0], a[1])
, c = getHookFromGlobal(a[0].substring(1));
c && (
hook.Z = function (a) {
return a.get(c)
}
,
hook.o = function (model, b, g, ca) {
model.set(c, g, ca)
}
,
hook.F = void 0);
return hook
});
var _OOT = T("_oot")
, PREVIEW_TASK = S("previewTask")
, CHECK_PROTOCOL_TASK = S("checkProtocolTask")
, VALIDATION_TASK = S("validationTask")
, CHECK_STORAGE_TASK = S("checkStorageTask")
, HISTORY_IMPORT_TASK = S("historyImportTask")
, SAMPLER_TASK = S("samplerTask")
, _RLT = S("_rlt")
, BUILD_HIT_TASK = S("buildHitTask")
, SEND_HIT_TASK = S("sendHitTask")
, CE_TASK = S("ceTask")
, DEV_ID_TASK = S("devIdTask")
, TIMING_TASK = S("timingTask")
, DISPLAY_FEATURES_TASK = S("displayFeaturesTask")
, TRACKER_NAME = T("name")// 跟踪器名称
, CLIENT_ID = T("clientId", "cid")// 客户端 ID
, CLIENT_ID_TIME = T("clientIdTime")
, USER_ID = S("userId", "uid")// 用户 ID
, TRACKING_ID = T("trackingId", "tid")// 跟踪 ID/网络媒体资源 ID
, COOKIE_NAME = T("cookieName", void 0, "_ga")// Cookie 名称
, COOKIE_DOMAIN = T("cookieDomain")// Cookie 网域
, COOKIE_PATH = T("cookiePath", void 0, "/")
, COOKIE_EXPIRES = T("cookieExpires", void 0, 63072E3)// 63072E3 单位为秒,时长两年
, LEGACY_COOKIE_DOMAIN = T("legacyCookieDomain") // 旧版本的
, LEGACY_HISTORY_IMPORT = T("legacyHistoryImport", void 0, !0)
, STORAGE = T("storage", void 0, "cookie")
, ALLOW_LINKER = T("allowLinker", void 0, !1)
, ALLOW_ANCHOR = T("allowAnchor", void 0, !0)
// 抽样率,指定应对多大比例的用户进行跟踪。默认值为100(跟踪所有用户),但是大型网站可能需要降低抽样率,以免超出Google Analytics(分析)的处理上限。
, SAMPLE_RATE = T("sampleRate", "sf", 100)
// 网站速度抽样率
, SITE_SPEED_SAMPLE_RATE = T("siteSpeedSampleRate", void 0, 1)
, ALWAYS_SEND_REFERRER = T("alwaysSendReferrer", void 0, !1)
, TRANSPORT_URL = S("transportUrl") // 发送内容的目标URL
, _R = S("_r", "_r");
/**
* 包裹一下指定的API函数
* 每次执行都会记录一下idx
* 如果执行出错则发错误记录
*
* function wrapApi(methodName, obj, method, idx)
*/
function X(methodName, obj, method, idx) {
obj[methodName] = function () {
try {
return idx && reg(idx),
method.apply(this, arguments)
} catch (e) {
throw errorPing("exc", methodName, e && e.name),
e;
}
}
}
/**
* 这个对象未被引用到,但是是在计算网站速度频率的时候使用到的,感觉像一个锚点
*
*
*/
var SpeedAnchor = function (int_a) {
this.V = int_a;
this.fa = void 0;
this.$ = !1;
this.oa = void 0;
this.ea = 1
};
/**
* 这个地方感觉有bug fa变量一直没被别的地方用到
*
*
*
* @return {number}
*/
var workWithSpeedAnchor = function (sAnchor, model) {
var _uu;
if (sAnchor.fa && sAnchor.$)
return 0;
sAnchor.$ = !0;
if (model) {
if (sAnchor.oa && getAttrToInt(model, sAnchor.oa))
return getAttrToInt(model, sAnchor.oa);
if (0 == model.get(SITE_SPEED_SAMPLE_RATE))
return 0
}
if (0 == sAnchor.V)
return 0;
void 0 === _uu && (_uu = uuid());
return 0 == _uu % sAnchor.V ? Math.floor(_uu / sAnchor.V) % sAnchor.ea + 1 : 0
};
/**
* flash 版本
*/
function getFlashVersion() {
var a, b, c;
if ((c = (c = iwin.navigator) ? c.plugins : null ) && c.length)
for (var d = 0; d < c.length && !b; d++) {
var e = c[d];
-1 < e.name.indexOf("Shockwave Flash") && (b = e.description)
}
if (!b)
try {
a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"),
b = a.GetVariable("$version")
} catch (g) {
}
if (!b)
try {
a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"),
b = "WIN 6,0,21,0",
a.AllowScriptAccess = "always",
b = a.GetVariable("$version")
} catch (g) {
}
if (!b)
try {
a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),
b = a.GetVariable("$version")
} catch (g) {
}
b && (a = b.match(/[\d]+/g)) && 3 <= a.length && (b = a[0] + "." + a[1] + " r" + a[2]);
return b || void 0
}
/**
*
*
*/
var aa = function (model) {
var b = Math.min(getAttrToInt(model, SITE_SPEED_SAMPLE_RATE), 100);
return str2Num(getAttrToStr(model, CLIENT_ID)) % 100 >= b ? !1 : !0
};
/**
* 计算页面的加载性能
* config 是配置
* callback 是回调函数
*
* var calTiming = function(config, callback) {
*/
var calTiming = function (callback) {
var config = {};
if (calPagePerf(config) || calLoadTime(config)) {
var c = config[L1];
void 0 == c || Infinity == c || isNaN(c) || (0 < c ? (removeUselessValue(config, L3),
removeUselessValue(config, L6),
removeUselessValue(config, L5),
removeUselessValue(config, L2),
removeUselessValue(config, L4),
removeUselessValue(config, L7),
removeUselessValue(config, L8),
callback(config)) : iAddEventListener(iwin, "load", function () {
calTiming(callback)
}, !1))
}
};
/**
* 通过performance API来抓去加载时间等性能参数
*
*
*
* var calPagePerf = function(config) {
*/
var calPagePerf = function (config) {
var b = iwin.performance || iwin.webkitPerformance
, b = b && b.timing;
if (!b)
return !1;
var c = b.navigationStart;
if (0 == c)
return !1;
config[L1] = b.loadEventStart - c;
config[L3] = b.domainLookupEnd - b.domainLookupStart;
config[L6] = b.connectEnd - b.connectStart;
config[L5] = b.responseStart - b.requestStart;
config[L2] = b.responseEnd - b.responseStart;
config[L4] = b.fetchStart - c;
config[L7] = b.domInteractive - c;
config[L8] = b.domContentLoadedEventStart - c;
return !0
};
/**
*
* 抓去加载时间等参数
*
* var calLoadTime = function(config) {
*/
var calLoadTime = function (config) {
if (iwin.top != iwin)
return !1;
var b = iwin.external
, c = b && b.onloadT;
b && !b.isValidLoadTime && (c = void 0);
//// 2147483648 === 10000000000000000000000000000000 (32位)
2147483648 < c && (c = void 0);
0 < c && b.setPageReadyTime();
if (void 0 == c)
return !1;
config[L1] = c;
return !0
};
/**
* 如果配置中没有这个参数的值是NaN或者无限大或者小于0,则设置为undefined
*
* var removeUselessValue = function(conf, key)
*/
var removeUselessValue = function (configObj, key) {
var val = configObj[key];
if (isNaN(val) || Infinity == val || 0 > val)
configObj[key] = void 0
};
/**
* 创建一个timing任务
*
* var createTimingTask = function(tracker)
*/
var createTimingTask = function (tracker) {
return function (b) {
if ("pageview" == b.get(HIT_TYPE) && !tracker.I) {
tracker.I = !0;
var c = aa(b);
b = 0 < getUrlParamVal(b.get(LOCATION), "gclid").length;
(c || b) && calTiming(function (b) {
tracker.send(c ? "timing" : "adtiming", b)
})
}
}
};
//gaCookieSetted
var gaCookieSetted = !1 ;// hc
/**
* 设置GA cookie
*
* var setGACookie = function(model)
*/
var setGACookie = function (model) {
if ("cookie" == getAttrToStr(model, STORAGE)) {
var b = getAttrToStr(model, COOKIE_NAME)
, c = calGACookieValue(model)
, d = normalizePath(getAttrToStr(model, COOKIE_PATH))
, e = normalizeDomain(getAttrToStr(model, COOKIE_DOMAIN))
, g = 1E3 * getAttrToInt(model, COOKIE_EXPIRES)
, ca = getAttrToStr(model, TRACKING_ID);
if ("auto" != e)
setCookie(b, c, d, e, ca, g) && (gaCookieSetted = !0);
else {
reg(32);
var l;
a: {
c = [];
// => e.mp.qq.com
e = getHostName().split(".");
// => ['e', 'mp', 'qq', 'com']
if (4 == e.length && (l = e[e.length - 1],
parseInt(l, 10) == l)) {
// hostname是ip地址的情况下
// 10.6.8.10
l = ["none"];
break a
}
for (l = e.length - 2; 0 <= l; l--)
c.push(e.slice(l).join("."));
// => ['qq.com', 'mp.qq.com', 'e.mp.qq.com']
c.push("none");
// => ['qq.com', 'mp.qq.com', 'e.mp.qq.com', 'none'];
l = c
}
for (var k = 0; k < l.length; k++)
if (e = l[k],
model.data.set(COOKIE_DOMAIN, e),
c = calGACookieValue(model),
setCookie(b, c, d, e, ca, g)) {
gaCookieSetted = !0;
return
}
model.data.set(COOKIE_DOMAIN, "auto")
}
}
};
/**
* 检查cookie的storage
* 如果没设置cookie,则设置一遍
* var checkStorageTaskFunc = function(model)
*/
var checkCookieStorageTaskFunc = function (model) {
if ("cookie" == getAttrToStr(model, STORAGE) && !gaCookieSetted && (setGACookie(model),
!gaCookieSetted))
throw "abort";
};
/**
* 前一版本GA的数据的导入,方便迁移
* var historyImportTaskFunc = function(model)
*/
var historyImportTaskFunc = function (model) {
if (model.get(LEGACY_HISTORY_IMPORT)) {
var b = getAttrToStr(model, COOKIE_DOMAIN)
, c = getAttrToStr(model, LEGACY_COOKIE_DOMAIN) || getHostName()
, d = parseAndGetOldGACookie("__utma", c, b);
d && (reg(19),
model.set(_UTMHT, (new Date).getTime(), !0),
model.set(_UTMA, d.R),
(b = parseAndGetOldGACookie("__utmz", c, b)) && d.hash == b.hash && model.set(_UTMZ, b.R))
}
};
/**
* 计算 _ga 的cookie值
* var calGACookieValue = function(conf)
*/
var calGACookieValue = function (model) {
var clientId = encodeURIComponentWithBrackets(getAttrToStr(model, CLIENT_ID))
, baseDomain = normalizeDomain(getAttrToStr(model, COOKIE_DOMAIN)).split(".").length;
var pathCount = getPathCount(getAttrToStr(model, COOKIE_PATH));
1 < pathCount && (baseDomain += "-" + pathCount);
return ["GA1", baseDomain, clientId].join(".")
};
/**
* 计算cookie值中,层级相同或更小层级的cookie值
* 层级最小的值如果有多个,则同时保留
*
* var getSameOrSmallCookieValues = function(parsedGaCookieValues, count, index)
*/
var getSameOrSmallCookieValues = function (parsedGaCookieValues, b, index) {
for (var sameCountValue = [], smallCountValue = [], g, i = 0; i < parsedGaCookieValues.length; i++) {
var cookieValue = parsedGaCookieValues[i];
cookieValue.H[index] == b ? sameCountValue.push(cookieValue) : void 0 == g || cookieValue.H[index] < g ? (smallCountValue = [cookieValue],
g = cookieValue.H[index]) : cookieValue.H[index] == g && smallCountValue.push(cookieValue)
}
return 0 < sameCountValue.length ? sameCountValue : smallCountValue
};
/**
* 如果第一个字符是“.”,则去掉
* var normalizeDomain = function(domain)
*/
var normalizeDomain = function (domain) {
return 0 == domain.indexOf(".") ? domain.substr(1) : domain
};
/**
* 补全path
* 没有输入,则返回 '/'
* 如果最后一个字符是'/'并且还有别的字符,则去掉path中的最后一个 '/'
* 如果path的第一个字符不是 “/”,则补全
*
* var normalizePath = function(path)
*
* path
*/
var normalizePath = function (path) {
if (!path)
return "/";
// 如果最后一个字符是'/'并且还有别的字符,则去掉path中的最后一个 '/'
1 < path.length && path.lastIndexOf("/") == path.length - 1 && (path = path.substr(0, path.length - 1));
// 如果path的第一个字符不是 “/”,则补全
0 != path.indexOf("/") && (path = "/" + path);
return path
};
/**
* 获取path的层级
* 首页表示1级
* '/as'表示2级
* '/as/a'表示三级
*
* var getPathCount = function(a)
*/
var getPathCount = function (path) {
var a = normalizePath(path);
return "/" == a ? 1 : a.split("/").length
};
/**
* 解析和获取旧的GA cookie
* name为 __utma 或者 __utmz
*
* name, legacyDomain, curDomain
*
* function parseAndGetOldGACookie(name, legacyDomain, curDomain)
*/
function parseAndGetOldGACookie(name, legacyDomain, curDomain) {
"none" == legacyDomain && (legacyDomain = "");
var parsedValues = []
, e = getCookie(name);
name = "__utma" == name ? 6 : 2;
for (var g = 0; g < e.length; g++) {
var ca = ("" + e[g]).split(".");
ca.length >= name && parsedValues.push({
hash: ca[0],
R: e[g],
O: ca
})
}
// 优先使用旧域名的
if (0 != parsedValues.length)
return 1 == parsedValues.length ? parsedValues[0] : getCookieFromSpecifiedDomain(legacyDomain, parsedValues) || getCookieFromSpecifiedDomain(curDomain, parsedValues) || getCookieFromSpecifiedDomain(null, parsedValues) || parsedValues[0]
}
/**
* 找到指定域名的cookie值 domain, parsedValues
*
* function getCookieFromSpecifiedDomain(domain, parsedValues)
*/
function getCookieFromSpecifiedDomain(domain, parsedValues) {
// domain == 'qq.com'
// hash1|hash2 == 'qq.com'
// hash1|hash2 == '.qq.com'
var c, d;
null == domain ? c = d = 1 : (c = str2Num(domain),
d = str2Num(startWith(domain, ".") ? domain.substring(1) : "." + domain));
for (var e = 0; e < parsedValues.length; e++)
if (parsedValues[e].hash == c || parsedValues[e].hash == d)
return parsedValues[e]
}
var URL_REGEX = new RegExp(/^https?:\/\/([^\/:]+)/)
, ANCHOR_GA_REGEX = /(.*)([?&#])(?:_ga=[^&#]*)(?:&?)(.*)/;
/**
* linkerParam 参数的getter
* 用于增加其校验字符串
* function linkerParamGetter(a)
*/
function linkerParamGetter(model) {
var a = model.get(CLIENT_ID);
var b = calCheckCode(a, 0);
return "_ga=1." + iEncodeURIComponent(b + "." + a)
}
/**
* 计算校验字符串,计算依赖于:
* 1. 指定的字符串
* 2. userAgent
* 3. 时区
* 4. 当前时间的年、月、日、小时、分钟
*
* function calCheckCode(str, minuteOffset)
*/
function calCheckCode(str, minuteOffset) {
for (var date = new Date,
nav = iwin.navigator,
plugins = nav.plugins || [],
c = [str,
nav.userAgent,
date.getTimezoneOffset(),
date.getYear(),
date.getDate(),
date.getHours(),
date.getMinutes() + minuteOffset],
i = 0; i < plugins.length; ++i)
c.push(plugins[i].description);
return str2Num(c.join("."))
}
/**
*
*
* Linker
*
* var Linker = function(a)
*
*
*/
var Linker = function (a) {
reg(48);
this.target = a;
this.T = !1
};
/**
* 给连接地址、a标签、form标签加上特定的ga参数
*
* Linker.prototype.decorate = function(a, b)
*/
Linker.prototype.ca = function (element, b) {
if (element.tagName) {
if ("a" == element.tagName.toLowerCase()) {
element.href && (element.href = getGaHrefFromLinker(this, element.href, b));
return
}
if ("form" == element.tagName.toLowerCase())
return addGaInputToForm(this, element)
}
if ("string" == typeof element)
return getGaHrefFromLinker(this, element, b)
};
/**
*
* @param linker
* @param href
* @param params
* @returns {XML|string|void}
*/
var getGaHrefFromLinker = function (linker, href, params) {
var d = ANCHOR_GA_REGEX.exec(href);
d && 3 <= d.length && (href = d[1] + (d[3] ? d[2] + d[3] : ""));
linker = linker.target.get("linkerParam");
var e = href.indexOf("?")
, anchorPosition = href.indexOf("#");
params ? href += (-1 == anchorPosition ? "#" : "&") + linker : (params = -1 == e ? "?" : "&",
href = -1 == anchorPosition ? href + (params + linker) : href.substring(0, anchorPosition) + params + linker + href.substring(anchorPosition));
return href = href.replace(/&+_ga=/, "&_ga=")
};
/**
*
* @param linker
* @param iForm
*/
var addGaInputToForm = function (linker, iForm) {
if (iForm && iForm.action) {
var val = linker.target.get("linkerParam").split("=")[1];
if ("get" == iForm.method.toLowerCase()) {
for (var inputs = iForm.childNodes || [], i = 0; i < inputs.length; i++)
if ("_ga" == inputs[i].name) {
inputs[i].setAttribute("value", val);
return
}
var gaInput = idoc.createElement("input");
gaInput.setAttribute("type", "hidden");
gaInput.setAttribute("name", "_ga");
gaInput.setAttribute("value", val);
iForm.appendChild(gaInput)
} else
"post" == iForm.method.toLowerCase() && (iForm.action = getGaHrefFromLinker(linker, iForm.action))
}
};
/**
* 自动给页面绑定mousedown、keyup、submit事情
* 在事件触发的时候,给连接地址加上特定参数
*
* Linker.prototype.autoLink = function(a, b, c)
*/
Linker.prototype.S = function (a, b, c) {
function eventHandler(event) {
try {
event = event || iwin.event;
var d;
a: {
var g = event.target || event.srcElement;
for (var i = 100; g && 0 < i;) {
if (g.href && g.nodeName.match(/^a(?:rea)?$/i)) {
d = g;
break a
}
g = g.parentNode;
i--;
}
d = {}
}
("http:" == d.protocol || "https:" == d.protocol) && urlIsNotClientHost(a, d.hostname || "") && d.href && (d.href = getGaHrefFromLinker(that, d.href, b))
} catch (k) {
reg(26)
}
}
var that = this;
this.T || (this.T = !0,
iAddEventListener(idoc, "mousedown", eventHandler, !1),
iAddEventListener(idoc, "keyup", eventHandler, !1));
c && iAddEventListener(idoc, "submit", function (b) {
b = b || iwin.event;
if ((b = b.target || b.srcElement) && b.action) {
var c = b.action.match(URL_REGEX);
c && urlIsNotClientHost(a, c[1]) && addGaInputToForm(that, b)
}
})
};
/**
*
*
*/
function urlIsNotClientHost(regs, url) {
if (url == idoc.location.hostname)
return !1;
for (var i = 0; i < regs.length; i++)
if (regs[i] instanceof RegExp) {
if (regs[i].test(url))
return !0
} else if (0 <= url.indexOf(regs[i]))
return !0;
return !1
}
var gtmIdReg = /^(GTM|OPT)-[A-Z0-9]+$/
, _gaexpReg = /;_gaexp=[^;]*/g
, __utmaReg = /;((__utma=)|([^;=]+=GAX?\d+\.))[^;]*/g;
/**
* 原来是t方法
* @param cmd
* @returns {string}
*/
var buildGtmUrl = function (cmd) {
function appendParamsToUrl(param, val) {
val && (url += "&" + param + "=" + iEncodeURIComponent(val))
}
//TODO change URL
var url = "https://" + iAnalyseBaseURL + "/gtm/js?id=" + iEncodeURIComponent(cmd.id);
"dataLayer" != cmd.B && appendParamsToUrl("l", cmd.B);
appendParamsToUrl("t", cmd.target);
appendParamsToUrl("cid", cmd.ja);
appendParamsToUrl("cidt", cmd.ka);
appendParamsToUrl("gac", cmd.la);
appendParamsToUrl("aip", cmd.ia);
cmd.na && appendParamsToUrl("m", "sync");
appendParamsToUrl("cycle", cmd.G);
return url
};
/**
*
*
* _gat 用于对每个 tracker 设置限制请求率,所以每个 tracker 的cookie名字不一样
*
* var DoubleClickModel = function(model, apiUrl, c)
*
*/
var DoubleClickModel = function (model, apiUrl, c) {
this.U = JID; //jidKey
this.aa = apiUrl; //apiUrl
(apiUrl = c) ||
(apiUrl =
(apiUrl = getAttrToStr(model, TRACKER_NAME)) && "t0" != apiUrl ?
gtmReg.test(apiUrl) ?
"_gat_" + encodeURIComponentWithBrackets(getAttrToStr(model, TRACKING_ID)) :
"_gat_" + encodeURIComponentWithBrackets(apiUrl) : "_gat");
this.Y = apiUrl;
workWithSpeedAnchor(new SpeedAnchor(100), model) &&
(
reg(30),
this.pa = !0
)
};
/**
*
* 为 buildHitTask 和 sendHitTask 做个包装
* var wrapBuildAndSendTask = function(doubleCModel, model)
*/
var wrapBuildAndSendTask = function (doubleCModel, model) {
var c = model.get(BUILD_HIT_TASK);
model.set(BUILD_HIT_TASK, function (b) {
setJid(doubleCModel, b);
var d = c(b);
setGatCookie(doubleCModel, b);
return d
});
var d = model.get(SEND_HIT_TASK);
model.set(SEND_HIT_TASK, function (b) {
var c = d(b);
Id(doubleCModel, b);
return c
})
};
/**
*
* 设置jid到model上
*
* var setJid = function(jd, model)
*/
var setJid = function (jd, model) {
model.get(jd.U) || ("1" == getCookie(jd.Y)[0] ? model.set(jd.U, "", !0) : model.set(jd.U, "" + _uuid(), !0))
};
/**
*
* 设置 _gat cookie值为1
*
* var setGatCookie = function(doubleClModel, model)
*/
var setGatCookie = function (doubleClModel, model) {
if (model.get(doubleClModel.U)) {
var c = 6E5; //600000
doubleClModel.pa && (c /= 10);
setCookie(doubleClModel.Y, "1", model.get(COOKIE_PATH), model.get(COOKIE_DOMAIN), model.get(TRACKING_ID), c)
}
};
/**
* 发送请求
*
*
*/
var Id = function (doubleClick, model) {
if (model.get(doubleClick.U)) {
var tmp = new iMAP;
// var setData = function(fieldName)
var setData = function (fieldName) {
getHook(fieldName).F && tmp.set(getHook(fieldName).F, model.get(fieldName))
};
setData(API_VERSION);
setData(CLIENT_VERSION);
setData(TRACKING_ID);
setData(CLIENT_ID);
setData(USER_ID);
setData(doubleClick.U);
tmp.set(getHook(USAGE).F, mergeAndEncodeUM(model));
var apiUrl = doubleClick.aa;
tmp.map(function (fieldName, fieldValue) {
apiUrl += iEncodeURIComponent(fieldName) + "=";
apiUrl += iEncodeURIComponent("" + fieldValue) + "&";
});
apiUrl += "z=" + _uuid();
//change to imgPing
createImg(apiUrl);
model.set(doubleClick.U, "", !0)
}
};
var gtmReg = /^gtm\d+$/;
/**
* 展示广告插件
* 此插件的工作原理是向 stats.g.doubleclick.net 发送一个额外的请求,以便提供 Google Analytics(分析)中的广告功能(例如再营销以及受众特征和兴趣报告)。
* 该插件还会创建一个名为 _gat 的新 Cookie,其有效时间为 10 分钟。
* 该 Cookie 不会存储任何用户信息,而只会用于限制发送到 doubleclick.net 的请求数量。
* https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features?hl=zh-cn#overview
*
* var displayFeaturesPlugin = function(tracker, opts)
*/
var displayFeaturesPlugin = function (tracker, opts) {
var doubleClick = tracker.b;
//
if (!doubleClick.get("dcLoaded")) {
setModelUM(doubleClick, 29);
opts = opts || {};
var d;
opts[COOKIE_NAME] && (d = encodeURIComponentWithBrackets(opts[COOKIE_NAME]));
//TODO change URL
var dcModel = new DoubleClickModel(doubleClick, "https://"+iAdBaseURL+"/r/collect?t=dc&aip=1&_r=3&", d);
wrapBuildAndSendTask(dcModel, doubleClick);
doubleClick.set("dcLoaded", !0)
}
};
/**
* 如果没有加载 doubleclick 的展示广告插件,并且用的cookie存储
* 则使用 /r/collect 作为API地址
*
* var displayFeaturesTaskFunc = function(model)
*/
var displayFeaturesTaskFunc = function (model) {
if (!model.get("dcLoaded") && "cookie" == model.get(STORAGE)) {
setModelUM(model, 51);
var dcModel = new DoubleClickModel(model);
setJid(dcModel, model);
setGatCookie(dcModel, model);
model.get(dcModel.U) && (model.set(_R, 1, !0),
//TODO change URL
model.set(TRANSPORT_URL, getGAOriginUrl() + "/r/collect", !0))
}
};
/**
* set AD_SENSE_ID
* @returns {*}
* @constructor
*/
var setAdSenseId = function () {
var a = iwin.gaGlobal = iwin.gaGlobal || {};
return a.hid = a.hid || _uuid()
};
//加载In-Page分析的功能
/**
*
* var loadInpageAnalytics = function(a, b, c)
*/
var inpageLoaded, loadInpageAnalytics = function (trackerId, iDomain, iPath) {
if (!inpageLoaded) {
var d;
d = idoc.location.hash;
var e = iwin.name
, g = /^#?gaso=([^&]*)/;
if (
e = (d = (d = d && d.match(g) || e && e.match(g)) ? d[1] : getCookie("GASO")[0] || "") && d.match(/^(?:!([-0-9a-z.]{1,40})!)?([-.\w]{10,1200})$/i)
)
setCookie("GASO", "" + d, iPath, iDomain, trackerId, 0),
window._udo || (window._udo = iDomain),
window._utcp || (window._utcp = iPath),
trackerId = e[1],
//TODO change URL
iInpageURL
loadScript(iInpageURL + (trackerId ? "prefix=" + trackerId + "&" : "") + _uuid(), "_gasojs");
//loadScript("https://www.google.com/analytics/web/inpage/pub/inpage.js?" + (trackerId ? "prefix=" + trackerId + "&" : "") + _uuid(), "_gasojs");
inpageLoaded = !0
}
};
// ga 的用户的 id 格式 UA-7076879-3
//TODO change UA to XD
var gaClientIdReg = /^(UA|YT|MO|GP)-(\d+)-(\d+)$/;
/**
* 跟踪器类
*
* https://developers.google.com/analytics/devguides/collection/analyticsjs/tracker-object-reference?hl=zh-cn
*
* var Tracker = function(opts)
*/
var Tracker = function (opts) {
/**
* function setData(fieldName, fieldValue)
*/
function setData(fieldName, fieldValue) {
that.b.data.set(fieldName, fieldValue)
}
/**
* function addFilter(filterName, filter)
*/
function addFilter(filterName, filter) {
setData(filterName, filter);
that.filters.add(filterName)
}
var that = this;
this.b = new iModel;
this.filters = new Queue;
setData(TRACKER_NAME, opts[TRACKER_NAME]);
setData(TRACKING_ID, trim(opts[TRACKING_ID]));
setData(COOKIE_NAME, opts[COOKIE_NAME]);
setData(COOKIE_DOMAIN, opts[COOKIE_DOMAIN] || getHostName());
setData(COOKIE_PATH, opts[COOKIE_PATH]);
setData(COOKIE_EXPIRES, opts[COOKIE_EXPIRES]);
setData(LEGACY_COOKIE_DOMAIN, opts[LEGACY_COOKIE_DOMAIN]);
setData(LEGACY_HISTORY_IMPORT, opts[LEGACY_HISTORY_IMPORT]);
setData(ALLOW_LINKER, opts[ALLOW_LINKER]);
setData(ALLOW_ANCHOR, opts[ALLOW_ANCHOR]);
setData(SAMPLE_RATE, opts[SAMPLE_RATE]);
setData(SITE_SPEED_SAMPLE_RATE, opts[SITE_SPEED_SAMPLE_RATE]);
setData(ALWAYS_SEND_REFERRER, opts[ALWAYS_SEND_REFERRER]);
setData(STORAGE, opts[STORAGE]);
setData(USER_ID, opts[USER_ID]);
setData(CLIENT_ID_TIME, opts[CLIENT_ID_TIME]);
setData(API_VERSION, 1);
setData(CLIENT_VERSION, "j47");
addFilter(_OOT, isGAPrefsAllowed);
addFilter(PREVIEW_TASK, isPreviewLoad);
addFilter(CHECK_PROTOCOL_TASK, checkProtocol);
addFilter(VALIDATION_TASK, validationTaskFunc);
addFilter(CHECK_STORAGE_TASK, checkCookieStorageTaskFunc);
addFilter(HISTORY_IMPORT_TASK, historyImportTaskFunc);
addFilter(SAMPLER_TASK, samplerTaskFunc);
addFilter(_RLT, rtlTaskFunc);
addFilter(CE_TASK, ceTaskFunc);
addFilter(DEV_ID_TASK, devIdTaskFunc);
addFilter(DISPLAY_FEATURES_TASK, displayFeaturesTaskFunc);
addFilter(BUILD_HIT_TASK, buildHitTaskFunc);
addFilter(SEND_HIT_TASK, sendHitTaskFunc);
addFilter(TIMING_TASK, createTimingTask(this));
buildAndSetGACookie(this.b, opts[CLIENT_ID]);
setBasicData(this.b);
this.b.set(AD_SENSE_ID, setAdSenseId());
loadInpageAnalytics(this.b.get(TRACKING_ID), this.b.get(COOKIE_DOMAIN), this.b.get(COOKIE_PATH));
};
/**
*
*
*/
var buildAndSetGACookie = function (model, cookieOpts) {
//存储方式是cookie
if ("cookie" == getAttrToStr(model, STORAGE)) {
gaCookieSetted = !1;
var c;
b: {
var tmpCookie = getCookie(getAttrToStr(model, COOKIE_NAME));
if (tmpCookie && !(1 > tmpCookie.length)) {
c = [];
for (var itemp = 0; itemp < tmpCookie.length; itemp++) {
// _ga 的 cookie 值有四个区域,以点间隔
// 四个区域的含义参考别人的答案 http://stackoverflow.com/questions/16102436/what-are-the-values-in-ga-cookie
// 1.2.286403989.1366364567
// GA1.3.494346849.1446193077
var g;
g = tmpCookie[itemp].split(".");
// 第一个区域值是版本号 gaVersion
var ca = g.shift();
// 第二个区域用于确认是否是指定域名和路径的cookie,因为GA可以在不同的域名和路径上设置多个cookie
// 所以需要这个区域值来区分,以获取到正确的cookie值
// 值的格式是 \d[-\d],例如:“2-1” 或者 “2”
// 第一个数字是 域名的层级,qq.com 为 “2;b.qq.com” 为 “3”
// 第二个数字是 路径的层级, / 为空字符, /data 为 “-2”,/user/xxx 为 “-3”
("GA1" == ca || "1" == ca) && 1 < g.length ? (ca = g.shift().split("-"),
1 == ca.length && (ca[1] = "1"), // 补全下 路径为 / 时,省略的 “-1”
// 字符串转换成数字
ca[0] *= 1,
ca[1] *= 1,
g = {
// 第二区域的值 [1, 2]
// domainAndPathCount: ca,
H: ca,
// 第三和第四区域的组合值,也就是clientId的值
// 第三区域是一个随机数
// 第四区域是cookie第一次设置时候的时间值
// idAndTime: gaCookie.join('.')
s: g.join(".")
}) : g = void 0;
g && c.push(g)
}
if (1 == c.length) {
reg(13);
c = c[0].s;
break b
}
if (0 == c.length)
reg(12);
else {
reg(14);
tmpCookie = normalizeDomain(getAttrToStr(model, COOKIE_DOMAIN)).split(".").length;
c = getSameOrSmallCookieValues(c, tmpCookie, 0);
if (1 == c.length) {
c = c[0].s;
break b
}
tmpCookie = getPathCount(getAttrToStr(model, COOKIE_PATH));
c = getSameOrSmallCookieValues(c, tmpCookie, 1);
c = c[0] && c[0].s;
break b
}
}
c = void 0
}
c || (c = getAttrToStr(model, COOKIE_DOMAIN),
tmpCookie = getAttrToStr(model, LEGACY_COOKIE_DOMAIN) || getHostName(),
c = parseAndGetOldGACookie("__utma", tmpCookie, c),
void 0 != c ? (reg(10),
c = c.O[1] + "." + c.O[2]) : c = void 0);
c && (model.data.set(CLIENT_ID, c),
gaCookieSetted = !0)
}
// 是否允许定位点参数
c = model.get(ALLOW_ANCHOR);
if (itemp = getUrlParamVal(idoc.location[c ? "href" : "search"], "_ga"))
// 有定位点ga参数
// 定位点 ga 参数值的形式为: '1.校验字符串.clientId'
// 允许链接器参数
model.get(ALLOW_LINKER) ? (c = itemp.indexOf("."),
-1 == c ? reg(22) : (tmpCookie = itemp.substring(c + 1),// 格式不正确
"1" != itemp.substring(0, c) ? reg(22) : (c = tmpCookie.indexOf("."),
-1 == c ? reg(22) : (itemp = tmpCookie.substring(0, c),
c = tmpCookie.substring(c + 1),
itemp != calCheckCode(c, 0) && itemp != calCheckCode(c, -1) && itemp != calCheckCode(c, -2) ? reg(23) : (reg(11),// 2分钟内计算的校验字符串都不对,则是很久以前复制的地址现在才打开// 2分钟内的定位点GA参数,还有效,则记录
model.data.set(CLIENT_ID, c)))))) : reg(21);// 不允许
// 如果在初始化时设置了clientId,则优先使用这个
cookieOpts && (reg(9),
model.data.set(CLIENT_ID, iEncodeURIComponent(cookieOpts)));
if (!model.get(CLIENT_ID))
if (c = (c = iwin.gaGlobal && iwin.gaGlobal.vid) && -1 != c.search(/^(?:utma\.)?\d+\.\d+$/) ? c : void 0)
reg(17),
model.data.set(CLIENT_ID, c);
else {
// 如果没有clientId,则自己生成一个
reg(8);
c = iwin.navigator.userAgent + (idoc.cookie ? idoc.cookie : "") + (idoc.referrer ? idoc.referrer : "");
tmpCookie = c.length;
for (itemp = iwin.history.length; 0 < itemp;)
c += itemp-- ^ tmpCookie++;
model.data.set(CLIENT_ID, [_uuid() ^ str2Num(c) & 2147483647, Math.round((new Date).getTime() / 1E3)].join("."))
}
setGACookie(model)
};
/**
*
*
* var setBasicData = function(model)
*/
var setBasicData = function (model) {
var b = iwin.navigator
, c = iwin.screen
, d = idoc.location;
model.set(REFERRER, getReferrer(model.get(ALWAYS_SEND_REFERRER)));
if (d) {
var e = d.pathname || "";
"/" != e.charAt(0) && (reg(31),
e = "/" + e);
model.set(LOCATION, d.protocol + "//" + d.hostname + e + d.search)
}
c && model.set(SCREEN_RESOLUTION, c.width + "x" + c.height);
c && model.set(SCREEN_COLORS, c.colorDepth + "-bit");
var c = idoc.documentElement
, g = (e = idoc.body) && e.clientWidth && e.clientHeight
, ca = [];
c && c.clientWidth && c.clientHeight && ("CSS1Compat" === idoc.compatMode || !g) ? ca = [c.clientWidth, c.clientHeight] : g && (ca = [e.clientWidth, e.clientHeight]);
c = 0 >= ca[0] || 0 >= ca[1] ? "" : ca.join("x");
model.set(VIEWPORT_SIZE, c);
model.set(FLASH_VERSION, getFlashVersion());
model.set(ENCODING, idoc.characterSet || idoc.charset);
model.set(JAVA_ENABLED, b && "function" === typeof b.javaEnabled && b.javaEnabled() || !1);
model.set(LANGUAGE, (b && (b.language || b.browserLanguage) || "").toLowerCase());
if (d && model.get(ALLOW_ANCHOR) && (b = idoc.location.hash)) {
b = b.split(/[?&#]+/);
d = [];
for (c = 0; c < b.length; ++c)
(startWith(b[c], "utm_id") || startWith(b[c], "utm_campaign") || startWith(b[c], "utm_source") || startWith(b[c], "utm_medium") || startWith(b[c], "utm_term") || startWith(b[c], "utm_content") || startWith(b[c], "gclid") || startWith(b[c], "dclid") || startWith(b[c], "gclsrc")) && d.push(b[c]);
0 < d.length && (b = "#" + d.join("&"),
model.set(LOCATION, model.get(LOCATION) + b))
}
};
Tracker.prototype.get = function (a) {
return this.b.get(a)
};
Tracker.prototype.set = function (a, b) {
this.b.set(a, b)
};
var SEND_PARAMS_NAMES = {
pageview: [PAGE],
event: [EVENT_CATEGORY, EVENT_ACTION, EVENT_LABEL, EVENT_VALUE],
social: [SOCIAL_NETWORK, SOCIAL_ACTION, SOCIAL_TARGET],
timing: [TIMING_CATEGORY, TIMING_VAR, TIMING_VALUE, TIMING_LABEL]
};
// Tracker的send方法
// ga('send', 'pageview');
// ga('send', 'event', '1', '2', '3', '4');
// 每次send之前都会执行所有获取器,并将当前配置临时存储到model中
// send结束之后,删掉临时数据
Tracker.prototype.send = function (a) {
if (!(1 > arguments.length)) {
var hitTypeV, opts;
( "string" === typeof arguments[0] ) ?
(
hitTypeV = arguments[0],
opts = [].slice.call(arguments, 1)
) : (
hitTypeV = arguments[0] && arguments[0][HIT_TYPE],
opts = arguments
);
hitTypeV &&
(
opts = transformInput(SEND_PARAMS_NAMES[hitTypeV] || [], opts),
opts[HIT_TYPE] = hitTypeV,
// 将配置存为临时数据
this.b.set(opts, void 0, !0),
// 执行filters
this.filters.D(this.b),
// 删掉临时数据
this.b.data.m = {}
)
}
};
/**
*
* 本脚本中基本未曾调用过
*
* @param key
* @param b
*/
Tracker.prototype.ma = function (key, b) {
var tracker = this;
setPluginToGA(key, tracker, b) ||
(
setBasePlugin(key, function () {
setPluginToGA(key, tracker, b)
}),
setMorePlugins(String(tracker.get(TRACKER_NAME)), key, void 0, b, !0)
)
};
/**
* 在浏览器预渲染的时候避免执行函数
* 返回:是否预渲染
*
* var executeWithoutPrerender = function(func)
*/
var isNotPreRender = function (callback) {
if ("prerender" == idoc.visibilityState)
return !1;
callback();
return !0
};
/**
* 主要逻辑入口
*
*
*/
var bootUp = function (func) {
if (!isNotPreRender(func)) {
// 处于预渲染中,则等待真正的展示开始才进行逻辑
reg(16);
var executed = !1,
c = function () {
if (!executed && isNotPreRender(func)) {
executed = !0;
var d = c
, e = idoc;
e.removeEventListener ? e.removeEventListener("visibilitychange", d, !1) : e.detachEvent && e.detachEvent("onvisibilitychange", d)
}
};
iAddEventListener(idoc, "visibilitychange", c)
}
};
// command 标识符的正则解析
// [trackerName.][pluginName:]methodName
// https://developers.google.com/analytics/devguides/collection/analyticsjs/command-queue-reference?hl=zh-cn#header
// 调用方法:ga(command, [...fields], [fieldsObject])
// args = [command, [...fields], [fieldsObject]];
// commandRegex
var commandRegex = /^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/;
/**
*
* var Command = function(args)
*/
var Command = function (args) {
if (isFunction(args[0]))
this.u = args[0];
else {
var b = commandRegex.exec(args[0]);
// Tracker名字默认为t0
null != b && 4 == b.length && (this.c = b[1] || "t0",
this.K = b[2] || "",// pluginName
this.C = b[3],// methodName
this.a = [].slice.call(args, 1),
this.K || (this.A = "create" == this.C,
this.i = "require" == this.C,
this.g = "provide" == this.C,
this.ba = "remove" == this.C),
this.i && (3 <= this.a.length ? (this.X = this.a[1],
this.W = this.a[2]) : this.a[1] && (isString(this.a[1]) ? this.X = this.a[1] : this.W = this.a[1])));
b = args[1];
args = args[2];
if (!this.C)
// 必须有一个方法名
throw "abort";
if (this.i && (!isString(b) || "" == b))
// require命令的第二个参数,必须是字符串,且不为空字符串
throw "abort";
if (this.g && (!isString(b) || "" == b || !isFunction(args)))
// 必须是这种输入,才算正确的provide命令
// ga('provide', pluginName, pluginConstuctor);
throw "abort";
if (hasPointOrColon(this.c) || hasPointOrColon(this.K))
// tracker和plugin的名字不能包含点和冒号
throw "abort";
if (this.g && "t0" != this.c)
// 不能单独为某个Tracker来provide插件
throw "abort";
}
};
/**
* 是否有点或者冒号
* string have . or :
*
* function hasPointOrColon(str)
*/
function hasPointOrColon(str) {
return 0 <= str.indexOf(".") || 0 <= str.indexOf(":")
}
var allPlugins, pluginUsageIdMap, loadedPlugins, basePlugins;
// 记录了所有插件的map,插件名作为key
allPlugins = new iMAP;
// 记录了已经加载的GA内置插件,插件名作为key
loadedPlugins = new iMAP;
// 记录所有GA内置插件的usageId的map,插件名作为key
basePlugins = new iMAP;
pluginUsageIdMap = {
ec: 45,
ecommerce: 46,
linkid: 47
};
/**
*
*
*/
var setPluginToGA = function (key, tracker, c) {
tracker == GA || tracker.get(TRACKER_NAME);
var plugin = allPlugins.get(key);
if (!isFunction(plugin))
return !1;
tracker.plugins_ = tracker.plugins_ || new iMAP;
// 如果没有创建过这个插件的实例,则创建一个
if (tracker.plugins_.get(key))
return !0;
tracker.plugins_.set(key, new plugin(tracker, c || {}));
return !0
};
/**
* gtm 加载相关
*
*/
var setMorePlugins = function (trackerName, key, url, cmd, e) {
if (!isFunction(allPlugins.get(key)) && !loadedPlugins.get(key)) {
pluginUsageIdMap.hasOwnProperty(key) && reg(pluginUsageIdMap[key]);
if (gtmIdReg.test(key)) {
reg(52);
var trackerTmp = GA.j(trackerName);
if (!trackerTmp)
return !0;
url = cmd || {};
//
cmd = {
id: key,
B: url.dataLayer || "dataLayer",
ia: !!trackerTmp.get("anonymizeIp"),
na: e,
G: !1
};
trackerTmp.get("&gtm") == key && (cmd.G = !0);
var g = String(trackerTmp.get("name"));
"t0" != g && (cmd.target = g);
checkGaUserPrefs(String(trackerTmp.get("trackingId"))) ||
(
cmd.ja = String(trackerTmp.get(CLIENT_ID)),
cmd.ka = Number(trackerTmp.get(CLIENT_ID_TIME)),
trackerTmp = url.palindrome ? __utmaReg : _gaexpReg,
trackerTmp = (trackerTmp = idoc.cookie.replace(/^|(; +)/g, ";").match(trackerTmp)) ? trackerTmp.sort().join("").substring(1) : void 0,
cmd.la = trackerTmp
);
var dataLayer = cmd.B;
url = (new Date).getTime();
iwin[dataLayer] = iwin[dataLayer] || [];
url = {
"gtm.start": url
};
e || (url.event = "gtm.js");
iwin[dataLayer].push(url);
url = buildGtmUrl(cmd);
}
!url && pluginUsageIdMap.hasOwnProperty(key) ?
(reg(39), url = key + ".js") : reg(43);
var pluginUrl,pluginProtocol,clientProtocol;
url &&
//TODO change URL
(url && 0 <= url.indexOf("/") || (url = (forceHTTPS || isHTTPS() ? "https:" : "http:") + "//" + iAnalyseBaseURL + "/plugins/ua/" + url),
pluginUrl = parseUrl(url),
pluginProtocol = pluginUrl.protocol,
clientProtocol = idoc.location.protocol,
("https:" == pluginProtocol || pluginProtocol == clientProtocol || ("http:" != pluginProtocol ? 0 : "http:" == clientProtocol)) &&
isOfficialUrl(pluginUrl) &&
(loadScript(pluginUrl.url, void 0, e),
loadedPlugins.set(key, !0)
)
)
}
};
/**
*
* @param key
* @param func
*/
var setBasePlugin = function (key, func) {
var plugin = basePlugins.get(key) || [];
plugin.push(func);
basePlugins.set(key, plugin)
};
/**
*
*/
var execBasePlugins = function (key, obj) {
allPlugins.set(key, obj);
for (var plugin = basePlugins.get(key) || [], i = 0; i < plugin.length; i++)
plugin[i]();
basePlugins.set(key, [])
};
/**
* 验证是官方插件地址
* plugins url check
* @return {boolean}
*/
var isOfficialUrl = function (cmd) {
//
var clientUrl = parseUrl(idoc.location.href);
//TODO change URL
if (startWith(cmd.url, "https://"+iAnalyseBaseURL+"/gtm/js?id="))
return true;
if (cmd.query || 0 <= cmd.url.indexOf("?") || 0 <= cmd.path.indexOf("://"))
return false;
if (cmd.host == clientUrl.host && cmd.port == clientUrl.port)
return true;
var cmdPort = "http:" == cmd.protocol ? 80 : 443;
//TODO change URL
return iAnalyseBaseURL == cmd.host && (cmd.port || cmdPort) == cmdPort && startWith(cmd.path, "/plugins/") ? !0 : !1
};
/**
* class
*
*
* // 解析url地址
* // 返回:
* // {
* // protocol: '',
* // host: '',
* // port: '',
* // path: '',
* // query: '',
* // url: ''
* // }
*
*
*
*/
var parseUrl = function (url) {
function parseLink(link) {
var host = (link.hostname || "").split(":")[0].toLowerCase()
, protocol = (link.protocol || "").toLowerCase()
, port = 1 * link.port || ("http:" == protocol ? 80 : "https:" == protocol ? 443 : "");
var pathname = link.pathname || "";
startWith(pathname, "/") || (pathname = "/" + pathname);
return [host, "" + port, pathname]
}
var link = idoc.createElement("a");
link.href = idoc.location.href;
var protocol = (link.protocol || "").toLowerCase()
, parsedLocalLink = parseLink(link)
, query = link.search || ""
, clientUrl = protocol + "//" + parsedLocalLink[0] + (parsedLocalLink[1] ? ":" + parsedLocalLink[1] : "");
startWith(url, "//") ?
url = protocol + url :
startWith(url, "/") ?
url = clientUrl + url :
!url || startWith(url, "?") ?
url = clientUrl + parsedLocalLink[2] + (url || query) :
0 > url.split("/")[0].indexOf(":") && (url = clientUrl + parsedLocalLink[2].substring(0, parsedLocalLink[2].lastIndexOf("/")) + "/" + url);
link.href = url;
var parsedLink = parseLink(link);
return {
protocol: (link.protocol || "").toLowerCase(),
host: parsedLink[0],
port: parsedLink[1],
path: parsedLink[2],
query: link.search || "",
url: url || ""
}
};
// Command Queue Query
// ga = ga || [];
// ga.push('create', 'xxxx', 'auto');
// var MethodQueue =
var MethodQueue = {
ga: function () {//init: function()
//MethodQueue.cmdQueue = []
MethodQueue.f = []
}
};
//MethodQueue.init();
MethodQueue.ga();
// 运行命令队列里面的命令
//MethodQueue.run = function(a)
MethodQueue.D = function (a) {
var commands = MethodQueue.J.apply(MethodQueue, arguments)
, b = MethodQueue.f.concat(commands);
for (MethodQueue.f = []; 0 < b.length && !MethodQueue.v(b[0]) && !(b.shift(),
0 < MethodQueue.f.length);)
;
MethodQueue.f = MethodQueue.f.concat(b)
};
// 将输入的参数转换成Command类的实例对象数组
// 如果是require命令则需要加载js代码
// 如果是provide命令则需要记录提供的插件构造函数
// MethodQueue.toCommands = function()
MethodQueue.J = function (a) {
for (var b = [], c = 0; c < arguments.length; c++)
try {
var cmd = new Command(arguments[c]);
cmd.g ? execBasePlugins(cmd.a[0], cmd.a[1]) : (cmd.i && (cmd.ha = setMorePlugins(cmd.c, cmd.a[0], cmd.X, cmd.W)),
b.push(cmd))
} catch (e) {
}
return b
};
/**
* 运行command对象
* 运行终端
*
* MethodQueue.runCommand = function(cmd)
*/
MethodQueue.v = function (cmd) {
try {
if (cmd.u)
cmd.u.call(iwin, GA.j("t0"));
else {
var tmpGA = cmd.c == GA_HOOK ? GA : GA.j(cmd.c);
if (cmd.A)
"t0" != cmd.c || GA.create.apply(GA, cmd.a);
else if (cmd.ba)
GA.remove(cmd.c);
else if (tmpGA)
if (cmd.i) {
// 如果没有创建过这个插件的实例,则创建一个
if (cmd.ha && (cmd.ha = setMorePlugins(cmd.c, cmd.a[0], cmd.X, cmd.W)),
!setPluginToGA(cmd.a[0], tmpGA, cmd.W))
return !0
// 很可能这时候加载的插件还没有下载下来
// 所以需要终端执行
} else if (cmd.K) { //cmd.pluginName
var c = cmd.C
, d = cmd.a
, e = tmpGA.plugins_.get(cmd.K);
e[c].apply(e, d)
} else
tmpGA[cmd.C].apply(tmpGA, cmd.a)
}
} catch (g) {
}
}
;
//N => GA
/**
* 主要的对象,提供很多静态方法使用
* var GA = function(a)
*/
var GA = function (a) {
reg(1);
MethodQueue.D.apply(MethodQueue, [arguments])
};
// GA.trackerMap = {};
GA.h = {};
//GA.trackers
GA.P = [];
//GA.startTime
GA.L = 0;
//GA.answer
GA.answer = 42;
var neededParams = [TRACKING_ID, COOKIE_DOMAIN, TRACKER_NAME];
/**
* 创建一个Tracker
*
*
*/
GA.create = function () {
var opts = transformInput(neededParams, [].slice.call(arguments));
opts[TRACKER_NAME] || (opts[TRACKER_NAME] = "t0");
var trackerName = "" + opts[TRACKER_NAME];
if (GA.h[trackerName])
return GA.h[trackerName];
var tracker = new Tracker(opts);
GA.h[trackerName] = tracker;
GA.P.push(tracker);
return tracker
};
/**
* 移除一个tracker
*/
GA.remove = function (trackerName) {
for (var i = 0; i < GA.P.length; i++)
if (GA.P[i].get(TRACKER_NAME) == trackerName) {
GA.P.splice(i, 1);
GA.h[trackerName] = null;
break
}
};
/**
* 获取tracker的名字
* N.j => GA.getByName
*/
GA.j = function (trackerName) {
return GA.h[trackerName]
};
/**
* 获取所有的trackers
*
*/
GA.getAll = function () {
return GA.P.slice(0)
};
/**
* 主入口方法
* GA.main = function()
*
*
*/
GA.N = function () {
"ga" != GA_HOOK && reg(49);
var a = iwin[GA_HOOK];
if (!a || 42 != a.answer) {
//
GA.L = a && a.l;
GA.loaded = !0;
var b = iwin[GA_HOOK] = GA;
X("create", b, b.create);
X("remove", b, b.remove);
X("getByName", b, b.j, 5);
X("getAll", b, b.getAll, 6);
var trackerPrototype = Tracker.prototype;
X("get", trackerPrototype, trackerPrototype.get, 7);
X("set", trackerPrototype, trackerPrototype.set, 4);
X("send", trackerPrototype, trackerPrototype.send);
X("requireSync", trackerPrototype, trackerPrototype.ma);
var modelPrototype = iModel.prototype;
X("get", modelPrototype, modelPrototype.get);
X("set", modelPrototype, modelPrototype.set);
var scriptIsHttps = !1;
//
if (!isHTTPS() && !forceHTTPS) {
// 如果设置使用https,则通过引入的js文件地址来判断是否使用https
a: {
for (var scripts = idoc.getElementsByTagName("script"), i = 0; i < scripts.length && 100 > i; i++) {
var scriptSrc = scripts[i].src;
//TODO change URL
if (scriptSrc && 0 == scriptSrc.indexOf("https://" + iAnalyseBaseURL + "/analytics")) {
reg(33);
scriptIsHttps = !0;
break a
}
}
}
scriptIsHttps && (forceHTTPS = !0)
}
isHTTPS() || forceHTTPS || !workWithSpeedAnchor(new SpeedAnchor(1E4)) || (reg(36), forceHTTPS = !0);
(iwin.gaplugins = iwin.gaplugins || {}).Linker = Linker;
var linkerPrototype = Linker.prototype;
execBasePlugins("linker", Linker);
X("decorate", linkerPrototype, linkerPrototype.ca, 20);
X("autoLink", linkerPrototype, linkerPrototype.S, 25);
execBasePlugins("displayfeatures", displayFeaturesPlugin);
execBasePlugins("adfeatures", displayFeaturesPlugin);
//// tmpGa.q ga的js代码执行前,push到ga命令队列里面的命令
//tmpGa = tmpGa && tmpGa.q;
a = a && a.q;
isArray(a) ? MethodQueue.D.apply(GA, a) : reg(50)
}
};
/**
*
*
*/
GA.da = function () {
for (var trackers = GA.getAll(), i = 0; i < trackers.length; i++)
trackers[i].get(TRACKER_NAME)
};
var startUp = GA.N;
var gaObj = iwin[GA_HOOK];
gaObj && gaObj.r ? startUp() : bootUp(startUp);
bootUp(function () {
MethodQueue.D(["provide", "render", emptyFunction])
});
/**
* str to Number
* 将字符串转换成一个数字
* 同一个字符串的输入转换结果是固定的
* 通常用于将随机字符串转换成数字,然后计算概率
*
* function str2Num(str)
*/
function str2Num(str) {
var resInt = 1, charCode, i;
if (str)
for (resInt = 0, i = str.length - 1; 0 <= i; i--)
charCode = str.charCodeAt(i),
resInt = (resInt << 6 & 268435455) + charCode + (charCode << 14),
charCode = resInt & 266338304,
resInt = 0 != charCode ? resInt ^ charCode >> 21 : resInt;
return resInt
}
})(window);
/**
* Created by zhangmx on 11/1/16.
*/
(function () {
var $c = function (a) {
this.w = a || []
};
$c.prototype.set = function (a) {
this.w[a] = !0
}
;
$c.prototype.encode = function () {
for (var a = [], b = 0; b < this.w.length; b++)
this.w[b] && (a[Math.floor(b / 6)] ^= 1 << b % 6);
for (b = 0; b < a.length; b++)
a[b] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(a[b] || 0);
return a.join("") + "~"
}
;
var vd = new $c;
function J(a) {
vd.set(a)
}
var Nd = function (a, b) {
var c = new $c(Dd(a));
c.set(b);
a.set(Gd, c.w)
}
, Td = function (a) {
a = Dd(a);
a = new $c(a);
for (var b = vd.w.slice(), c = 0; c < a.w.length; c++)
b[c] = b[c] || a.w[c];
return (new $c(b)).encode()
}
, Dd = function (a) {
a = a.get(Gd);
ka(a) || (a = []);
return a
};
var ea = function (a) {
return "function" == typeof a
}
, ka = function (a) {
return "[object Array]" == Object.prototype.toString.call(Object(a))
}
, qa = function (a) {
return void 0 != a && -1 < (a.constructor + "").indexOf("String")
}
, D = function (a, b) {
return 0 == a.indexOf(b)
}
, sa = function (a) {
return a ? a.replace(/^[\s\xa0]+|[\s\xa0]+$/g, "") : ""
}
, ta = function (a) {
var b = M.createElement("img");
b.width = 1;
b.height = 1;
b.src = a;
return b
}
, ua = function () {
}
, K = function (a) {
if (encodeURIComponent instanceof Function)
return encodeURIComponent(a);
J(28);
return a
}
, L = function (a, b, c, d) {
try {
a.addEventListener ? a.addEventListener(b, c, !!d) : a.attachEvent && a.attachEvent("on" + b, c)
} catch (e) {
J(27)
}
}
, f = /^[\w\-:/.?=&%!]+$/
, wa = function (a, b, c) {
a && (c ? (c = "",
b && f.test(b) && (c = ' id="' + b + '"'),
f.test(a) && M.write("<script" + c + ' src="' + a + '">\x3c/script>')) : (c = M.createElement("script"),
c.type = "text/javascript",
c.async = !0,
c.src = a,
b && (c.id = b),
a = M.getElementsByTagName("script")[0],
a.parentNode.insertBefore(c, a)))
}
, Ud = function () {
return "https:" == M.location.protocol
}
, E = function (a, b) {
var c = a.match("(?:&|#|\\?)" + K(b).replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") + "=([^&#]*)");
return c && 2 == c.length ? c[1] : ""
}
, xa = function () {
var a = "" + M.location.hostname;
return 0 == a.indexOf("www.") ? a.substring(4) : a
}
, ya = function (a) {
var b = M.referrer;
if (/^https?:\/\//i.test(b)) {
if (a)
return b;
a = "//" + M.location.hostname;
var c = b.indexOf(a);
if (5 == c || 6 == c)
if (a = b.charAt(c + a.length),
"/" == a || "?" == a || "" == a || ":" == a)
return;
return b
}
}
, za = function (a, b) {
if (1 == b.length && null != b[0] && "object" === typeof b[0])
return b[0];
for (var c = {}, d = Math.min(a.length + 1, b.length), e = 0; e < d; e++)
if ("object" === typeof b[e]) {
for (var g in b[e])
b[e].hasOwnProperty(g) && (c[g] = b[e][g]);
break
} else
e < a.length && (c[a[e]] = b[e]);
return c
};
var ee = function () {
this.keys = [];
this.values = {};
this.m = {}
};
ee.prototype.set = function (a, b, c) {
this.keys.push(a);
c ? this.m[":" + a] = b : this.values[":" + a] = b
}
;
ee.prototype.get = function (a) {
return this.m.hasOwnProperty(":" + a) ? this.m[":" + a] : this.values[":" + a]
}
;
ee.prototype.map = function (a) {
for (var b = 0; b < this.keys.length; b++) {
var c = this.keys[b]
, d = this.get(c);
d && a(c, d)
}
}
;
var O = window
, M = document;
var F = window
, G = function (a) {
var b = F._gaUserPrefs;
if (b && b.ioo && b.ioo() || a && !0 === F["ga-disable-" + a])
return !0;
try {
var c = F.external;
if (c && c._gaUserPrefs && "oo" == c._gaUserPrefs)
return !0
} catch (d) {
}
return !1
};
var Ca = function (a) {
var b = []
, c = M.cookie.split(";");
a = new RegExp("^\\s*" + a + "=\\s*(.*?)\\s*$");
for (var d = 0; d < c.length; d++) {
var e = c[d].match(a);
e && b.push(e[1])
}
return b
}
, zc = function (a, b, c, d, e, g) {
e = G(e) ? !1 : eb.test(M.location.hostname) || "/" == c && vc.test(d) ? !1 : !0;
if (!e)
return !1;
b && 1200 < b.length && (b = b.substring(0, 1200),
J(24));
c = a + "=" + b + "; path=" + c + "; ";
g && (c += "expires=" + (new Date((new Date).getTime() + g)).toGMTString() + "; ");
d && "none" != d && (c += "domain=" + d + ";");
d = M.cookie;
M.cookie = c;
if (!(d = d != M.cookie))
a: {
a = Ca(a);
for (d = 0; d < a.length; d++)
if (b == a[d]) {
d = !0;
break a
}
d = !1
}
return d
}
, Cc = function (a) {
return K(a).replace(/\(/g, "%28").replace(/\)/g, "%29")
}
, vc = /^(www\.)?google(\.com?)?(\.[a-z]{2})?$/
, eb = /(^|\.)doubleclick\.net$/i;
var oc = function () {
return (Ba || Ud() ? "https:" : "http:") + "//www.google-analytics.com"
}
, Da = function (a) {
this.name = "len";
this.message = a + "-8192"
}
, ba = function (a, b, c) {
c = c || ua;
if (2036 >= b.length)
wc(a, b, c);
else if (8192 >= b.length)
x(a, b, c) || wd(a, b, c) || wc(a, b, c);
else
throw ge("len", b.length),
new Da(b.length);
}
, wc = function (a, b, c) {
var d = ta(a + "?" + b);
d.onload = d.onerror = function () {
d.onload = null;
d.onerror = null;
c()
}
}
, wd = function (a, b, c) {
var d = O.XMLHttpRequest;
if (!d)
return !1;
var e = new d;
if (!("withCredentials" in e))
return !1;
e.open("POST", a, !0);
e.withCredentials = !0;
e.setRequestHeader("Content-Type", "text/plain");
e.onreadystatechange = function () {
4 == e.readyState && (c(),
e = null )
}
;
e.send(b);
return !0
}
, x = function (a, b, c) {
return O.navigator.sendBeacon ? O.navigator.sendBeacon(a, b) ? (c(),
!0) : !1 : !1
}
, ge = function (a, b, c) {
1 <= 100 * Math.random() || G("?") || (a = ["t=error", "_e=" + a, "_v=j47", "sr=1"],
b && a.push("_f=" + b),
c && a.push("_m=" + K(c.substring(0, 100))),
a.push("aip=1"),
a.push("z=" + hd()),
wc(oc() + "/collect", a.join("&"), ua))
};
var h = function (a) {
var b = O.gaData = O.gaData || {};
return b[a] = b[a] || {}
};
var Ha = function () {
this.M = []
};
Ha.prototype.add = function (a) {
this.M.push(a)
}
;
Ha.prototype.D = function (a) {
try {
for (var b = 0; b < this.M.length; b++) {
var c = a.get(this.M[b]);
c && ea(c) && c.call(O, a)
}
} catch (d) {
}
b = a.get(Ia);
b != ua && ea(b) && (a.set(Ia, ua, !0),
setTimeout(b, 10))
}
;
function Ja(a) {
if (100 != a.get(Ka) && La(P(a, Q)) % 1E4 >= 100 * R(a, Ka))
throw "abort";
}
function Ma(a) {
if (G(P(a, Na)))
throw "abort";
}
function Oa() {
var a = M.location.protocol;
if ("http:" != a && "https:" != a)
throw "abort";
}
function Pa(a) {
try {
O.navigator.sendBeacon ? J(42) : O.XMLHttpRequest && "withCredentials" in new O.XMLHttpRequest && J(40)
} catch (c) {
}
a.set(ld, Td(a), !0);
a.set(Ac, R(a, Ac) + 1);
var b = [];
Qa.map(function (c, d) {
if (d.F) {
var e = a.get(c);
void 0 != e && e != d.defaultValue && ("boolean" == typeof e && (e *= 1),
b.push(d.F + "=" + K("" + e)))
}
});
b.push("z=" + Bd());
a.set(Ra, b.join("&"), !0)
}
function Sa(a) {
var b = P(a, gd) || oc() + "/collect"
, c = P(a, fa);
!c && a.get(Vd) && (c = "beacon");
if (c) {
var d = P(a, Ra)
, e = a.get(Ia)
, e = e || ua;
"image" == c ? wc(b, d, e) : "xhr" == c && wd(b, d, e) || "beacon" == c && x(b, d, e) || ba(b, d, e)
} else
ba(b, P(a, Ra), a.get(Ia));
b = a.get(Na);
b = h(b);
c = b.hitcount;
b.hitcount = c ? c + 1 : 1;
b = a.get(Na);
delete h(b).pending_experiments;
a.set(Ia, ua, !0)
}
function Hc(a) {
(O.gaData = O.gaData || {}).expId && a.set(Nc, (O.gaData = O.gaData || {}).expId);
(O.gaData = O.gaData || {}).expVar && a.set(Oc, (O.gaData = O.gaData || {}).expVar);
var b;
var c = a.get(Na);
if (c = h(c).pending_experiments) {
var d = [];
for (b in c)
c.hasOwnProperty(b) && c[b] && d.push(encodeURIComponent(b) + "." + encodeURIComponent(c[b]));
b = d.join("!")
} else
b = void 0;
b && a.set(m, b, !0)
}
function cd() {
if (O.navigator && "preview" == O.navigator.loadPurpose)
throw "abort";
}
function yd(a) {
var b = O.gaDevIds;
ka(b) && 0 != b.length && a.set("&did", b.join(","), !0)
}
function vb(a) {
if (!a.get(Na))
throw "abort";
}
;
var hd = function () {
return Math.round(2147483647 * Math.random())
}
, Bd = function () {
try {
var a = new Uint32Array(1);
O.crypto.getRandomValues(a);
return a[0] & 2147483647
} catch (b) {
return hd()
}
};
function Ta(a) {
var b = R(a, Ua);
500 <= b && J(15);
var c = P(a, Va);
if ("transaction" != c && "item" != c) {
var c = R(a, Wa)
, d = (new Date).getTime()
, e = R(a, Xa);
0 == e && a.set(Xa, d);
e = Math.round(2 * (d - e) / 1E3);
0 < e && (c = Math.min(c + e, 20),
a.set(Xa, d));
if (0 >= c)
throw "abort";
a.set(Wa, --c)
}
a.set(Ua, ++b)
}
;
var Ya = function () {
this.data = new ee
}
, Qa = new ee
, Za = [];
Ya.prototype.get = function (a) {
var b = $a(a)
, c = this.data.get(a);
b && void 0 == c && (c = ea(b.defaultValue) ? b.defaultValue() : b.defaultValue);
return b && b.Z ? b.Z(this, a, c) : c
}
;
var P = function (a, b) {
var c = a.get(b);
return void 0 == c ? "" : "" + c
}
, R = function (a, b) {
var c = a.get(b);
return void 0 == c || "" === c ? 0 : 1 * c
};
Ya.prototype.set = function (a, b, c) {
if (a)
if ("object" == typeof a)
for (var d in a)
a.hasOwnProperty(d) && ab(this, d, a[d], c);
else
ab(this, a, b, c)
}
;
var ab = function (a, b, c, d) {
if (void 0 != c)
switch (b) {
case Na:
wb.test(c)
}
var e = $a(b);
e && e.o ? e.o(a, b, c, d) : a.data.set(b, c, d)
}
, bb = function (a, b, c, d, e) {
this.name = a;
this.F = b;
this.Z = d;
this.o = e;
this.defaultValue = c
}
, $a = function (a) {
var b = Qa.get(a);
if (!b)
for (var c = 0; c < Za.length; c++) {
var d = Za[c]
, e = d[0].exec(a);
if (e) {
b = d[1](e);
Qa.set(b.name, b);
break
}
}
return b
}
, yc = function (a) {
var b;
Qa.map(function (c, d) {
d.F == a && (b = d)
});
return b && b.name
}
, S = function (a, b, c, d, e) {
a = new bb(a, b, c, d, e);
Qa.set(a.name, a);
return a.name
}
, cb = function (a, b) {
Za.push([new RegExp("^" + a + "$"), b])
}
, T = function (a, b, c) {
return S(a, b, c, void 0, db)
}
, db = function () {
};
var gb = qa(window.GoogleAnalyticsObject) && sa(window.GoogleAnalyticsObject) || "ga"
, Ba = !1
, hb = T("apiVersion", "v")
, ib = T("clientVersion", "_v");
S("anonymizeIp", "aip");
var jb = S("adSenseId", "a")
, Va = S("hitType", "t")
, Ia = S("hitCallback")
, Ra = S("hitPayload");
S("nonInteraction", "ni");
S("currencyCode", "cu");
S("dataSource", "ds");
var Vd = S("useBeacon", void 0, !1)
, fa = S("transport");
S("sessionControl", "sc", "");
S("sessionGroup", "sg");
S("queueTime", "qt");
var Ac = S("_s", "_s");
S("screenName", "cd");
var kb = S("location", "dl", "")
, lb = S("referrer", "dr")
, mb = S("page", "dp", "");
S("hostname", "dh");
var nb = S("language", "ul")
, ob = S("encoding", "de");
S("title", "dt", function () {
return M.title || void 0
});
cb("contentGroup([0-9]+)", function (a) {
return new bb(a[0], "cg" + a[1])
});
var pb = S("screenColors", "sd")
, qb = S("screenResolution", "sr")
, rb = S("viewportSize", "vp")
, sb = S("javaEnabled", "je")
, tb = S("flashVersion", "fl");
S("campaignId", "ci");
S("campaignName", "cn");
S("campaignSource", "cs");
S("campaignMedium", "cm");
S("campaignKeyword", "ck");
S("campaignContent", "cc");
var ub = S("eventCategory", "ec")
, xb = S("eventAction", "ea")
, yb = S("eventLabel", "el")
, zb = S("eventValue", "ev")
, Bb = S("socialNetwork", "sn")
, Cb = S("socialAction", "sa")
, Db = S("socialTarget", "st")
, Eb = S("l1", "plt")
, Fb = S("l2", "pdt")
, Gb = S("l3", "dns")
, Hb = S("l4", "rrt")
, Ib = S("l5", "srt")
, Jb = S("l6", "tcp")
, Kb = S("l7", "dit")
, Lb = S("l8", "clt")
, Mb = S("timingCategory", "utc")
, Nb = S("timingVar", "utv")
, Ob = S("timingLabel", "utl")
, Pb = S("timingValue", "utt");
S("appName", "an");
S("appVersion", "av", "");
S("appId", "aid", "");
S("appInstallerId", "aiid", "");
S("exDescription", "exd");
S("exFatal", "exf");
var Nc = S("expId", "xid")
, Oc = S("expVar", "xvar")
, m = S("exp", "exp")
, Rc = S("_utma", "_utma")
, Sc = S("_utmz", "_utmz")
, Tc = S("_utmht", "_utmht")
, Ua = S("_hc", void 0, 0)
, Xa = S("_ti", void 0, 0)
, Wa = S("_to", void 0, 20);
cb("dimension([0-9]+)", function (a) {
return new bb(a[0], "cd" + a[1])
});
cb("metric([0-9]+)", function (a) {
return new bb(a[0], "cm" + a[1])
});
S("linkerParam", void 0, void 0, Bc, db);
var ld = S("usage", "_u")
, Gd = S("_um");
S("forceSSL", void 0, void 0, function () {
return Ba
}, function (a, b, c) {
J(34);
Ba = !!c
});
var ed = S("_j1", "jid");
cb("\\&(.*)", function (a) {
var b = new bb(a[0], a[1])
, c = yc(a[0].substring(1));
c && (b.Z = function (a) {
return a.get(c)
}
,
b.o = function (a, b, g, ca) {
a.set(c, g, ca)
}
,
b.F = void 0);
return b
});
var Qb = T("_oot")
, dd = S("previewTask")
, Rb = S("checkProtocolTask")
, md = S("validationTask")
, Sb = S("checkStorageTask")
, Uc = S("historyImportTask")
, Tb = S("samplerTask")
, Vb = S("_rlt")
, Wb = S("buildHitTask")
, Xb = S("sendHitTask")
, Vc = S("ceTask")
, zd = S("devIdTask")
, Cd = S("timingTask")
, Ld = S("displayFeaturesTask")
, V = T("name")
, Q = T("clientId", "cid")
, n = T("clientIdTime")
, Ad = S("userId", "uid")
, Na = T("trackingId", "tid")
, U = T("cookieName", void 0, "_ga")
, W = T("cookieDomain")
, Yb = T("cookiePath", void 0, "/")
, Zb = T("cookieExpires", void 0, 63072E3)
, $b = T("legacyCookieDomain")
, Wc = T("legacyHistoryImport", void 0, !0)
, ac = T("storage", void 0, "cookie")
, bc = T("allowLinker", void 0, !1)
, cc = T("allowAnchor", void 0, !0)
, Ka = T("sampleRate", "sf", 100)
, dc = T("siteSpeedSampleRate", void 0, 1)
, ec = T("alwaysSendReferrer", void 0, !1)
, gd = S("transportUrl")
, Md = S("_r", "_r");
function X(a, b, c, d) {
b[a] = function () {
try {
return d && J(d),
c.apply(this, arguments)
} catch (e) {
throw ge("exc", a, e && e.name),
e;
}
}
}
;
var Od = function (a) {
this.V = a;
this.fa = void 0;
this.$ = !1;
this.oa = void 0;
this.ea = 1
}
, Ed = function (a, b) {
var c;
if (a.fa && a.$)
return 0;
a.$ = !0;
if (b) {
if (a.oa && R(b, a.oa))
return R(b, a.oa);
if (0 == b.get(dc))
return 0
}
if (0 == a.V)
return 0;
void 0 === c && (c = Bd());
return 0 == c % a.V ? Math.floor(c / a.V) % a.ea + 1 : 0
};
function fc() {
var a, b, c;
if ((c = (c = O.navigator) ? c.plugins : null ) && c.length)
for (var d = 0; d < c.length && !b; d++) {
var e = c[d];
-1 < e.name.indexOf("Shockwave Flash") && (b = e.description)
}
if (!b)
try {
a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"),
b = a.GetVariable("$version")
} catch (g) {
}
if (!b)
try {
a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"),
b = "WIN 6,0,21,0",
a.AllowScriptAccess = "always",
b = a.GetVariable("$version")
} catch (g) {
}
if (!b)
try {
a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),
b = a.GetVariable("$version")
} catch (g) {
}
b && (a = b.match(/[\d]+/g)) && 3 <= a.length && (b = a[0] + "." + a[1] + " r" + a[2]);
return b || void 0
}
;
var aa = function (a) {
var b = Math.min(R(a, dc), 100);
return La(P(a, Q)) % 100 >= b ? !1 : !0
}
, gc = function (a) {
var b = {};
if (Ec(b) || Fc(b)) {
var c = b[Eb];
void 0 == c || Infinity == c || isNaN(c) || (0 < c ? (Y(b, Gb),
Y(b, Jb),
Y(b, Ib),
Y(b, Fb),
Y(b, Hb),
Y(b, Kb),
Y(b, Lb),
a(b)) : L(O, "load", function () {
gc(a)
}, !1))
}
}
, Ec = function (a) {
var b = O.performance || O.webkitPerformance
, b = b && b.timing;
if (!b)
return !1;
var c = b.navigationStart;
if (0 == c)
return !1;
a[Eb] = b.loadEventStart - c;
a[Gb] = b.domainLookupEnd - b.domainLookupStart;
a[Jb] = b.connectEnd - b.connectStart;
a[Ib] = b.responseStart - b.requestStart;
a[Fb] = b.responseEnd - b.responseStart;
a[Hb] = b.fetchStart - c;
a[Kb] = b.domInteractive - c;
a[Lb] = b.domContentLoadedEventStart - c;
return !0
}
, Fc = function (a) {
if (O.top != O)
return !1;
var b = O.external
, c = b && b.onloadT;
b && !b.isValidLoadTime && (c = void 0);
2147483648 < c && (c = void 0);
0 < c && b.setPageReadyTime();
if (void 0 == c)
return !1;
a[Eb] = c;
return !0
}
, Y = function (a, b) {
var c = a[b];
if (isNaN(c) || Infinity == c || 0 > c)
a[b] = void 0
}
, Fd = function (a) {
return function (b) {
if ("pageview" == b.get(Va) && !a.I) {
a.I = !0;
var c = aa(b);
b = 0 < E(b.get(kb), "gclid").length;
(c || b) && gc(function (b) {
a.send(c ? "timing" : "adtiming", b)
})
}
}
};
var hc = !1
, mc = function (a) {
if ("cookie" == P(a, ac)) {
var b = P(a, U)
, c = nd(a)
, d = kc(P(a, Yb))
, e = lc(P(a, W))
, g = 1E3 * R(a, Zb)
, ca = P(a, Na);
if ("auto" != e)
zc(b, c, d, e, ca, g) && (hc = !0);
else {
J(32);
var l;
a: {
c = [];
e = xa().split(".");
if (4 == e.length && (l = e[e.length - 1],
parseInt(l, 10) == l)) {
l = ["none"];
break a
}
for (l = e.length - 2; 0 <= l; l--)
c.push(e.slice(l).join("."));
c.push("none");
l = c
}
for (var k = 0; k < l.length; k++)
if (e = l[k],
a.data.set(W, e),
c = nd(a),
zc(b, c, d, e, ca, g)) {
hc = !0;
return
}
a.data.set(W, "auto")
}
}
}
, nc = function (a) {
if ("cookie" == P(a, ac) && !hc && (mc(a),
!hc))
throw "abort";
}
, Yc = function (a) {
if (a.get(Wc)) {
var b = P(a, W)
, c = P(a, $b) || xa()
, d = Xc("__utma", c, b);
d && (J(19),
a.set(Tc, (new Date).getTime(), !0),
a.set(Rc, d.R),
(b = Xc("__utmz", c, b)) && d.hash == b.hash && a.set(Sc, b.R))
}
}
, nd = function (a) {
var b = Cc(P(a, Q))
, c = lc(P(a, W)).split(".").length;
a = jc(P(a, Yb));
1 < a && (c += "-" + a);
return ["GA1", c, b].join(".")
}
, Gc = function (a, b, c) {
for (var d = [], e = [], g, ca = 0; ca < a.length; ca++) {
var l = a[ca];
l.H[c] == b ? d.push(l) : void 0 == g || l.H[c] < g ? (e = [l],
g = l.H[c]) : l.H[c] == g && e.push(l)
}
return 0 < d.length ? d : e
}
, lc = function (a) {
return 0 == a.indexOf(".") ? a.substr(1) : a
}
, kc = function (a) {
if (!a)
return "/";
1 < a.length && a.lastIndexOf("/") == a.length - 1 && (a = a.substr(0, a.length - 1));
0 != a.indexOf("/") && (a = "/" + a);
return a
}
, jc = function (a) {
a = kc(a);
return "/" == a ? 1 : a.split("/").length
};
function Xc(a, b, c) {
"none" == b && (b = "");
var d = []
, e = Ca(a);
a = "__utma" == a ? 6 : 2;
for (var g = 0; g < e.length; g++) {
var ca = ("" + e[g]).split(".");
ca.length >= a && d.push({
hash: ca[0],
R: e[g],
O: ca
})
}
if (0 != d.length)
return 1 == d.length ? d[0] : Zc(b, d) || Zc(c, d) || Zc(null, d) || d[0]
}
function Zc(a, b) {
var c, d;
null == a ? c = d = 1 : (c = La(a),
d = La(D(a, ".") ? a.substring(1) : "." + a));
for (var e = 0; e < b.length; e++)
if (b[e].hash == c || b[e].hash == d)
return b[e]
}
;
var od = new RegExp(/^https?:\/\/([^\/:]+)/)
, pd = /(.*)([?&#])(?:_ga=[^&#]*)(?:&?)(.*)/;
function Bc(a) {
a = a.get(Q);
var b = Ic(a, 0);
return "_ga=1." + K(b + "." + a)
}
function Ic(a, b) {
for (var c = new Date, d = O.navigator, e = d.plugins || [], c = [a, d.userAgent, c.getTimezoneOffset(), c.getYear(), c.getDate(), c.getHours(), c.getMinutes() + b], d = 0; d < e.length; ++d)
c.push(e[d].description);
return La(c.join("."))
}
var Dc = function (a) {
J(48);
this.target = a;
this.T = !1
};
Dc.prototype.ca = function (a, b) {
if (a.tagName) {
if ("a" == a.tagName.toLowerCase()) {
a.href && (a.href = qd(this, a.href, b));
return
}
if ("form" == a.tagName.toLowerCase())
return rd(this, a)
}
if ("string" == typeof a)
return qd(this, a, b)
}
;
var qd = function (a, b, c) {
var d = pd.exec(b);
d && 3 <= d.length && (b = d[1] + (d[3] ? d[2] + d[3] : ""));
a = a.target.get("linkerParam");
var e = b.indexOf("?")
, d = b.indexOf("#");
c ? b += (-1 == d ? "#" : "&") + a : (c = -1 == e ? "?" : "&",
b = -1 == d ? b + (c + a) : b.substring(0, d) + c + a + b.substring(d));
return b = b.replace(/&+_ga=/, "&_ga=")
}
, rd = function (a, b) {
if (b && b.action) {
var c = a.target.get("linkerParam").split("=")[1];
if ("get" == b.method.toLowerCase()) {
for (var d = b.childNodes || [], e = 0; e < d.length; e++)
if ("_ga" == d[e].name) {
d[e].setAttribute("value", c);
return
}
d = M.createElement("input");
d.setAttribute("type", "hidden");
d.setAttribute("name", "_ga");
d.setAttribute("value", c);
b.appendChild(d)
} else
"post" == b.method.toLowerCase() && (b.action = qd(a, b.action))
}
};
Dc.prototype.S = function (a, b, c) {
function d(c) {
try {
c = c || O.event;
var d;
a: {
var g = c.target || c.srcElement;
for (c = 100; g && 0 < c;) {
if (g.href && g.nodeName.match(/^a(?:rea)?$/i)) {
d = g;
break a
}
g = g.parentNode;
c--
}
d = {}
}
("http:" == d.protocol || "https:" == d.protocol) && sd(a, d.hostname || "") && d.href && (d.href = qd(e, d.href, b))
} catch (k) {
J(26)
}
}
var e = this;
this.T || (this.T = !0,
L(M, "mousedown", d, !1),
L(M, "keyup", d, !1));
c && L(M, "submit", function (b) {
b = b || O.event;
if ((b = b.target || b.srcElement) && b.action) {
var c = b.action.match(od);
c && sd(a, c[1]) && rd(e, b)
}
})
}
;
function sd(a, b) {
if (b == M.location.hostname)
return !1;
for (var c = 0; c < a.length; c++)
if (a[c] instanceof RegExp) {
if (a[c].test(b))
return !0
} else if (0 <= b.indexOf(a[c]))
return !0;
return !1
}
;
var p = /^(GTM|OPT)-[A-Z0-9]+$/
, q = /;_gaexp=[^;]*/g
, r = /;((__utma=)|([^;=]+=GAX?\d+\.))[^;]*/g
, t = function (a) {
function b(a, b) {
b && (c += "&" + a + "=" + K(b))
}
var c = "https://www.google-analytics.com/gtm/js?id=" + K(a.id);
"dataLayer" != a.B && b("l", a.B);
b("t", a.target);
b("cid", a.ja);
b("cidt", a.ka);
b("gac", a.la);
b("aip", a.ia);
a.na && b("m", "sync");
b("cycle", a.G);
return c
};
var Jd = function (a, b, c) {
this.U = ed;
this.aa = b;
(b = c) || (b = (b = P(a, V)) && "t0" != b ? Wd.test(b) ? "_gat_" + Cc(P(a, Na)) : "_gat_" + Cc(b) : "_gat");
this.Y = b;
Ed(new Od(100), a) && (J(30),
this.pa = !0)
}
, Rd = function (a, b) {
var c = b.get(Wb);
b.set(Wb, function (b) {
Pd(a, b);
var d = c(b);
Qd(a, b);
return d
});
var d = b.get(Xb);
b.set(Xb, function (b) {
var c = d(b);
Id(a, b);
return c
})
}
, Pd = function (a, b) {
b.get(a.U) || ("1" == Ca(a.Y)[0] ? b.set(a.U, "", !0) : b.set(a.U, "" + hd(), !0))
}
, Qd = function (a, b) {
if (b.get(a.U)) {
var c = 6E5;
a.pa && (c /= 10);
zc(a.Y, "1", b.get(Yb), b.get(W), b.get(Na), c)
}
}
, Id = function (a, b) {
if (b.get(a.U)) {
var c = new ee
, d = function (a) {
$a(a).F && c.set($a(a).F, b.get(a))
};
d(hb);
d(ib);
d(Na);
d(Q);
d(Ad);
d(a.U);
c.set($a(ld).F, Td(b));
var e = a.aa;
c.map(function (a, b) {
e += K(a) + "=";
e += K("" + b) + "&"
});
e += "z=" + hd();
ta(e);
b.set(a.U, "", !0)
}
}
, Wd = /^gtm\d+$/;
var fd = function (a, b) {
var c = a.b;
if (!c.get("dcLoaded")) {
Nd(c, 29);
b = b || {};
var d;
b[U] && (d = Cc(b[U]));
d = new Jd(c, "https://stats.g.doubleclick.net/r/collect?t=dc&aip=1&_r=3&", d);
Rd(d, c);
c.set("dcLoaded", !0)
}
};
var Sd = function (a) {
if (!a.get("dcLoaded") && "cookie" == a.get(ac)) {
Nd(a, 51);
var b = new Jd(a);
Pd(b, a);
Qd(b, a);
a.get(b.U) && (a.set(Md, 1, !0),
a.set(gd, oc() + "/r/collect", !0))
}
};
var Lc = function () {
var a = O.gaGlobal = O.gaGlobal || {};
return a.hid = a.hid || hd()
};
var ad, bd = function (a, b, c) {
if (!ad) {
var d;
d = M.location.hash;
var e = O.name
, g = /^#?gaso=([^&]*)/;
if (e = (d = (d = d && d.match(g) || e && e.match(g)) ? d[1] : Ca("GASO")[0] || "") && d.match(/^(?:!([-0-9a-z.]{1,40})!)?([-.\w]{10,1200})$/i))
zc("GASO", "" + d, c, b, a, 0),
window._udo || (window._udo = b),
window._utcp || (window._utcp = c),
a = e[1],
wa("https://www.google.com/analytics/web/inpage/pub/inpage.js?" + (a ? "prefix=" + a + "&" : "") + hd(), "_gasojs");
ad = !0
}
};
var wb = /^(UA|YT|MO|GP)-(\d+)-(\d+)$/
, pc = function (a) {
function b(a, b) {
d.b.data.set(a, b)
}
function c(a, c) {
b(a, c);
d.filters.add(a)
}
var d = this;
this.b = new Ya;
this.filters = new Ha;
b(V, a[V]);
b(Na, sa(a[Na]));
b(U, a[U]);
b(W, a[W] || xa());
b(Yb, a[Yb]);
b(Zb, a[Zb]);
b($b, a[$b]);
b(Wc, a[Wc]);
b(bc, a[bc]);
b(cc, a[cc]);
b(Ka, a[Ka]);
b(dc, a[dc]);
b(ec, a[ec]);
b(ac, a[ac]);
b(Ad, a[Ad]);
b(n, a[n]);
b(hb, 1);
b(ib, "j47");
c(Qb, Ma);
c(dd, cd);
c(Rb, Oa);
c(md, vb);
c(Sb, nc);
c(Uc, Yc);
c(Tb, Ja);
c(Vb, Ta);
c(Vc, Hc);
c(zd, yd);
c(Ld, Sd);
c(Wb, Pa);
c(Xb, Sa);
c(Cd, Fd(this));
Jc(this.b, a[Q]);
Kc(this.b);
this.b.set(jb, Lc());
bd(this.b.get(Na), this.b.get(W), this.b.get(Yb))
}
, Jc = function (a, b) {
if ("cookie" == P(a, ac)) {
hc = !1;
var c;
b: {
var d = Ca(P(a, U));
if (d && !(1 > d.length)) {
c = [];
for (var e = 0; e < d.length; e++) {
var g;
g = d[e].split(".");
var ca = g.shift();
("GA1" == ca || "1" == ca) && 1 < g.length ? (ca = g.shift().split("-"),
1 == ca.length && (ca[1] = "1"),
ca[0] *= 1,
ca[1] *= 1,
g = {
H: ca,
s: g.join(".")
}) : g = void 0;
g && c.push(g)
}
if (1 == c.length) {
J(13);
c = c[0].s;
break b
}
if (0 == c.length)
J(12);
else {
J(14);
d = lc(P(a, W)).split(".").length;
c = Gc(c, d, 0);
if (1 == c.length) {
c = c[0].s;
break b
}
d = jc(P(a, Yb));
c = Gc(c, d, 1);
c = c[0] && c[0].s;
break b
}
}
c = void 0
}
c || (c = P(a, W),
d = P(a, $b) || xa(),
c = Xc("__utma", d, c),
void 0 != c ? (J(10),
c = c.O[1] + "." + c.O[2]) : c = void 0);
c && (a.data.set(Q, c),
hc = !0)
}
c = a.get(cc);
if (e = E(M.location[c ? "href" : "search"], "_ga"))
a.get(bc) ? (c = e.indexOf("."),
-1 == c ? J(22) : (d = e.substring(c + 1),
"1" != e.substring(0, c) ? J(22) : (c = d.indexOf("."),
-1 == c ? J(22) : (e = d.substring(0, c),
c = d.substring(c + 1),
e != Ic(c, 0) && e != Ic(c, -1) && e != Ic(c, -2) ? J(23) : (J(11),
a.data.set(Q, c)))))) : J(21);
b && (J(9),
a.data.set(Q, K(b)));
if (!a.get(Q))
if (c = (c = O.gaGlobal && O.gaGlobal.vid) && -1 != c.search(/^(?:utma\.)?\d+\.\d+$/) ? c : void 0)
J(17),
a.data.set(Q, c);
else {
J(8);
c = O.navigator.userAgent + (M.cookie ? M.cookie : "") + (M.referrer ? M.referrer : "");
d = c.length;
for (e = O.history.length; 0 < e;)
c += e-- ^ d++;
a.data.set(Q, [hd() ^ La(c) & 2147483647, Math.round((new Date).getTime() / 1E3)].join("."))
}
mc(a)
}
, Kc = function (a) {
var b = O.navigator
, c = O.screen
, d = M.location;
a.set(lb, ya(a.get(ec)));
if (d) {
var e = d.pathname || "";
"/" != e.charAt(0) && (J(31),
e = "/" + e);
a.set(kb, d.protocol + "//" + d.hostname + e + d.search)
}
c && a.set(qb, c.width + "x" + c.height);
c && a.set(pb, c.colorDepth + "-bit");
var c = M.documentElement
, g = (e = M.body) && e.clientWidth && e.clientHeight
, ca = [];
c && c.clientWidth && c.clientHeight && ("CSS1Compat" === M.compatMode || !g) ? ca = [c.clientWidth, c.clientHeight] : g && (ca = [e.clientWidth, e.clientHeight]);
c = 0 >= ca[0] || 0 >= ca[1] ? "" : ca.join("x");
a.set(rb, c);
a.set(tb, fc());
a.set(ob, M.characterSet || M.charset);
a.set(sb, b && "function" === typeof b.javaEnabled && b.javaEnabled() || !1);
a.set(nb, (b && (b.language || b.browserLanguage) || "").toLowerCase());
if (d && a.get(cc) && (b = M.location.hash)) {
b = b.split(/[?&#]+/);
d = [];
for (c = 0; c < b.length; ++c)
(D(b[c], "utm_id") || D(b[c], "utm_campaign") || D(b[c], "utm_source") || D(b[c], "utm_medium") || D(b[c], "utm_term") || D(b[c], "utm_content") || D(b[c], "gclid") || D(b[c], "dclid") || D(b[c], "gclsrc")) && d.push(b[c]);
0 < d.length && (b = "#" + d.join("&"),
a.set(kb, a.get(kb) + b))
}
};
pc.prototype.get = function (a) {
return this.b.get(a)
}
;
pc.prototype.set = function (a, b) {
this.b.set(a, b)
}
;
var qc = {
pageview: [mb],
event: [ub, xb, yb, zb],
social: [Bb, Cb, Db],
timing: [Mb, Nb, Pb, Ob]
};
pc.prototype.send = function (a) {
if (!(1 > arguments.length)) {
var b, c;
"string" === typeof arguments[0] ? (b = arguments[0],
c = [].slice.call(arguments, 1)) : (b = arguments[0] && arguments[0][Va],
c = arguments);
b && (c = za(qc[b] || [], c),
c[Va] = b,
this.b.set(c, void 0, !0),
this.filters.D(this.b),
this.b.data.m = {})
}
}
;
pc.prototype.ma = function (a, b) {
var c = this;
u(a, c, b) || (v(a, function () {
u(a, c, b)
}),
y(String(c.get(V)), a, void 0, b, !0))
}
;
var rc = function (a) {
if ("prerender" == M.visibilityState)
return !1;
a();
return !0
}
, z = function (a) {
if (!rc(a)) {
J(16);
var b = !1
, c = function () {
if (!b && rc(a)) {
b = !0;
var d = c
, e = M;
e.removeEventListener ? e.removeEventListener("visibilitychange", d, !1) : e.detachEvent && e.detachEvent("onvisibilitychange", d)
}
};
L(M, "visibilitychange", c)
}
};
var td = /^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/
, sc = function (a) {
if (ea(a[0]))
this.u = a[0];
else {
var b = td.exec(a[0]);
null != b && 4 == b.length && (this.c = b[1] || "t0",
this.K = b[2] || "",
this.C = b[3],
this.a = [].slice.call(a, 1),
this.K || (this.A = "create" == this.C,
this.i = "require" == this.C,
this.g = "provide" == this.C,
this.ba = "remove" == this.C),
this.i && (3 <= this.a.length ? (this.X = this.a[1],
this.W = this.a[2]) : this.a[1] && (qa(this.a[1]) ? this.X = this.a[1] : this.W = this.a[1])));
b = a[1];
a = a[2];
if (!this.C)
throw "abort";
if (this.i && (!qa(b) || "" == b))
throw "abort";
if (this.g && (!qa(b) || "" == b || !ea(a)))
throw "abort";
if (ud(this.c) || ud(this.K))
throw "abort";
if (this.g && "t0" != this.c)
throw "abort";
}
};
function ud(a) {
return 0 <= a.indexOf(".") || 0 <= a.indexOf(":")
}
;
var Yd, Zd, $d, A;
Yd = new ee;
$d = new ee;
A = new ee;
Zd = {
ec: 45,
ecommerce: 46,
linkid: 47
};
var u = function (a, b, c) {
b == N || b.get(V);
var d = Yd.get(a);
if (!ea(d))
return !1;
b.plugins_ = b.plugins_ || new ee;
if (b.plugins_.get(a))
return !0;
b.plugins_.set(a, new d(b, c || {}));
return !0
}
, y = function (a, b, c, d, e) {
if (!ea(Yd.get(b)) && !$d.get(b)) {
Zd.hasOwnProperty(b) && J(Zd[b]);
if (p.test(b)) {
J(52);
a = N.j(a);
if (!a)
return !0;
c = d || {};
d = {
id: b,
B: c.dataLayer || "dataLayer",
ia: !!a.get("anonymizeIp"),
na: e,
G: !1
};
a.get("&gtm") == b && (d.G = !0);
var g = String(a.get("name"));
"t0" != g && (d.target = g);
G(String(a.get("trackingId"))) || (d.ja = String(a.get(Q)),
d.ka = Number(a.get(n)),
a = c.palindrome ? r : q,
a = (a = M.cookie.replace(/^|(; +)/g, ";").match(a)) ? a.sort().join("").substring(1) : void 0,
d.la = a);
a = d.B;
c = (new Date).getTime();
O[a] = O[a] || [];
c = {
"gtm.start": c
};
e || (c.event = "gtm.js");
O[a].push(c);
c = t(d)
}
!c && Zd.hasOwnProperty(b) ? (J(39),
c = b + ".js") : J(43);
c && (c && 0 <= c.indexOf("/") || (c = (Ba || Ud() ? "https:" : "http:") + "//www.google-analytics.com/plugins/ua/" + c),
d = ae(c),
a = d.protocol,
c = M.location.protocol,
("https:" == a || a == c || ("http:" != a ? 0 : "http:" == c)) && B(d) && (wa(d.url, void 0, e),
$d.set(b, !0)))
}
}
, v = function (a, b) {
var c = A.get(a) || [];
c.push(b);
A.set(a, c)
}
, C = function (a, b) {
Yd.set(a, b);
for (var c = A.get(a) || [], d = 0; d < c.length; d++)
c[d]();
A.set(a, [])
}
, B = function (a) {
var b = ae(M.location.href);
if (D(a.url, "https://www.google-analytics.com/gtm/js?id="))
return !0;
if (a.query || 0 <= a.url.indexOf("?") || 0 <= a.path.indexOf("://"))
return !1;
if (a.host == b.host && a.port == b.port)
return !0;
b = "http:" == a.protocol ? 80 : 443;
return "www.google-analytics.com" == a.host && (a.port || b) == b && D(a.path, "/plugins/") ? !0 : !1
}
, ae = function (a) {
function b(a) {
var b = (a.hostname || "").split(":")[0].toLowerCase()
, c = (a.protocol || "").toLowerCase()
, c = 1 * a.port || ("http:" == c ? 80 : "https:" == c ? 443 : "");
a = a.pathname || "";
D(a, "/") || (a = "/" + a);
return [b, "" + c, a]
}
var c = M.createElement("a");
c.href = M.location.href;
var d = (c.protocol || "").toLowerCase()
, e = b(c)
, g = c.search || ""
, ca = d + "//" + e[0] + (e[1] ? ":" + e[1] : "");
D(a, "//") ? a = d + a : D(a, "/") ? a = ca + a : !a || D(a, "?") ? a = ca + e[2] + (a || g) : 0 > a.split("/")[0].indexOf(":") && (a = ca + e[2].substring(0, e[2].lastIndexOf("/")) + "/" + a);
c.href = a;
d = b(c);
return {
protocol: (c.protocol || "").toLowerCase(),
host: d[0],
port: d[1],
path: d[2],
query: c.search || "",
url: a || ""
}
};
var Z = {
ga: function () {
Z.f = []
}
};
Z.ga();
Z.D = function (a) {
var b = Z.J.apply(Z, arguments)
, b = Z.f.concat(b);
for (Z.f = []; 0 < b.length && !Z.v(b[0]) && !(b.shift(),
0 < Z.f.length);)
;
Z.f = Z.f.concat(b)
}
;
Z.J = function (a) {
for (var b = [], c = 0; c < arguments.length; c++)
try {
var d = new sc(arguments[c]);
d.g ? C(d.a[0], d.a[1]) : (d.i && (d.ha = y(d.c, d.a[0], d.X, d.W)),
b.push(d))
} catch (e) {
}
return b
}
;
Z.v = function (a) {
try {
if (a.u)
a.u.call(O, N.j("t0"));
else {
var b = a.c == gb ? N : N.j(a.c);
if (a.A)
"t0" != a.c || N.create.apply(N, a.a);
else if (a.ba)
N.remove(a.c);
else if (b)
if (a.i) {
if (a.ha && (a.ha = y(a.c, a.a[0], a.X, a.W)),
!u(a.a[0], b, a.W))
return !0
} else if (a.K) {
var c = a.C
, d = a.a
, e = b.plugins_.get(a.K);
e[c].apply(e, d)
} else
b[a.C].apply(b, a.a)
}
} catch (g) {
}
}
;
var N = function (a) {
J(1);
Z.D.apply(Z, [arguments])
};
N.h = {};
N.P = [];
N.L = 0;
N.answer = 42;
var uc = [Na, W, V];
N.create = function (a) {
var b = za(uc, [].slice.call(arguments));
b[V] || (b[V] = "t0");
var c = "" + b[V];
if (N.h[c])
return N.h[c];
b = new pc(b);
N.h[c] = b;
N.P.push(b);
return b
}
;
N.remove = function (a) {
for (var b = 0; b < N.P.length; b++)
if (N.P[b].get(V) == a) {
N.P.splice(b, 1);
N.h[a] = null;
break
}
}
;
N.j = function (a) {
return N.h[a]
}
;
N.getAll = function () {
return N.P.slice(0)
}
;
N.N = function () {
"ga" != gb && J(49);
var a = O[gb];
if (!a || 42 != a.answer) {
N.L = a && a.l;
N.loaded = !0;
var b = O[gb] = N;
X("create", b, b.create);
X("remove", b, b.remove);
X("getByName", b, b.j, 5);
X("getAll", b, b.getAll, 6);
b = pc.prototype;
X("get", b, b.get, 7);
X("set", b, b.set, 4);
X("send", b, b.send);
X("requireSync", b, b.ma);
b = Ya.prototype;
X("get", b, b.get);
X("set", b, b.set);
if (!Ud() && !Ba) {
a: {
for (var b = M.getElementsByTagName("script"), c = 0; c < b.length && 100 > c; c++) {
var d = b[c].src;
if (d && 0 == d.indexOf("https://www.google-analytics.com/analytics")) {
J(33);
b = !0;
break a
}
}
b = !1
}
b && (Ba = !0)
}
Ud() || Ba || !Ed(new Od(1E4)) || (J(36),
Ba = !0);
(O.gaplugins = O.gaplugins || {}).Linker = Dc;
b = Dc.prototype;
C("linker", Dc);
X("decorate", b, b.ca, 20);
X("autoLink", b, b.S, 25);
C("displayfeatures", fd);
C("adfeatures", fd);
a = a && a.q;
ka(a) ? Z.D.apply(N, a) : J(50)
}
}
;
N.da = function () {
for (var a = N.getAll(), b = 0; b < a.length; b++)
a[b].get(V)
}
;
var H = N.N
, I = O[gb];
I && I.r ? H() : z(H);
z(function () {
Z.D(["provide", "render", ua])
});
function La(a) {
var b = 1, c, d;
if (a)
for (b = 0,
d = a.length - 1; 0 <= d; d--)
c = a.charCodeAt(d),
b = (b << 6 & 268435455) + c + (c << 14),
c = b & 266338304,
b = 0 != c ? b ^ c >> 21 : b;
return b
}
;
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment