PageSourceSearch

https://salescmscdn.pa18.com/appStatic/pss-sws-cdn/v1.0.0/static/eventTrack.js

js pa18.com collected 2026-09-25 04:13:02 UTC 32,806 bytes, 713 lines download raw bytes

1//埋点eventTrackJS
2;
3(function (undefined) {
4    "use strict"
5    var _global;
6
7    function EventTrack(opt) {
8        this._initial(opt);
9        // this._utils._createScript('../static/crypto-min.js');
10    }
11    EventTrack.prototype = {
12        constructor: this,
13        _initial: function (opt) {
14            var pageStartTime = new Date(); //当前时间
15            var DEFAULT_CONFIG = {
16                netType: 'web', //内外网标志,web内,dmz外
17                isTest: false, //是否测试环境
18                url: '', //请求地址
19                userId: '', //用户标识
20                sessionId: '', //用于标识同一会话
21                eventId: '', //事件埋点值
22                sourceSystem: '', //所属子系统标识
23                systemVersion: '', //前端应用版本号
24                parameters: '', //拓展字段
25                pageParameters: '', //页面埋点拓展字段
26                publicKey: 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNbin2RgntWkPk3zoMybE9ig3dT77sBIo+N5amXJuG4cly3pX0rfM1h2z6M2apdqgFK/G1TKWk8FsJiR3X8WQguybeQ3NmU+vOAwg1X6lib4igV5/ju3LauYnXNBANh74J9OIgGXwGsjKV4qKuGKWONn8eQyYrpV0sdobmUJg/cQIDAQAB', //加密公钥
27                encryptFields: [], //加密字段
28                pageStartTime: pageStartTime, //进入页面时间
29                pageEndTime: '', //离开页面时间
30                pageDuration: '', //停留页面时间
31                useCache: false, //是否使用缓存
32                pageNo: '', //页面埋点
33                pageTrack: null, //非Vue页面埋点配置
34                pageTrackVue: null, //Vue页面埋点配置
35                _hashChangeTime: '', //记录hashchange开始时间
36                useToken: true, //是否启用鉴权
37                token: '', //鉴权token
38                pageHref:'',//页面埋点的url
39            };
40            this.config = this._utils._extend(DEFAULT_CONFIG, opt, true); //配置参数
41            if (this.config.userId) {
42                this.config.userId = this.config.userId.toLocaleUpperCase();
43            }
44            if (this.config.isTest) { //测试环境
45                if (!this.config.token) this.config.token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiYXMtZXZlbnQtdHJhY2siLCJpYXQiOjE1ODczNjY5OTh9.ChziZQ81GkDW4q2dAqn_Noy9OHWpR6WD7tGENfmV5Rg';
46                if (this.config.netType !== 'web') { //测试外网
47                    this.config.url = 'https://pss-collect-stg3.pingan.com.cn/bdc/behaviordata';
48                } else { //测试内网
49                    this.config.url = 'https://pss-esales-collect-bdc-sender-wgq-stg3-web-padis.paic.com.cn/bdc/behaviordata';
50                }
51            } else { //生产环境
52                if (!this.config.token) this.config.token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiYXMtZXZlbnQtdHJhY2siLCJpYXQiOjE1ODczNjY5OTh9.lV2aXWMdPTsftSZAFq7QbbpwR9bPAuRfkYyMmA8w6yE';
53                if (this.config.netType !== 'web') { //生产外网
54                    this.config.url = 'https://pss-collect.pingan.com.cn/bdc/behaviordata';
55                } else { //生产内网
56                    this.config.url = 'https://pss-esales-collect-bdc-sender-gl-prd-web-padis.paic.com.cn/bdc/behaviordata';
57                }
58            }
59            if (this.config.useToken) {
60                this.config.url = this.config.url.replace('behaviordata', 'v2/behaviordata');
61            }
62            this._initEvents();
63            var currDate = this._utils._fmtDate(pageStartTime, "yyyy-MM-dd hh:mm:ss");
64            if (!this.config.sessionId) {
65                var sessionId = this._utils._getStore('trackSessionId', 'session');
66                if (!sessionId) {
67                    sessionId = this._utils._randomSessionId();
68                    this._utils._setStore('trackSessionId', sessionId, 'session');
69                    this._dealCalc(currDate, true, 'censusClick');
70                    this._dealCalc(currDate, true, 'censusPage');
71                }
72                this.config.sessionId = sessionId;
73            }
74        },
75        /**
76         * 设置配置参数
77         */
78        setConfig: function (config) {
79            this.config = this._utils._extend(this.config, config, true); //配置参数
80            if (this.config.userId) {
81                this.config.userId = this.config.userId.toLocaleUpperCase();
82            }
83            if (this.config.isTest) { //测试环境
84                if (!this.config.token) this.config.token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiYXMtZXZlbnQtdHJhY2siLCJpYXQiOjE1ODczNjY5OTh9.ChziZQ81GkDW4q2dAqn_Noy9OHWpR6WD7tGENfmV5Rg';
85                if (this.config.netType !== 'web') { //测试外网
86                    this.config.url = 'https://pss-collect-stg3.pingan.com.cn/bdc/behaviordata';
87                } else { //测试内网
88                    this.config.url = 'https://pss-esales-collect-bdc-sender-wgq-stg3-web-padis.paic.com.cn/bdc/behaviordata';
89                }
90            } else { //生产环境
91                if (!this.config.token) this.config.token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiYXMtZXZlbnQtdHJhY2siLCJpYXQiOjE1ODczNjY5OTh9.lV2aXWMdPTsftSZAFq7QbbpwR9bPAuRfkYyMmA8w6yE';
92                if (this.config.netType !== 'web') { //生产外网
93                    this.config.url = 'https://pss-collect.pingan.com.cn/bdc/behaviordata';
94                } else { //生产内网
95                    this.config.url = 'https://pss-esales-collect-bdc-sender-gl-prd-web-padis.paic.com.cn/bdc/behaviordata';
96                }
97            }
98            if (this.config.useToken) {
99                this.config.url = this.config.url.replace('behaviordata', 'v2/behaviordata');
100            }
101        },
102        /**
103         * 设置埋点
104         */
105        setEventTrack: function (data) {
106            if (!data) return false;
107            if (Object.prototype.toString.call(data) === '[object Object]') {
108                this.setConfig(data);
109            } else {
110                this.config.eventId = data;
111            }
112            var track = this._getParams('event');
113            this._submit(track, 'event');
114        },
115        setPageTrack: function (data) {
116            // if (!data) return false;
117            if (Object.prototype.toString.call(data) === '[object Object]') {
118                this.setConfig(data);
119            } else {
120                var currDate = new Date();
121                if (this.config.pageNo) {
122                    this.config.pageEndTime = currDate; //当前时间
123                    this.config.pageDuration = this.config.pageEndTime.getTime() - this.config.pageStartTime.getTime();
124                    this._submitPageTrack();
125                }
126                this.config.pageStartTime = currDate; //重置当前页面开始时间
127                var calcDate = this._utils._fmtDate(currDate, "yyyy-MM-dd hh:mm:ss");
128                this.config.pageNo = data;
129                
130            }
131        },
132        //批量提交埋点
133        submitTrace: function (self) {
134            var storeName = 'tracklog' + (this.config.userId || '') + (this.config.sourceSystem || '');
135            var traceList = self._utils._getStore(storeName);
136            if(!traceList || !traceList.length) return;
137            // var token = self._utils._setJwtToken(this.config.isTest); //鉴权秘钥
138            var token = '';
139            if (this.config.useToken) {
140                token = this.config.token;
141            }
142            var currDate = this._utils._fmtDate(new Date(), "yyyy-MM-dd hh:mm:ss"); //当前时间
143            var clickList = [];
144            var pageList = [];
145            for (var i=0,l=traceList.length;i<l;i++) {
146                if (traceList[i].uploadTime) {
147                    traceList[i].uploadTime = currDate;
148                }
149                if (traceList[i].eventType === 'page') {
150                    pageList.push(traceList[i]);
151                } else if (traceList[i].eventType === 'click') {
152                    clickList.push(traceList[i]);
153                }
154            }
155            var param = {
156                dataName: '',
157                token: token,
158                dataContent: {
159                    basic: {
160                        uploadTime: currDate,
161                        total: 0,
162                        netType: self.config.netType,
163                    },
164                    clicks: [],
165                    pages: []
166                }
167            }
168            if (clickList.length) {
169                param.dataName = 'bas-event-track-click';
170                param.dataContent.basic.total = clickList.length;
171                param.dataContent.clicks = clickList;
172                param.dataContent.pages = [];
173                self.ajaxRequest(param, storeName);
174            }
175            if (pageList.length) {
176                param.dataName = 'bas-event-track-page';
177                param.dataContent.basic.total = pageList.length;
178                param.dataContent.clicks = [];
179                param.dataContent.pages = pageList;
180                self.ajaxRequest(param, storeName);
181            }
182        },
183        ajaxRequest: function (param, storeName) {
184            var xmlhttp;
185            if (window.XMLHttpRequest) {
186                xmlhttp = new XMLHttpRequest();
187            } else {
188                xmlhttp = new ActiveXObject;
189            }
190            xmlhttp.open('PUT', self.config.url, true);
191            xmlhttp.setRequestHeader('Accept', 'application/json, text/javascript, */*');
192            xmlhttp.setRequestHeader('Content-type', 'application/json;charset=utf-8;');
193            xmlhttp.withCredentials = true; //支持跨域
194            xmlhttp.send(JSON.stringify(param));
195            xmlhttp.onreadystatechange = function () {
196                if (xmlhttp.readyState == 4) {
197                    if (xmlhttp.status == 200) {
198                        localStorage.removeItem(storeName);
199                    }
200                }
201            }
202        },
203        routerBeforeEach: function (to, from) {
204            var self = this;
205        },
206        _submitPageTrack: function () {
207            var track = this._getParams('page');
208            this._submit(track, 'page');
209        },
210        /**
211         * 参数
212         */
213        _getParams: function (type) {
214            var currDate = this._utils._fmtDate(new Date(), "yyyy-MM-dd hh:mm:ss"); //当前时间
215            var explorerInfo = this._utils._getExplorerInfo(); //浏览器版本信息
216            var params = {};
217            var storeName = type == 'event' ? 'censusClick' : 'censusPage';
218            this._dealCalc(currDate, false, storeName);
219            var pending = {};
220            if (type == 'event') {
221                pending = this._utils._getStore('censusClick') || {};
222                //记录时间
223                params = {
224                    browserType: explorerInfo.type + '-' + explorerInfo.version, //浏览器+版本
225                    userId: this.config.userId, //用户ID
226                    eventId: window.encodeURIComponent(this.config.eventId),
227                    operationTime: currDate, //事件发生时间
228                    uploadTime: currDate, //上传(提交)时间
229                    userAgent: window.navigator.userAgent, //浏览器UA
230                    sourceSystem: this.config.sourceSystem, //所属子系统标识
231                    systemVersion: this.config.systemVersion, //前端应用版本号
232                    eventDuration: pending.eventDuration || '', //距离上一事件的间隔时间
233                    sessionId: this.config.sessionId, //浏览器会话的sessionId
234                    sequence: pending.sequence, //事件顺序ID
235                    url: window.location.href, //请求url
236                    referer: document.referrer || '', //浏览器的referer属性
237                    parameters: this.config.parameters, //扩展字段
238                    eventType: 'click', //事件类型
239                }
240            } else { //page
241                var parameters = this.config.pageParameters;
242                pending = this._utils._getStore('censusPage') || {};
243                if (this.config.pageTrack) {
244                    for (var prop in this.config.pageTrack) {
245                        if (window.location.href.indexOf(prop) != -1) { //暂时按indexOf处理 后续提供自定义规则
246                            this.config.pageNo = this.config.pageNo || this.config.pageTrack[prop].pageNo;
247                            parameters = this.config.pageTrack[prop].parameters;
248                            break;
249                        }
250                    }
251                } else if (this.config.pageTrackVue) {
252                    var href = location.href;
253                    var module = href.split(".html")[0].split("/").pop(),
254                        hash = href.split("#/")[1].split("?")[0];
255                    if (this.config.pageTrackVue[module] && this.config.pageTrackVue[module][hash]) {
256                        this.config.pageNo = this.config.pageNo || this.config.pageTrackVue[module][hash].pageNo;
257                        parameters = this.config.pageTrackVue[module][hash].parameters;
258                    }
259                }
260                if (!this.config.pageNo) {
261                    console.log('页面没有埋点');
262                    return;
263                }
264                params = {
265                    browserType: explorerInfo.type + '-' + explorerInfo.version, //浏览器+版本
266                    userId: this.config.userId, //用户ID
267                    pageNo: window.encodeURIComponent(this.config.pageNo), //页面埋点编号
268                    pageStartTime: this._utils._fmtDate(this.config.pageStartTime, "yyyy-MM-dd hh:mm:ss"), //进入页面时间
269                    pageEndTime: this._utils._fmtDate(this.config.pageEndTime, "yyyy-MM-dd hh:mm:ss"), //离开页面时间
270                    pageDuration: this.config.pageDuration || '', //停留页面时间
271                    userAgent: window.navigator.userAgent, //浏览器UA
272                    sourceSystem: this.config.sourceSystem, //所属子系统标识
273                    systemVersion: this.config.systemVersion, //前端应用版本号
274                    sessionId: this.config.sessionId, //浏览器会话的sessionId
275                    sequence: pending.sequence, //事件顺序ID
276                    url: this.config.pageHref || window.location.href, //请求url
277                    parameters: parameters, //扩展字段
278                    eventType: 'page', //事件类型
279                }
280            }
281            //加密参数
282            if (this.config.encryptFields.length) {
283                for (var i = 0, len = this.config.encryptFields.length; i < len; i++) {
284                    var field = this.config.encryptFields[i];
285                    if (this.config.hasOwnProperty(field)) {
286                        params[field] = this._utils._encrypt.call(this, params[field]);
287                    }
288                }
289            }
290            return params;
291        },
292        /**
293         * 记录事件埋点时间
294         */
295        _dealCalc: function (currDate, init, type) {
296            var storeName = type ? type : 'censusClick';
297            var pendingData = this._utils._getStore(storeName) || {};
298            var currSequence = pendingData.sequence;
299            currSequence ? currSequence++ : 1
300            var lastTime = pendingData.now ? pendingData.now.replace(/-/g, '/') : ''; //兼容ie的new Date('yyyy/mm/dd hh:mm:ss')
301            var pending = {
302                now: currDate,
303                eventDuration: lastTime ? new Date().getTime() - new Date(lastTime).getTime() : '',
304                sequence: currSequence || 1,
305            }
306            if (init) {
307                pending = {
308                    now: currDate,
309                    eventDuration: '',
310                    sequence: 0,
311                }
312            }
313            this._utils._setStore(storeName, pending);
314        },
315        /**
316         * 提交埋点
317         */
318        _submit: function (data, type) {
319            if(!data || !data.userId){//没有数据不缓存或提交
320                return;
321            }
322            if (this.config.useCache) { //设置缓存
323                this._saveCache(data);
324                return;
325            }
326            var self = this;
327            this._utils._baseRequest.call(this, data, function () {
328                self._resetPageData();
329            });
330        },
331        //重置页面埋点数据
332        _resetPageData: function(){
333            if (this.config._hashChangeTime) {
334                //hash改变是改变startTime
335                this.config.pageStartTime = this.config._hashChangeTime;
336                //清空提交的pageNo,eventId
337                this.config.pageNo = '';
338                this.config.pageParameters = '';
339            }
340            this.config.eventId = '';
341            this.config.parameters = '';
342            this.config.pageHref = '';
343        },
344        //缓存数据
345        _saveCache: function (data) {
346            var storeName = 'tracklog' + (this.config.userId || '') + (this.config.sourceSystem || '');
347            var tracklog = this._utils._getStore(storeName) ? this._utils._getStore(storeName) : [];
348            tracklog.push(data);
349            this._resetPageData();
350            this._utils._setStore(storeName, tracklog);
351        },
352        _initEvents: function () {
353            // this._DOMContentLoaded();
354            this._beforeunload();
355            this._hashchange();
356            //使用缓存,则定时批量提交埋点
357            var self = this;
358            if (this.config.useCache) {
359                window.setInterval(function () {
360                    self.submitTrace(self);
361                }, 10000);
362            }
363        },
364        _beforeunload: function () {
365            var self = this;
366            this._utils._addEvents(_global, 'beforeunload', function () {
367                self.config.pageEndTime = new Date(); //当前时间
368                self.config.pageDuration = self.config.pageEndTime.getTime() - self.config.pageStartTime.getTime();
369                self._submitPageTrack();
370            });
371        },
372        _hashchange: function () {
373            var self = this;
374            this._utils._addEvents(_global, 'hashchange', function () {
375                self.config.pageEndTime = new Date(); //当前时间
376                self.config.pageDuration = self.config.pageEndTime.getTime() - self.config.pageStartTime.getTime();
377                self.config._hashChangeTime = new Date();
378                self._submitPageTrack();
379            });
380        },
381        _DOMContentLoaded: function () {
382            var self = this;
383            this._utils._addEvents(_global, 'DOMContentLoaded', function () {
384                self.config.pageStartTime = new Date();
385            });
386        },
387        /**
388         * _utils
389         */
390        _utils: {
391            _extend: function (o, n, override) {
392                for (var key in n) {
393                    if (n.hasOwnProperty(key) && (!o.hasOwnProperty(key) || override)) {
394                        o[key] = n[key];
395                    }
396                }
397                return o;
398            },
399            /**
400             * encrypt加密
401             */
402            _encrypt: function (data) {
403                if (!this.config.publicKey) {
404                    console.log('参数未加密,加密请设置publicKey');
405                    return data;
406                }
407                var encrypt = new JSEncrypt();
408                encrypt.setPublicKey(this.config.publicKey);
409                return encrypt.encrypt(data);
410            },
411            _setStore: function (name, content, type) {
412                if (!name) return;
413                if (type === 'session') {
414                    window.sessionStorage.setItem(name, window.JSON.stringify(content));
415                } else {
416                    window.localStorage.setItem(name, window.JSON.stringify(content));
417                }
418            },
419            _getStore: function (name, type) {
420                if (!name) return;
421                var storage = '';
422                if (type === 'session') {
423                    storage = window.sessionStorage.getItem(name);
424                } else {
425                    storage = window.localStorage.getItem(name);
426                }
427                return storage ? window.JSON.parse(storage) : '';
428            },
429            _fmtDate: function (date, fmt) {
430                var o = {
431                    'M+': date.getMonth() + 1, // 月份
432                    'd+': date.getDate(), // 日
433                    'h+': date.getHours(), // 小时
434                    'm+': date.getMinutes(), // 分
435                    's+': date.getSeconds(), // 秒
436                    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
437                    S: date.getMilliseconds(), // 毫秒
438                };
439                if (/(y+)/.test(fmt)) {
440                    var dateValue = date.getFullYear().toString();
441                    fmt = fmt.replace(RegExp.$1, dateValue.substr(4 - RegExp.$1.length));
442                }
443                for (var k in o) {
444                    var keyText = '(' + k + ')';
445                    if (new RegExp(keyText).test(fmt)) {
446                        var data1 = '' + o[k];
447                        var data2 = '00' + o[k];
448                        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (data2.substr(data1.length)));
449                    }
450                }
451                return fmt;
452            },
453            /**
454             * 发送请求
455             */
456            _baseRequest: function (params, callback) {
457                var img = document.createElement('img');
458                // var token = this._utils._setJwtToken(this.config.isTest);
459                var token = '';
460                if (this.config.useToken) {
461                    token = this.config.token;
462                }
463                img.onload = function () {
464                    callback && typeof callback == 'function' && callback();
465                }
466                var clickList = [];
467                var pageList = [];
468                var dataName = '';
469                if (params.eventType === 'page') {
470                    pageList.push(params);
471                    dataName = 'bas-event-track-page';
472                } else if (params.eventType === 'click') {
473                    clickList.push(params);
474                    dataName = 'bas-event-track-click';
475                }
476                var param = {
477                    basic: {
478                        uploadTime: params.uploadTime || params.pageEndTime,
479                        total: 1,
480                        netType: this.config.netType,
481                    },
482                    clicks: clickList,
483                    pages: pageList
484                }
485                var imgUrl = this.config.url + '?dataName='+ dataName +'&token=' + token + '&dataContent=' + encodeURIComponent(this._utils._formatParams(param));
486                // var imgUrl = this.config.url + '?dataName='+ dataName + '&dataContent=' + encodeURIComponent(this._utils._formatParams(param));
487                var host = window.location.host;
488                //避免本地环境调用生产接口
489                if ((host.indexOf('0.0.0.0') !== -1 || host.indexOf('localhost') !== -1) && !this.config.isTest) {
490                    console.log({imgUrl: imgUrl})
491                    callback && typeof callback == 'function' && callback();
492                    return false;
493                }
494                img.src = imgUrl;
495                callback && typeof callback == 'function' && callback();
496            },
497            _formatParams: function (data) {
498                // var arr = [];
499                // for (var name in data) {
500                //     if (Object.prototype.toString.call(data[name]) === '[object Object]') {
501                //         arr.push(name + '=' + window.encodeURIComponent(window.JSON.stringify(data[name])));
502                //     } else {
503                //         arr.push(name + '=' + window.encodeURIComponent(data[name]));
504                //     }
505                // }
506                // return arr.join("&");
507                var dataStr = '';
508                if (Object.prototype.toString.call(data) === '[object Object]') {
509                    dataStr = window.JSON.stringify(data);
510                } else {
511                    dataStr = data;
512                }
513                return dataStr;
514            },
515            _addEvents: function (ele, evt, fn) {
516                if (document.addEventListener) {
517                    ele.addEventListener(evt, function () {
518                        fn(event, ele)
519                    }, false);
520                } else if (document.attachEvent) {
521                    ele.attachEvent('on' + evt, function () {
522                        fn(event, ele)
523                    });
524                } else {
525                    ele['on' + evt] = function () {
526                        fn(event, ele)
527                    };
528                }
529            },
530            _getExplorerInfo: function () {
531                var userAgent = window.navigator.userAgent;
532                var explorer = window.navigator.userAgent.toLowerCase();
533                var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
534                var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge 
535                var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; //判断是否ie11
536                if (isEdge) {
537                    return {
538                        type: 'IE',
539                        version: 'Edge'
540                    };
541                } else if (isIE11) {
542                    return {
543                        type: 'IE',
544                        version: '11'
545                    };
546                } else if (explorer.indexOf('msie') >= 0) {
547                    var ver = explorer.match(/msie ([\d.]+)/)[1];
548                    return {
549                        type: 'IE',
550                        version: ver
551                    };
552                } else if (explorer.indexOf('firefox') >= 0) {
553                    var ver = explorer.match(/firefox\/([\d.]+)/)[1];
554                    return {
555                        type: 'Firefox',
556                        version: ver
557                    };
558                } else if (explorer.indexOf('chrome') >= 0) {
559                    var ver = explorer.match(/chrome\/([\d.]+)/)[1];
560                    return {
561                        type: 'Chrome',
562                        version: ver
563                    };
564                } else if (explorer.indexOf('opera') >= 0) {
565                    var ver = explorer.match(/opera.([\d.]+)/)[1];
566                    return {
567                        type: 'Opera',
568                        version: ver
569                    };
570                } else if (explorer.indexOf('Safari') >= 0) {
571                    var ver = explorer.match(/version\/([\d.]+)/)[1];
572                    return {
573                        type: 'Safari',
574                        version: ver
575                    };
576                } else {
577                    return {
578                        type: 'unknown',
579                        version: '0.0.0'
580                    };
581                }
582            },
583            /**
584             * 生成jwt
585             */
586            _setJwtToken: function (isTest) {
587                var keyWord = '21e2e4966ac640a8bcba8fd1016ccc92';
588                if (!isTest) {
589                    keyWord = 'c27c8ae4f4a24071bd237a0ac3a5e3cb';
590                }
591                var head = {
592                        'alg': 'HS256',
593                        'typ': 'JWT'
594                    },
595                    payload = {
596                        'sub': 'bas-event-track',
597                        'iat': new Date().getTime()
598                    };
599                var headBase64 = this._base64Encode(JSON.stringify(head)),
600                    payloadBase64 = this._base64Encode(JSON.stringify(payload)),
601                    signature = CryptoJS.HmacSHA256(
602                        headBase64 + "." + payloadBase64,
603                        keyWord
604                    );
605                var token = headBase64+'.'+payloadBase64+'.'+signature;
606                return token;
607            },
608            /**
609             * 转换base64
610             */
611            _base64Encode: function (input) {  
612                var output = "";  
613                var chr1, chr2, chr3, enc1, enc2, enc3, enc4;  
614                var i = 0;  
615                var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
615+/=";
616                input = this._utf8Encode(input);  
617                while (i < input.length) {  
618                    chr1 = input.charCodeAt(i++);  
619                    chr2 = input.charCodeAt(i++);  
620                    chr3 = input.charCodeAt(i++);  
621                    enc1 = chr1 >> 2;  
622                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);  
623                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);  
624                    enc4 = chr3 & 63;  
625                    if (isNaN(chr2)) {  
626                        enc3 = enc4 = 64;  
627                    } else if (isNaN(chr3)) {  
628                        enc4 = 64;  
629                    }  
630                    output = output +  
631                    _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +  
632                    _keyStr.charAt(enc3) + _keyStr.charAt(enc4);  
633                }  
634                return output;  
635            },
636            /**
637             * 转换base64
638             */
639            _utf8Encode: function (string) {  
640                string = string.replace(/\r\n/g,"\n");  
641                var utftext = "";  
642                for (var n = 0; n < string.length; n++) {  
643                    var c = string.charCodeAt(n);  
644                    if (c < 128) {  
645                        utftext += String.fromCharCode(c);  
646                    } else if((c > 127) && (c < 2048)) {  
647                        utftext += String.fromCharCode((c >> 6) | 192);  
648                        utftext += String.fromCharCode((c & 63) | 128);  
649                    } else {  
650                        utftext += String.fromCharCode((c >> 12) | 224);  
651                        utftext += String.fromCharCode(((c >> 6) & 63) | 128);  
652                        utftext += String.fromCharCode((c & 63) | 128);  
653                    }
654                }  
655                return utftext;  
656            },
657            /**
658             * 动态引入
659             */
660            _createScript: function (value) {
661                var script = document.createElement("script");
662                script.setAttribute("type", "text/javascript");
663                script.setAttribute("src", value);
664                document.body.appendChild(script);
665            },
666            /**
667             * 生成随机码
668             */
669            _randomSessionId: function () {
670                var len = 32, radix = 64;
671                var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
672                var uuid = [], i;
673                radix = radix || chars.length;
674                if (len) {
675                    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
676                } else {
677                    var r;
678                    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
679                    uuid[14] = '4';
680                    for (i = 0; i < 36; i++) {
681                        if (!uuid[i]) {
682                            r = 0 | Math.random()*16;
683                            uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
684                        }
685                    }
686                }
687                return uuid.join('');
688            },
689            _getCookie: function (key) {
690                var arr,
691                    reg = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
692                if (arr = document.cookie.match(reg)) {
693                    return (arr[2]);
694                } else {
695                    return '';
696                }
697            }
698        }
699    }
700    // 设置全局
701    _global = (function () {
702        return this || (0, eval)('this');
703    }());
704    if (typeof module !== "undefined" && module.exports) {
705        module.exports = EventTrack;
706    } else if (typeof define === "function" && (define.amd || define.cmd)) {
707        define(function () {
708            return EventTrack;
709        });
710    } else {
711        !('EventTrack' in _global) && (_global.EventTrack = EventTrack);
712    }
713}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.