hina-cloud-js-sdk 3.1.6 → 3.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/.gitlab-ci.yml +2 -6
  2. package/build/hina.cjs.min.js +1 -0
  3. package/build/hina.esm.min.js +1 -0
  4. package/build/hina.min.js +1 -4
  5. package/build/hotAnalyse.min.js +1 -1
  6. package/package.json +2 -7
  7. package/packages/core/dist/index.cjs.js +64 -0
  8. package/packages/core/dist/index.cjs.js.map +1 -0
  9. package/packages/core/dist/index.d.ts +45 -0
  10. package/packages/core/dist/index.esm.js +62 -0
  11. package/packages/core/dist/index.esm.js.map +1 -0
  12. package/packages/core/dist/index.global.js +1199 -0
  13. package/packages/core/dist/index.global.js.map +1 -0
  14. package/packages/core/dist/index.js +1200 -0
  15. package/packages/core/dist/index.js.map +1 -0
  16. package/packages/monitor/dist/index.cjs.js +150 -0
  17. package/packages/monitor/dist/index.cjs.js.map +1 -0
  18. package/packages/monitor/dist/index.d.ts +35 -0
  19. package/packages/monitor/dist/index.esm.js +145 -0
  20. package/packages/monitor/dist/index.esm.js.map +1 -0
  21. package/packages/monitor/dist/index.global.js +1343 -0
  22. package/packages/monitor/dist/index.global.js.map +1 -0
  23. package/packages/monitor/dist/index.js +1344 -0
  24. package/packages/monitor/dist/index.js.map +1 -0
  25. package/packages/track/dist/index.cjs.js +1930 -0
  26. package/packages/track/dist/index.cjs.js.map +1 -0
  27. package/packages/track/dist/index.d.ts +212 -0
  28. package/packages/track/dist/index.esm.js +1925 -0
  29. package/packages/track/dist/index.esm.js.map +1 -0
  30. package/packages/track/dist/index.global.js +4259 -0
  31. package/packages/track/dist/index.global.js.map +1 -0
  32. package/packages/track/dist/index.js +4260 -0
  33. package/packages/track/dist/index.js.map +1 -0
  34. package/packages/types/dist/index.d.ts +603 -0
  35. package/packages/types/dist/index.esm.js +25 -0
  36. package/packages/types/dist/index.esm.js.map +1 -0
  37. package/packages/utils/dist/index.cjs.js +1535 -0
  38. package/packages/utils/dist/index.cjs.js.map +1 -0
  39. package/packages/utils/dist/index.d.ts +394 -0
  40. package/packages/utils/dist/index.esm.js +1465 -0
  41. package/packages/utils/dist/index.esm.js.map +1 -0
  42. package/packages/utils/dist/index.global.js +2507 -0
  43. package/packages/utils/dist/index.global.js.map +1 -0
  44. package/packages/utils/dist/index.js +2508 -0
  45. package/packages/utils/dist/index.js.map +1 -0
@@ -0,0 +1,4260 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.hinaDataStatistic = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
22
+
23
+ var extendStatics = function(d, b) {
24
+ extendStatics = Object.setPrototypeOf ||
25
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
26
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
27
+ return extendStatics(d, b);
28
+ };
29
+
30
+ function __extends(d, b) {
31
+ if (typeof b !== "function" && b !== null)
32
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
33
+ extendStatics(d, b);
34
+ function __() { this.constructor = d; }
35
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
36
+ }
37
+
38
+ var __assign = function() {
39
+ __assign = Object.assign || function __assign(t) {
40
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
41
+ s = arguments[i];
42
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
43
+ }
44
+ return t;
45
+ };
46
+ return __assign.apply(this, arguments);
47
+ };
48
+
49
+ function __values(o) {
50
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
51
+ if (m) return m.call(o);
52
+ if (o && typeof o.length === "number") return {
53
+ next: function () {
54
+ if (o && i >= o.length) o = void 0;
55
+ return { value: o && o[i++], done: !o };
56
+ }
57
+ };
58
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
59
+ }
60
+
61
+ function __read(o, n) {
62
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
63
+ if (!m) return o;
64
+ var i = m.call(o), r, ar = [], e;
65
+ try {
66
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
67
+ }
68
+ catch (error) { e = { error: error }; }
69
+ finally {
70
+ try {
71
+ if (r && !r.done && (m = i["return"])) m.call(i);
72
+ }
73
+ finally { if (e) throw e.error; }
74
+ }
75
+ return ar;
76
+ }
77
+
78
+ function __spreadArray(to, from, pack) {
79
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
80
+ if (ar || !(i in from)) {
81
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
82
+ ar[i] = from[i];
83
+ }
84
+ }
85
+ return to.concat(ar || Array.prototype.slice.call(from));
86
+ }
87
+
88
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
89
+ var e = new Error(message);
90
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
91
+ };
92
+
93
+ var ConsoleTypes;
94
+ (function (ConsoleTypes) {
95
+ ConsoleTypes["LOG"] = "log";
96
+ ConsoleTypes["INFO"] = "info";
97
+ ConsoleTypes["WARN"] = "warn";
98
+ ConsoleTypes["ERROR"] = "error";
99
+ ConsoleTypes["ASSERT"] = "assert";
100
+ })(ConsoleTypes || (ConsoleTypes = {}));
101
+ var ReportType;
102
+ (function (ReportType) {
103
+ ReportType["BEACON"] = "beacon";
104
+ ReportType["IMAGE"] = "image";
105
+ ReportType["AJAX"] = "ajax";
106
+ })(ReportType || (ReportType = {}));
107
+
108
+ var PluginBase = /** @class */ (function () {
109
+ function PluginBase(options, context) {
110
+ this.options = options;
111
+ this.context = context;
112
+ }
113
+ return PluginBase;
114
+ }());
115
+
116
+ var MAX_REFERRER_STRING_LENGTH = 2000;
117
+ var MAX_STRING_LENGTH = 1024 * 4;
118
+ var PV_LIB_VERSION = '4.0.0';
119
+ var COOKIE_TEST_NAME = 'hinasdk_domain_test';
120
+ var utmTypes = [
121
+ 'utm_source',
122
+ 'utm_medium',
123
+ 'utm_campaign',
124
+ 'utm_content',
125
+ 'utm_term'
126
+ ];
127
+ var searchTypes = [
128
+ 'www.baidu.',
129
+ 'm.baidu.',
130
+ 'm.sm.cn',
131
+ 'so.com',
132
+ 'sogou.com',
133
+ 'youdao.com',
134
+ 'google.',
135
+ 'yahoo.com/',
136
+ 'bing.com/',
137
+ 'ask.com/'
138
+ ];
139
+ var socialTypes = [
140
+ 'weibo.com',
141
+ 'renren.com',
142
+ 'kaixin001.com',
143
+ 'douban.com',
144
+ 'qzone.qq.com',
145
+ 'zhihu.com',
146
+ 'tieba.baidu.com',
147
+ 'weixin.qq.com'
148
+ ];
149
+ var searchKeywords = {
150
+ baidu: ['wd', 'word', 'kw', 'keyword'],
151
+ google: 'q',
152
+ bing: 'q',
153
+ yahoo: 'p',
154
+ sogou: ['query', 'keyword'],
155
+ so: 'q',
156
+ sm: 'q'
157
+ };
158
+
159
+ function isObject(val) {
160
+ return Object.prototype.toString.call(val) === '[object Object]';
161
+ }
162
+ function isValid(val) {
163
+ return val !== null && val !== undefined;
164
+ }
165
+ function isArray(val) {
166
+ return Array.isArray(val);
167
+ }
168
+ function isFunction(val) {
169
+ return typeof val === 'function';
170
+ }
171
+ function isString(val) {
172
+ return typeof val === 'string';
173
+ }
174
+ function isNumber(val) {
175
+ return typeof val === 'number';
176
+ }
177
+ function isBoolean(val) {
178
+ return typeof val === 'boolean';
179
+ }
180
+ function noop() { }
181
+ function isJSONString(val) {
182
+ try {
183
+ JSON.parse(val);
184
+ }
185
+ catch (e) {
186
+ return false;
187
+ }
188
+ return true;
189
+ }
190
+ function safeJSONParse(val) {
191
+ try {
192
+ return JSON.parse(val);
193
+ }
194
+ catch (e) { }
195
+ return val;
196
+ }
197
+ function isEmptyObject(obj) {
198
+ return Object.keys(obj).length === 0;
199
+ }
200
+ function nowStamp() {
201
+ if (Date.now && isFunction(Date.now)) {
202
+ return Date.now();
203
+ }
204
+ return new Date().getTime();
205
+ }
206
+ function merge() {
207
+ var args = [];
208
+ for (var _i = 0; _i < arguments.length; _i++) {
209
+ args[_i] = arguments[_i];
210
+ }
211
+ var result = Object.create(null);
212
+ args.forEach(function (obj) {
213
+ if (obj) {
214
+ Object.keys(obj).forEach(function (key) {
215
+ var val = obj[key];
216
+ if (isObject(val)) {
217
+ if (isObject(result[key])) {
218
+ result[key] = merge(result[key], val);
219
+ }
220
+ else {
221
+ result[key] = merge(val);
222
+ }
223
+ }
224
+ else {
225
+ result[key] = val;
226
+ }
227
+ });
228
+ }
229
+ });
230
+ return result;
231
+ }
232
+ function stripEmptyProperties(obj) {
233
+ return Object.keys(obj).reduce(function (acc, key) {
234
+ if (isValid(obj[key]) && obj[key] !== '') {
235
+ acc[key] = obj[key];
236
+ }
237
+ return acc;
238
+ }, {});
239
+ }
240
+ /**
241
+ * 返回URL对象
242
+ * @param url
243
+ */
244
+ function getURL(url) {
245
+ var urlObj = {};
246
+ try {
247
+ urlObj = new URL(url);
248
+ }
249
+ catch (e) { }
250
+ return urlObj;
251
+ }
252
+ /**
253
+ * 获取URL上的search参数
254
+ * @param queryString
255
+ */
256
+ function getURLSearchParams(queryString) {
257
+ queryString = queryString || '';
258
+ var args = {};
259
+ var searchParams = new URLSearchParams(queryString);
260
+ searchParams.forEach(function (value, key) {
261
+ args[key] = value;
262
+ });
263
+ return args;
264
+ }
265
+ function formatDecimal(num, decimal) {
266
+ if (!num) {
267
+ return num;
268
+ }
269
+ var str = num.toString();
270
+ var index = str.indexOf('.');
271
+ if (index !== -1) {
272
+ str = str.substring(0, index + decimal + 1);
273
+ }
274
+ else {
275
+ str = str.substring(0);
276
+ }
277
+ return parseFloat(str);
278
+ }
279
+ /**
280
+ * 获取cookie顶级域名
281
+ * @param hostname
282
+ */
283
+ function getCookieTopLevelDomain(hostname) {
284
+ hostname = hostname || window.location.hostname;
285
+ if (!/^[a-zA-Z0-9\u4e00-\u9fa5\-\\.]+$/.exec(hostname)) {
286
+ hostname = '';
287
+ }
288
+ var splitResult = hostname.split('.');
289
+ if (splitResult.length >= 2 && !/^(\d+\.)+\d+$/.test(hostname)) {
290
+ var domainStr = ".".concat(splitResult.splice(splitResult.length - 1, 1));
291
+ while (splitResult.length > 0) {
292
+ domainStr = ".".concat(splitResult.splice(splitResult.length - 1, 1)).concat(domainStr);
293
+ document.cookie = "".concat(COOKIE_TEST_NAME, "=true; path=/; domain=").concat(domainStr);
294
+ if (document.cookie.indexOf("".concat(COOKIE_TEST_NAME, "=true")) !== -1) {
295
+ document.cookie = "".concat(COOKIE_TEST_NAME, "=true; path=/; domain=").concat(domainStr, "; max-age=0");
296
+ return domainStr;
297
+ }
298
+ }
299
+ }
300
+ return '';
301
+ }
302
+ /**
303
+ * 获取当前页面的domain
304
+ * 注意这里的domain,并不是普通的window.location.hostname值,而是拥有相同子域名的域名,因为浏览器的cookie是二级域名共享的
305
+ */
306
+ function getCurrentDomain() {
307
+ var cookieDomain = getCookieTopLevelDomain();
308
+ if (cookieDomain === '') {
309
+ return 'url解析失败';
310
+ }
311
+ return cookieDomain;
312
+ }
313
+ /**
314
+ * 获取当前页面的referrer
315
+ */
316
+ function getReferrer(value) {
317
+ var referrer = value || document.referrer;
318
+ if (typeof referrer !== 'string') {
319
+ return "referrer exception".concat(String(referrer));
320
+ }
321
+ if (referrer.startsWith('https://www.baidu.com/')) {
322
+ referrer = referrer.split('?')[0];
323
+ }
324
+ referrer = referrer.slice(0, MAX_REFERRER_STRING_LENGTH);
325
+ return typeof referrer === 'string' ? referrer : '';
326
+ }
327
+ /**
328
+ * 获取hostname
329
+ * @param url
330
+ * @param defaultValue
331
+ */
332
+ function getHostname(url, defaultValue) {
333
+ if (!defaultValue || typeof defaultValue !== 'string') {
334
+ defaultValue = 'hostname解析异常';
335
+ }
336
+ if (!url) {
337
+ return defaultValue;
338
+ }
339
+ var hostname = getURL(url).hostname || '';
340
+ return hostname || defaultValue;
341
+ }
342
+ /**
343
+ * 此函数有两个作用
344
+ * 1:referrer为空时,直接返回true
345
+ * 2:referrer不为空时,判断是否是外链流量 document.referrer对应的hostname是否和当前URL的hostname是否相同
346
+ * @param referrer
347
+ */
348
+ function isReferralTraffic(referrer) {
349
+ referrer = referrer || document.referrer;
350
+ if (referrer === '') {
351
+ return true;
352
+ }
353
+ return (getCookieTopLevelDomain(getHostname(referrer)) !== getCookieTopLevelDomain());
354
+ }
355
+ /**
356
+ * 获取浏览器scrollTop
357
+ */
358
+ function getScrollTop() {
359
+ return document.documentElement.scrollTop || document.body.scrollTop || 0;
360
+ }
361
+ /**
362
+ * 获取浏览器scrollLeft
363
+ */
364
+ function getScrollLeft() {
365
+ return document.documentElement.scrollLeft || document.body.scrollLeft || 0;
366
+ }
367
+ /**
368
+ * 获取浏览器可视高度
369
+ */
370
+ function getScreenHeight() {
371
+ return (window.innerHeight ||
372
+ document.documentElement.clientHeight ||
373
+ document.body.clientHeight ||
374
+ 0);
375
+ }
376
+ /**
377
+ * 获取浏览器可视宽度
378
+ */
379
+ function getScreenWidth() {
380
+ return (window.innerWidth ||
381
+ document.documentElement.clientWidth ||
382
+ document.body.clientWidth ||
383
+ 0);
384
+ }
385
+ /**
386
+ * 获取浏览器网络类型
387
+ */
388
+ function networkType() {
389
+ if (navigator.connection === undefined)
390
+ return 'unknown';
391
+ var connection = navigator.connection;
392
+ if (connection.effectiveType) {
393
+ return connection.effectiveType;
394
+ }
395
+ if (connection.type) {
396
+ return connection.type;
397
+ }
398
+ return '取值异常';
399
+ }
400
+ /**
401
+ * 生成随机数
402
+ */
403
+ function getRandom() {
404
+ var date = new Date();
405
+ var seed = date.getTime();
406
+ var num = Math.floor(Math.random() * 1000000);
407
+ return "".concat(seed, "_").concat(num);
408
+ }
409
+ var ListenPageState = /** @class */ (function () {
410
+ function ListenPageState(payload) {
411
+ this.visibleHandler = function () { };
412
+ this.hiddenHandler = function () { };
413
+ var visible = payload.visible, hidden = payload.hidden;
414
+ if (isFunction(visible)) {
415
+ this.visibleHandler = visible;
416
+ }
417
+ if (isFunction(hidden)) {
418
+ this.hiddenHandler = hidden;
419
+ }
420
+ this.init();
421
+ }
422
+ ListenPageState.prototype.isSupport = function () {
423
+ return typeof document.hidden !== 'undefined';
424
+ };
425
+ ListenPageState.prototype.init = function () {
426
+ var _this = this;
427
+ if (this.isSupport()) {
428
+ document.addEventListener('visibilitychange', function () {
429
+ if (document.hidden) {
430
+ _this.hiddenHandler();
431
+ }
432
+ else {
433
+ _this.visibleHandler();
434
+ }
435
+ });
436
+ }
437
+ else {
438
+ window.addEventListener('focus', this.visibleHandler);
439
+ window.addEventListener('blur', this.hiddenHandler);
440
+ }
441
+ };
442
+ return ListenPageState;
443
+ }());
444
+ function generatorUUID() {
445
+ var T = function () {
446
+ var d = nowStamp();
447
+ var i = 0;
448
+ while (d === nowStamp()) {
449
+ i++;
450
+ }
451
+ return d.toString(16) + i.toString(16);
452
+ };
453
+ var R = function () {
454
+ return Math.random().toString(16).replace('.', '');
455
+ };
456
+ var UA = function () {
457
+ var ua = navigator.userAgent;
458
+ var i;
459
+ var ch;
460
+ var buffer = [];
461
+ var ret = 0;
462
+ function xor(result, byteArray) {
463
+ var j;
464
+ var tmp = 0;
465
+ for (j = 0; j < byteArray.length; j++) {
466
+ tmp |= buffer[j] << (j * 8);
467
+ }
468
+ return result ^ tmp;
469
+ }
470
+ for (i = 0; i < ua.length; i++) {
471
+ ch = ua.charCodeAt(i);
472
+ buffer.unshift(ch & 0xff);
473
+ if (buffer.length >= 4) {
474
+ ret = xor(ret, buffer);
475
+ buffer = [];
476
+ }
477
+ }
478
+ if (buffer.length > 0) {
479
+ ret = xor(ret, buffer);
480
+ }
481
+ return ret.toString(16);
482
+ };
483
+ var se = String(window.screen.height * window.screen.width);
484
+ if (se && /\d{5,}/.test(se)) {
485
+ // @ts-ignore
486
+ se = se.toString(16);
487
+ }
488
+ else {
489
+ se = String(Math.random() * 31242)
490
+ .replace('.', '')
491
+ .slice(0, 8);
492
+ }
493
+ var val = "".concat(T(), "-").concat(R(), "-").concat(UA(), "-").concat(se, "-").concat(T());
494
+ if (val) {
495
+ return val;
496
+ }
497
+ return (String(Math.random()) +
498
+ String(Math.random()) +
499
+ String(Math.random())).slice(2, 15);
500
+ }
501
+ /**
502
+ * 查找指定url中的参数
503
+ * replace(/[\[]/, "\\[") 将 [ 替换为 \[。
504
+ * replace(/[\]]/, "\\]") 将 ] 替换为 \]。
505
+ * example[123]=>example\[123\]
506
+ * @param url
507
+ * @param key
508
+ */
509
+ function getQueryParam(url, key) {
510
+ key = key.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
511
+ url = decodeURIComponent(url);
512
+ var regex = new RegExp("[\\?&]".concat(key, "=([^&#]*)"));
513
+ var results = regex.exec(url);
514
+ if (results === null ||
515
+ (results && typeof results[1] !== 'string' && results[1].length)) {
516
+ return '';
517
+ }
518
+ return decodeURIComponent(results[1]);
519
+ }
520
+ function base64Encode(str) {
521
+ try {
522
+ return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (e, t) {
523
+ return String.fromCharCode(Number("0x".concat(t)));
524
+ }));
525
+ }
526
+ catch (e) {
527
+ return str;
528
+ }
529
+ }
530
+ function handleDecodeURLComponent(val) {
531
+ var result = val;
532
+ try {
533
+ result = decodeURIComponent(val);
534
+ }
535
+ catch (e) { }
536
+ return result;
537
+ }
538
+ function handleEncodeURLComponent(val) {
539
+ var result = val;
540
+ try {
541
+ result = encodeURIComponent(val);
542
+ }
543
+ catch (e) { }
544
+ return result;
545
+ }
546
+ /**
547
+ * 对原生方法进行重写
548
+ * @param source 需要被重写的对象
549
+ * @param name 重写方法名
550
+ * @param replacement 重写方法
551
+ * @param isForced 是否强制重写(可能原先没有该属性)
552
+ */
553
+ function replaceOld(source, name, replacement, isForced) {
554
+ if (source === undefined)
555
+ return;
556
+ if (name in source || isForced) {
557
+ var original = source[name];
558
+ var wrapped = replacement(original);
559
+ if (isFunction(wrapped)) {
560
+ source[name] = wrapped;
561
+ }
562
+ }
563
+ }
564
+ function supportHistory() {
565
+ return window && !!window.history.pushState && !!window.history.replaceState;
566
+ }
567
+
568
+ /**
569
+ * cookie 操作
570
+ */
571
+ var CookieStorage = /** @class */ (function () {
572
+ function CookieStorage() {
573
+ this.name = 'CookieStorage';
574
+ }
575
+ /**
576
+ * 用于判断是否支持cookie
577
+ * @param testKey
578
+ * @param testValue
579
+ */
580
+ CookieStorage.prototype.isSupport = function (testKey, testValue) {
581
+ var _this = this;
582
+ if (testKey === void 0) { testKey = 'cookie_support_test'; }
583
+ if (testValue === void 0) { testValue = '1'; }
584
+ var test = function () {
585
+ _this.set(testKey, testValue);
586
+ var value = _this.get(testKey);
587
+ if (value !== testValue)
588
+ return false;
589
+ _this.remove(testKey);
590
+ return true;
591
+ };
592
+ return navigator.cookieEnabled && test();
593
+ };
594
+ /**
595
+ * 获取指定的cookie值
596
+ * @param name
597
+ */
598
+ CookieStorage.prototype.get = function (name) {
599
+ var e_1, _a;
600
+ var cookieList = document.cookie.split(';');
601
+ try {
602
+ for (var cookieList_1 = __values(cookieList), cookieList_1_1 = cookieList_1.next(); !cookieList_1_1.done; cookieList_1_1 = cookieList_1.next()) {
603
+ var cookie = cookieList_1_1.value;
604
+ var cookiePair = cookie.split('=');
605
+ if (cookiePair[0].trim() === name) {
606
+ return decodeURIComponent(cookiePair[1]);
607
+ }
608
+ }
609
+ }
610
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
611
+ finally {
612
+ try {
613
+ if (cookieList_1_1 && !cookieList_1_1.done && (_a = cookieList_1.return)) _a.call(cookieList_1);
614
+ }
615
+ finally { if (e_1) throw e_1.error; }
616
+ }
617
+ // 如果没有找到对应的cookie,则返回null
618
+ return null;
619
+ };
620
+ /**
621
+ * 设置cookie
622
+ * @param name cookie名称
623
+ * @param value cookie值
624
+ * @param timeStamp 过期时间戳 单位s
625
+ * @param path 路径
626
+ * @param domain cookie域名
627
+ * @param sameSite 跨域设置
628
+ * @param secure 是否仅通过 HTTPS 协议传输
629
+ */
630
+ CookieStorage.prototype.set = function (name, value, timeStamp, path, domain, sameSite, secure) {
631
+ path = path || '/';
632
+ name = name.trim();
633
+ value = value.trim();
634
+ var cookieStr = "".concat(name, "=").concat(encodeURIComponent(value), "; path=").concat(path, ";");
635
+ timeStamp = isValid(timeStamp) ? timeStamp : 73000;
636
+ // 设置过期时间
637
+ cookieStr += " max-age=".concat(timeStamp, ";");
638
+ // 是否仅通过 HTTPS 协议传输
639
+ if (secure) {
640
+ cookieStr += ' secure;';
641
+ }
642
+ // 设置域名
643
+ if (domain) {
644
+ cookieStr += " domain=".concat(domain, ";");
645
+ }
646
+ // 设置跨域
647
+ if (['Strict', 'Lax', 'None'].includes(sameSite)) {
648
+ cookieStr += " SameSite=".concat(sameSite, ";");
649
+ }
650
+ document.cookie = cookieStr;
651
+ };
652
+ /**
653
+ * 删除指定cookie
654
+ * @param name
655
+ * @param path
656
+ */
657
+ CookieStorage.prototype.remove = function (name, path) {
658
+ if (path === void 0) { path = '/'; }
659
+ this.set(name, '1', 0, path);
660
+ };
661
+ /**
662
+ * 将cookie设置到当前子域名下,用于跨站共享
663
+ * @param name
664
+ * @param value
665
+ * @param timeStamp
666
+ */
667
+ CookieStorage.prototype.setDomain = function (name, value, timeStamp) {
668
+ var domain = getCurrentDomain();
669
+ if (domain === 'url解析失败') {
670
+ domain = '';
671
+ }
672
+ this.set(name, value, timeStamp, '/', domain);
673
+ };
674
+ return CookieStorage;
675
+ }());
676
+ /**
677
+ * localStorage 操作
678
+ */
679
+ var LocalStorage = /** @class */ (function () {
680
+ function LocalStorage() {
681
+ this.name = 'LocalStorage';
682
+ }
683
+ /**
684
+ * 判断是否支持localStorage
685
+ */
686
+ LocalStorage.prototype.isSupport = function () {
687
+ var supported = true;
688
+ try {
689
+ var supportName = '__localStorageSupport__';
690
+ var val = 'testIsSupportStorage';
691
+ this.set(supportName, val);
692
+ if (this.get(supportName) !== val) {
693
+ supported = false;
694
+ }
695
+ this.remove(supportName);
696
+ }
697
+ catch (e) {
698
+ supported = false;
699
+ }
700
+ return supported;
701
+ };
702
+ LocalStorage.prototype.key = function (index) {
703
+ return window.localStorage.key(index);
704
+ };
705
+ LocalStorage.prototype.get = function (key) {
706
+ return window.localStorage.getItem(key);
707
+ };
708
+ LocalStorage.prototype.length = function () {
709
+ return window.localStorage.length;
710
+ };
711
+ LocalStorage.prototype.set = function (key, value) {
712
+ try {
713
+ window.localStorage.setItem(key, value);
714
+ }
715
+ catch (e) { }
716
+ };
717
+ LocalStorage.prototype.remove = function (key) {
718
+ window.localStorage.removeItem(key);
719
+ };
720
+ LocalStorage.prototype.parse = function (key) {
721
+ var result = this.get(key);
722
+ try {
723
+ result = JSON.parse(result);
724
+ }
725
+ catch (e) {
726
+ result = '';
727
+ }
728
+ return result;
729
+ };
730
+ return LocalStorage;
731
+ }());
732
+ /**
733
+ * memoryStorage 操作
734
+ */
735
+ var MemoryStorage = /** @class */ (function () {
736
+ function MemoryStorage() {
737
+ this.name = 'MemoryStorage';
738
+ this.data = {};
739
+ }
740
+ MemoryStorage.prototype.get = function (key) {
741
+ var result = this.data[key];
742
+ if (isValid(result === null || result === void 0 ? void 0 : result.expireTime)) {
743
+ if (result.expireTime < nowStamp()) {
744
+ return null;
745
+ }
746
+ return result.value;
747
+ }
748
+ return result === null || result === void 0 ? void 0 : result.value;
749
+ };
750
+ /**
751
+ * 存储数据
752
+ * @param key
753
+ * @param value
754
+ * @param expires 单位 s
755
+ */
756
+ MemoryStorage.prototype.set = function (key, value, expires) {
757
+ if (isValid(expires)) {
758
+ var expireTime = nowStamp() + expires * 1000;
759
+ this.data[key] = {
760
+ value: value,
761
+ expireTime: expireTime
762
+ };
763
+ }
764
+ this.data[key] = { value: value };
765
+ };
766
+ MemoryStorage.prototype.setDomain = function (name, value, timeStamp) {
767
+ this.set(name, value, timeStamp);
768
+ };
769
+ return MemoryStorage;
770
+ }());
771
+
772
+ function isElement(val) {
773
+ return (val === null || val === void 0 ? void 0 : val.nodeType) === 1;
774
+ }
775
+ /**
776
+ * 获取指定元素以及其父元素组成的路径
777
+ * @param element
778
+ */
779
+ function getElementParents(element) {
780
+ var pathArr = [element];
781
+ try {
782
+ if (!isElement(element)) {
783
+ return pathArr;
784
+ }
785
+ if (element === null || element.parentElement === null) {
786
+ return pathArr;
787
+ }
788
+ while (element.parentElement !== null) {
789
+ element = element.parentElement;
790
+ pathArr.push(element);
791
+ }
792
+ return pathArr;
793
+ }
794
+ catch (error) { }
795
+ return pathArr;
796
+ }
797
+ /**
798
+ * 获取input元素的内容
799
+ * @param element
800
+ * @param isCollectInput 是否采集input
801
+ */
802
+ function getInputElementContent(element, isCollectInput) {
803
+ var _a;
804
+ var tagName = (_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
805
+ if (tagName === 'input') {
806
+ if (['button', 'submit'].includes(element.type) || isCollectInput) {
807
+ return element.value || '';
808
+ }
809
+ return '';
810
+ }
811
+ var textContent = '';
812
+ if (element.textContent) {
813
+ textContent = element.textContent.trim();
814
+ }
815
+ else if (element.innerText) {
816
+ textContent = element.innerText.trim();
817
+ }
818
+ if (textContent) {
819
+ textContent = textContent
820
+ .replace(/[\r\n]/g, ' ')
821
+ .replace(/[ ]+/g, ' ')
822
+ .substring(0, 255);
823
+ }
824
+ return textContent || '';
825
+ }
826
+ /**
827
+ * 获取元素信息
828
+ * @param element 元素
829
+ * @param isCollectInput 是否采集input
830
+ */
831
+ function getElementProperties(element, isCollectInput) {
832
+ var _a;
833
+ if (!isElement(element))
834
+ return {};
835
+ var tagName = (_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
836
+ var props = {
837
+ H_element_type: tagName,
838
+ H_element_name: element.getAttribute('name'),
839
+ H_element_id: element.getAttribute('id'),
840
+ H_element_target_url: element.getAttribute('href'),
841
+ H_element_class_name: element.getAttribute('className'),
842
+ H_element_content: getInputElementContent(element, isCollectInput)
843
+ };
844
+ return stripEmptyProperties(props);
845
+ }
846
+ /**
847
+ * 获取页面信息
848
+ */
849
+ function getPageProperties() {
850
+ var referrer = getReferrer();
851
+ var url_domain = getCurrentDomain();
852
+ var viewportPosition = Math.round(getScrollTop());
853
+ var props = {
854
+ H_referrer: referrer,
855
+ H_referrer_host: referrer ? getHostname(referrer) : '',
856
+ H_url: window.location.href,
857
+ H_url_host: getHostname(window.location.href, 'url_host取值异常'),
858
+ H_url_domain: url_domain,
859
+ H_url_path: window.location.pathname,
860
+ H_url_hash: window.location.hash,
861
+ H_title: document.title,
862
+ H_viewport_position: viewportPosition
863
+ };
864
+ return stripEmptyProperties(props);
865
+ }
866
+
867
+ var SearchKeyword = /** @class */ (function () {
868
+ function SearchKeyword() {
869
+ }
870
+ SearchKeyword.getSourceFromReferrer = function () {
871
+ var getMatchStrFromArr = function (arr, str) {
872
+ for (var i = 0; i < arr.length; i++) {
873
+ if (str.split('?')[0].indexOf(arr[i]) !== -1) {
874
+ return true;
875
+ }
876
+ }
877
+ };
878
+ var utm_reg = "(".concat(utmTypes.join('|'), ")\\=[^&]+");
879
+ var referrer = document.referrer || '';
880
+ var url = window.location.href;
881
+ if (url) {
882
+ var utm_match = url.match(new RegExp(utm_reg));
883
+ if (utm_match && utm_match[0]) {
884
+ return '付费广告流量';
885
+ }
886
+ if (getMatchStrFromArr(searchTypes, referrer)) {
887
+ return '自然搜索流量';
888
+ }
889
+ if (getMatchStrFromArr(socialTypes, referrer)) {
890
+ return '社交网站流量';
891
+ }
892
+ if (referrer === '') {
893
+ return '直接流量';
894
+ }
895
+ return '引荐流量';
896
+ }
897
+ return '获取url异常';
898
+ };
899
+ SearchKeyword.getReferSearchEngine = function (referrerUrl) {
900
+ var e_1, _a;
901
+ var hostname = getHostname(referrerUrl);
902
+ if (!hostname || hostname === 'hostname解析异常') {
903
+ return '';
904
+ }
905
+ var regexps = {
906
+ baidu: [/^.*\.baidu\.com$/],
907
+ bing: [/^.*\.bing\.com$/],
908
+ google: [
909
+ /^www\.google\.com$/,
910
+ /^www\.google\.com\.[a-z]{2}$/,
911
+ /^www\.google\.[a-z]{2}$/
912
+ ],
913
+ sm: [/^m\.sm\.cn$/],
914
+ so: [/^.+\.so\.com$/],
915
+ sogou: [/^.*\.sogou\.com$/],
916
+ yahoo: [/^.*\.yahoo\.com$/]
917
+ };
918
+ for (var regexp in regexps) {
919
+ var regexList = regexps[regexp];
920
+ try {
921
+ for (var regexList_1 = (e_1 = void 0, __values(regexList)), regexList_1_1 = regexList_1.next(); !regexList_1_1.done; regexList_1_1 = regexList_1.next()) {
922
+ var regex = regexList_1_1.value;
923
+ if (regex.test(hostname)) {
924
+ return regexp;
925
+ }
926
+ }
927
+ }
928
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
929
+ finally {
930
+ try {
931
+ if (regexList_1_1 && !regexList_1_1.done && (_a = regexList_1.return)) _a.call(regexList_1);
932
+ }
933
+ finally { if (e_1) throw e_1.error; }
934
+ }
935
+ }
936
+ return '未知搜索引擎';
937
+ };
938
+ SearchKeyword.getKeywordFromReferrer = function () {
939
+ var referrerUrl = document.referrer || '';
940
+ if (referrerUrl.indexOf('http') === 0) {
941
+ var searchEngine = this.getReferSearchEngine(referrerUrl);
942
+ var query = getURLSearchParams(getURL(referrerUrl).search);
943
+ if (isEmptyObject(query)) {
944
+ return '未取到值';
945
+ }
946
+ for (var key in searchKeywords) {
947
+ var value = searchKeywords[key];
948
+ if (key === searchEngine) {
949
+ if (isArray(value)) {
950
+ for (var i = 0; i < value.length; i++) {
951
+ var val = query[value[i]];
952
+ if (val) {
953
+ return val;
954
+ }
955
+ }
956
+ }
957
+ else if (query[value]) {
958
+ return query[value];
959
+ }
960
+ }
961
+ }
962
+ return '未取到值';
963
+ }
964
+ if (referrerUrl === '') {
965
+ return '未取到值_直接打开';
966
+ }
967
+ return '未取到值_非http的url';
968
+ };
969
+ return SearchKeyword;
970
+ }());
971
+ /**
972
+ * 广告参数
973
+ * @param prefix
974
+ */
975
+ function getUmtsParams(prefix) {
976
+ if (prefix === void 0) { prefix = ''; }
977
+ var utms = getUtm();
978
+ var allUtms = {};
979
+ Object.keys(utms).forEach(function (key) {
980
+ allUtms[prefix + key] = utms[key];
981
+ });
982
+ return allUtms;
983
+ }
984
+ function getUtm() {
985
+ var params = {};
986
+ utmTypes.forEach(function (key) {
987
+ var result = getQueryParam(window.location.href, key);
988
+ if (result.length) {
989
+ params[key] = result;
990
+ }
991
+ });
992
+ return params;
993
+ }
994
+
995
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
996
+
997
+ function getDefaultExportFromCjs (x) {
998
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
999
+ }
1000
+
1001
+ var uaParser = {exports: {}};
1002
+
1003
+ (function (module, exports) {
1004
+ /////////////////////////////////////////////////////////////////////////////////
1005
+ /* UAParser.js v1.0.38
1006
+ Copyright © 2012-2021 Faisal Salman <f@faisalman.com>
1007
+ MIT License *//*
1008
+ Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
1009
+ Supports browser & node.js environment.
1010
+ Demo : https://faisalman.github.io/ua-parser-js
1011
+ Source : https://github.com/faisalman/ua-parser-js */
1012
+ /////////////////////////////////////////////////////////////////////////////////
1013
+
1014
+ (function (window, undefined$1) {
1015
+
1016
+ //////////////
1017
+ // Constants
1018
+ /////////////
1019
+
1020
+
1021
+ var LIBVERSION = '1.0.38',
1022
+ EMPTY = '',
1023
+ UNKNOWN = '?',
1024
+ FUNC_TYPE = 'function',
1025
+ UNDEF_TYPE = 'undefined',
1026
+ OBJ_TYPE = 'object',
1027
+ STR_TYPE = 'string',
1028
+ MAJOR = 'major',
1029
+ MODEL = 'model',
1030
+ NAME = 'name',
1031
+ TYPE = 'type',
1032
+ VENDOR = 'vendor',
1033
+ VERSION = 'version',
1034
+ ARCHITECTURE= 'architecture',
1035
+ CONSOLE = 'console',
1036
+ MOBILE = 'mobile',
1037
+ TABLET = 'tablet',
1038
+ SMARTTV = 'smarttv',
1039
+ WEARABLE = 'wearable',
1040
+ EMBEDDED = 'embedded',
1041
+ UA_MAX_LENGTH = 500;
1042
+
1043
+ var AMAZON = 'Amazon',
1044
+ APPLE = 'Apple',
1045
+ ASUS = 'ASUS',
1046
+ BLACKBERRY = 'BlackBerry',
1047
+ BROWSER = 'Browser',
1048
+ CHROME = 'Chrome',
1049
+ EDGE = 'Edge',
1050
+ FIREFOX = 'Firefox',
1051
+ GOOGLE = 'Google',
1052
+ HUAWEI = 'Huawei',
1053
+ LG = 'LG',
1054
+ MICROSOFT = 'Microsoft',
1055
+ MOTOROLA = 'Motorola',
1056
+ OPERA = 'Opera',
1057
+ SAMSUNG = 'Samsung',
1058
+ SHARP = 'Sharp',
1059
+ SONY = 'Sony',
1060
+ XIAOMI = 'Xiaomi',
1061
+ ZEBRA = 'Zebra',
1062
+ FACEBOOK = 'Facebook',
1063
+ CHROMIUM_OS = 'Chromium OS',
1064
+ MAC_OS = 'Mac OS';
1065
+
1066
+ ///////////
1067
+ // Helper
1068
+ //////////
1069
+
1070
+ var extend = function (regexes, extensions) {
1071
+ var mergedRegexes = {};
1072
+ for (var i in regexes) {
1073
+ if (extensions[i] && extensions[i].length % 2 === 0) {
1074
+ mergedRegexes[i] = extensions[i].concat(regexes[i]);
1075
+ } else {
1076
+ mergedRegexes[i] = regexes[i];
1077
+ }
1078
+ }
1079
+ return mergedRegexes;
1080
+ },
1081
+ enumerize = function (arr) {
1082
+ var enums = {};
1083
+ for (var i=0; i<arr.length; i++) {
1084
+ enums[arr[i].toUpperCase()] = arr[i];
1085
+ }
1086
+ return enums;
1087
+ },
1088
+ has = function (str1, str2) {
1089
+ return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
1090
+ },
1091
+ lowerize = function (str) {
1092
+ return str.toLowerCase();
1093
+ },
1094
+ majorize = function (version) {
1095
+ return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined$1;
1096
+ },
1097
+ trim = function (str, len) {
1098
+ if (typeof(str) === STR_TYPE) {
1099
+ str = str.replace(/^\s\s*/, EMPTY);
1100
+ return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
1101
+ }
1102
+ };
1103
+
1104
+ ///////////////
1105
+ // Map helper
1106
+ //////////////
1107
+
1108
+ var rgxMapper = function (ua, arrays) {
1109
+
1110
+ var i = 0, j, k, p, q, matches, match;
1111
+
1112
+ // loop through all regexes maps
1113
+ while (i < arrays.length && !matches) {
1114
+
1115
+ var regex = arrays[i], // even sequence (0,2,4,..)
1116
+ props = arrays[i + 1]; // odd sequence (1,3,5,..)
1117
+ j = k = 0;
1118
+
1119
+ // try matching uastring with regexes
1120
+ while (j < regex.length && !matches) {
1121
+
1122
+ if (!regex[j]) { break; }
1123
+ matches = regex[j++].exec(ua);
1124
+
1125
+ if (!!matches) {
1126
+ for (p = 0; p < props.length; p++) {
1127
+ match = matches[++k];
1128
+ q = props[p];
1129
+ // check if given property is actually array
1130
+ if (typeof q === OBJ_TYPE && q.length > 0) {
1131
+ if (q.length === 2) {
1132
+ if (typeof q[1] == FUNC_TYPE) {
1133
+ // assign modified match
1134
+ this[q[0]] = q[1].call(this, match);
1135
+ } else {
1136
+ // assign given value, ignore regex match
1137
+ this[q[0]] = q[1];
1138
+ }
1139
+ } else if (q.length === 3) {
1140
+ // check whether function or regex
1141
+ if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
1142
+ // call function (usually string mapper)
1143
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined$1;
1144
+ } else {
1145
+ // sanitize match using given regex
1146
+ this[q[0]] = match ? match.replace(q[1], q[2]) : undefined$1;
1147
+ }
1148
+ } else if (q.length === 4) {
1149
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined$1;
1150
+ }
1151
+ } else {
1152
+ this[q] = match ? match : undefined$1;
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ i += 2;
1158
+ }
1159
+ },
1160
+
1161
+ strMapper = function (str, map) {
1162
+
1163
+ for (var i in map) {
1164
+ // check if current value is array
1165
+ if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
1166
+ for (var j = 0; j < map[i].length; j++) {
1167
+ if (has(map[i][j], str)) {
1168
+ return (i === UNKNOWN) ? undefined$1 : i;
1169
+ }
1170
+ }
1171
+ } else if (has(map[i], str)) {
1172
+ return (i === UNKNOWN) ? undefined$1 : i;
1173
+ }
1174
+ }
1175
+ return str;
1176
+ };
1177
+
1178
+ ///////////////
1179
+ // String map
1180
+ //////////////
1181
+
1182
+ // Safari < 3.0
1183
+ var oldSafariMap = {
1184
+ '1.0' : '/8',
1185
+ '1.2' : '/1',
1186
+ '1.3' : '/3',
1187
+ '2.0' : '/412',
1188
+ '2.0.2' : '/416',
1189
+ '2.0.3' : '/417',
1190
+ '2.0.4' : '/419',
1191
+ '?' : '/'
1192
+ },
1193
+ windowsVersionMap = {
1194
+ 'ME' : '4.90',
1195
+ 'NT 3.11' : 'NT3.51',
1196
+ 'NT 4.0' : 'NT4.0',
1197
+ '2000' : 'NT 5.0',
1198
+ 'XP' : ['NT 5.1', 'NT 5.2'],
1199
+ 'Vista' : 'NT 6.0',
1200
+ '7' : 'NT 6.1',
1201
+ '8' : 'NT 6.2',
1202
+ '8.1' : 'NT 6.3',
1203
+ '10' : ['NT 6.4', 'NT 10.0'],
1204
+ 'RT' : 'ARM'
1205
+ };
1206
+
1207
+ //////////////
1208
+ // Regex map
1209
+ /////////////
1210
+
1211
+ var regexes = {
1212
+
1213
+ browser : [[
1214
+
1215
+ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
1216
+ ], [VERSION, [NAME, 'Chrome']], [
1217
+ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge
1218
+ ], [VERSION, [NAME, 'Edge']], [
1219
+
1220
+ // Presto based
1221
+ /(opera mini)\/([-\w\.]+)/i, // Opera Mini
1222
+ /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet
1223
+ /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera
1224
+ ], [NAME, VERSION], [
1225
+ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
1226
+ ], [VERSION, [NAME, OPERA+' Mini']], [
1227
+ /\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
1228
+ ], [VERSION, [NAME, OPERA+' GX']], [
1229
+ /\bopr\/([\w\.]+)/i // Opera Webkit
1230
+ ], [VERSION, [NAME, OPERA]], [
1231
+
1232
+ // Mixed
1233
+ /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
1234
+ ], [VERSION, [NAME, 'Baidu']], [
1235
+ /(kindle)\/([\w\.]+)/i, // Kindle
1236
+ /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
1237
+ // Trident based
1238
+ /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
1239
+ /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
1240
+
1241
+ // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
1242
+ /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
1243
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ
1244
+ /(heytap|ovi)browser\/([\d\.]+)/i, // Heytap/Ovi
1245
+ /(weibo)__([\d\.]+)/i // Weibo
1246
+ ], [NAME, VERSION], [
1247
+ /\bddg\/([\w\.]+)/i // DuckDuckGo
1248
+ ], [VERSION, [NAME, 'DuckDuckGo']], [
1249
+ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
1250
+ ], [VERSION, [NAME, 'UC'+BROWSER]], [
1251
+ /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
1252
+ /\bqbcore\/([\w\.]+).+microm/i,
1253
+ /micromessenger\/([\w\.]+)/i // WeChat
1254
+ ], [VERSION, [NAME, 'WeChat']], [
1255
+ /konqueror\/([\w\.]+)/i // Konqueror
1256
+ ], [VERSION, [NAME, 'Konqueror']], [
1257
+ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11
1258
+ ], [VERSION, [NAME, 'IE']], [
1259
+ /ya(?:search)?browser\/([\w\.]+)/i // Yandex
1260
+ ], [VERSION, [NAME, 'Yandex']], [
1261
+ /slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
1262
+ ], [VERSION, [NAME, 'Smart Lenovo '+BROWSER]], [
1263
+ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
1264
+ ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [
1265
+ /\bfocus\/([\w\.]+)/i // Firefox Focus
1266
+ ], [VERSION, [NAME, FIREFOX+' Focus']], [
1267
+ /\bopt\/([\w\.]+)/i // Opera Touch
1268
+ ], [VERSION, [NAME, OPERA+' Touch']], [
1269
+ /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser
1270
+ ], [VERSION, [NAME, 'Coc Coc']], [
1271
+ /dolfin\/([\w\.]+)/i // Dolphin
1272
+ ], [VERSION, [NAME, 'Dolphin']], [
1273
+ /coast\/([\w\.]+)/i // Opera Coast
1274
+ ], [VERSION, [NAME, OPERA+' Coast']], [
1275
+ /miuibrowser\/([\w\.]+)/i // MIUI Browser
1276
+ ], [VERSION, [NAME, 'MIUI '+BROWSER]], [
1277
+ /fxios\/([-\w\.]+)/i // Firefox for iOS
1278
+ ], [VERSION, [NAME, FIREFOX]], [
1279
+ /\bqihu|(qi?ho?o?|360)browser/i // 360
1280
+ ], [[NAME, '360 ' + BROWSER]], [
1281
+ /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i
1282
+ ], [[NAME, /(.+)/, '$1 ' + BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser
1283
+ /samsungbrowser\/([\w\.]+)/i // Samsung Internet
1284
+ ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
1285
+ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
1286
+ ], [[NAME, /_/g, ' '], VERSION], [
1287
+ /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
1288
+ ], [VERSION, [NAME, 'Sogou Explorer']], [
1289
+ /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
1290
+ ], [[NAME, 'Sogou Mobile'], VERSION], [
1291
+ /(electron)\/([\w\.]+) safari/i, // Electron-based App
1292
+ /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
1293
+ /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
1294
+ ], [NAME, VERSION], [
1295
+ /(lbbrowser)/i, // LieBao Browser
1296
+ /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
1297
+ ], [NAME], [
1298
+
1299
+ // WebView
1300
+ /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
1301
+ ], [[NAME, FACEBOOK], VERSION], [
1302
+ /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
1303
+ /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
1304
+ /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
1305
+ /safari (line)\/([\w\.]+)/i, // Line App for iOS
1306
+ /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
1307
+ /(alipay)client\/([\w\.]+)/i, // Alipay
1308
+ /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
1309
+ /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
1310
+ ], [NAME, VERSION], [
1311
+ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
1312
+ ], [VERSION, [NAME, 'GSA']], [
1313
+ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
1314
+ ], [VERSION, [NAME, 'TikTok']], [
1315
+
1316
+ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
1317
+ ], [VERSION, [NAME, CHROME+' Headless']], [
1318
+
1319
+ / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
1320
+ ], [[NAME, CHROME+' WebView'], VERSION], [
1321
+
1322
+ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
1323
+ ], [VERSION, [NAME, 'Android '+BROWSER]], [
1324
+
1325
+ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia
1326
+ ], [NAME, VERSION], [
1327
+
1328
+ /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i // Mobile Safari
1329
+ ], [VERSION, [NAME, 'Mobile Safari']], [
1330
+ /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile
1331
+ ], [VERSION, NAME], [
1332
+ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
1333
+ ], [NAME, [VERSION, strMapper, oldSafariMap]], [
1334
+
1335
+ /(webkit|khtml)\/([\w\.]+)/i
1336
+ ], [NAME, VERSION], [
1337
+
1338
+ // Gecko based
1339
+ /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
1340
+ ], [[NAME, 'Netscape'], VERSION], [
1341
+ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
1342
+ ], [VERSION, [NAME, FIREFOX+' Reality']], [
1343
+ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow
1344
+ /(swiftfox)/i, // Swiftfox
1345
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
1346
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
1347
+ /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
1348
+ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
1349
+ /(firefox)\/([\w\.]+)/i, // Other Firefox-based
1350
+ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
1351
+
1352
+ // Other
1353
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
1354
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
1355
+ /(links) \(([\w\.]+)/i, // Links
1356
+ /panasonic;(viera)/i // Panasonic Viera
1357
+ ], [NAME, VERSION], [
1358
+
1359
+ /(cobalt)\/([\w\.]+)/i // Cobalt
1360
+ ], [NAME, [VERSION, /master.|lts./, ""]]
1361
+ ],
1362
+
1363
+ cpu : [[
1364
+
1365
+ /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64)
1366
+ ], [[ARCHITECTURE, 'amd64']], [
1367
+
1368
+ /(ia32(?=;))/i // IA32 (quicktime)
1369
+ ], [[ARCHITECTURE, lowerize]], [
1370
+
1371
+ /((?:i[346]|x)86)[;\)]/i // IA32 (x86)
1372
+ ], [[ARCHITECTURE, 'ia32']], [
1373
+
1374
+ /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64
1375
+ ], [[ARCHITECTURE, 'arm64']], [
1376
+
1377
+ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF
1378
+ ], [[ARCHITECTURE, 'armhf']], [
1379
+
1380
+ // PocketPC mistakenly identified as PowerPC
1381
+ /windows (ce|mobile); ppc;/i
1382
+ ], [[ARCHITECTURE, 'arm']], [
1383
+
1384
+ /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC
1385
+ ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
1386
+
1387
+ /(sun4\w)[;\)]/i // SPARC
1388
+ ], [[ARCHITECTURE, 'sparc']], [
1389
+
1390
+ /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
1391
+ // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
1392
+ ], [[ARCHITECTURE, lowerize]]
1393
+ ],
1394
+
1395
+ device : [[
1396
+
1397
+ //////////////////////////
1398
+ // MOBILES & TABLETS
1399
+ /////////////////////////
1400
+
1401
+ // Samsung
1402
+ /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
1403
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
1404
+ /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
1405
+ /samsung[- ]([-\w]+)/i,
1406
+ /sec-(sgh\w+)/i
1407
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
1408
+
1409
+ // Apple
1410
+ /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i // iPod/iPhone
1411
+ ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
1412
+ /\((ipad);[-\w\),; ]+apple/i, // iPad
1413
+ /applecoremedia\/[\w\.]+ \((ipad)/i,
1414
+ /\b(ipad)\d\d?,\d\d?[;\]].+ios/i
1415
+ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
1416
+ /(macintosh);/i
1417
+ ], [MODEL, [VENDOR, APPLE]], [
1418
+
1419
+ // Sharp
1420
+ /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
1421
+ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
1422
+
1423
+ // Huawei
1424
+ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
1425
+ ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
1426
+ /(?:huawei|honor)([-\w ]+)[;\)]/i,
1427
+ /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
1428
+ ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
1429
+
1430
+ // Xiaomi
1431
+ /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO
1432
+ /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
1433
+ /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
1434
+ /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
1435
+ /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
1436
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
1437
+ ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
1438
+ /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
1439
+ /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
1440
+ ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
1441
+
1442
+ // OPPO
1443
+ /; (\w+) bui.+ oppo/i,
1444
+ /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
1445
+ ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
1446
+ /\b(opd2\d{3}a?) bui/i
1447
+ ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
1448
+
1449
+ // Vivo
1450
+ /vivo (\w+)(?: bui|\))/i,
1451
+ /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
1452
+ ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
1453
+
1454
+ // Realme
1455
+ /\b(rmx[1-3]\d{3})(?: bui|;|\))/i
1456
+ ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
1457
+
1458
+ // Motorola
1459
+ /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
1460
+ /\bmot(?:orola)?[- ](\w*)/i,
1461
+ /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
1462
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
1463
+ /\b(mz60\d|xoom[2 ]{0,2}) build\//i
1464
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
1465
+
1466
+ // LG
1467
+ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
1468
+ ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
1469
+ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
1470
+ /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
1471
+ /\blg-?([\d\w]+) bui/i
1472
+ ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
1473
+
1474
+ // Lenovo
1475
+ /(ideatab[-\w ]+)/i,
1476
+ /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
1477
+ ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
1478
+
1479
+ // Nokia
1480
+ /(?:maemo|nokia).*(n900|lumia \d+)/i,
1481
+ /nokia[-_ ]?([-\w\.]*)/i
1482
+ ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [
1483
+
1484
+ // Google
1485
+ /(pixel c)\b/i // Google Pixel C
1486
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
1487
+ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel
1488
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
1489
+
1490
+ // Sony
1491
+ /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
1492
+ ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
1493
+ /sony tablet [ps]/i,
1494
+ /\b(?:sony)?sgp\w+(?: bui|\))/i
1495
+ ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
1496
+
1497
+ // OnePlus
1498
+ / (kb2005|in20[12]5|be20[12][59])\b/i,
1499
+ /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
1500
+ ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
1501
+
1502
+ // Amazon
1503
+ /(alexa)webm/i,
1504
+ /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
1505
+ /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
1506
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
1507
+ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
1508
+ ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [
1509
+
1510
+ // BlackBerry
1511
+ /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook
1512
+ ], [MODEL, VENDOR, [TYPE, TABLET]], [
1513
+ /\b((?:bb[a-f]|st[hv])100-\d)/i,
1514
+ /\(bb10; (\w+)/i // BlackBerry 10
1515
+ ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
1516
+
1517
+ // Asus
1518
+ /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
1519
+ ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [
1520
+ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
1521
+ ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [
1522
+
1523
+ // HTC
1524
+ /(nexus 9)/i // HTC Nexus 9
1525
+ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
1526
+ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC
1527
+
1528
+ // ZTE
1529
+ /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
1530
+ /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
1531
+ ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
1532
+
1533
+ // Acer
1534
+ /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
1535
+ ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
1536
+
1537
+ // Meizu
1538
+ /droid.+; (m[1-5] note) bui/i,
1539
+ /\bmz-([-\w]{2,})/i
1540
+ ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
1541
+
1542
+ // Ulefone
1543
+ /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
1544
+ ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
1545
+
1546
+ // MIXED
1547
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
1548
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
1549
+ /(hp) ([\w ]+\w)/i, // HP iPAQ
1550
+ /(asus)-?(\w+)/i, // Asus
1551
+ /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
1552
+ /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo
1553
+ /(jolla)/i, // Jolla
1554
+ /(oppo) ?([\w ]+) bui/i // OPPO
1555
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1556
+
1557
+ /(kobo)\s(ereader|touch)/i, // Kobo
1558
+ /(archos) (gamepad2?)/i, // Archos
1559
+ /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
1560
+ /(kindle)\/([\w\.]+)/i, // Kindle
1561
+ /(nook)[\w ]+build\/(\w+)/i, // Nook
1562
+ /(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak
1563
+ /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets
1564
+ /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets
1565
+ /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets
1566
+ /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone
1567
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
1568
+
1569
+ /(surface duo)/i // Surface Duo
1570
+ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [
1571
+ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone
1572
+ ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [
1573
+ /(u304aa)/i // AT&T
1574
+ ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [
1575
+ /\bsie-(\w*)/i // Siemens
1576
+ ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
1577
+ /\b(rct\w+) b/i // RCA Tablets
1578
+ ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
1579
+ /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets
1580
+ ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
1581
+ /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet
1582
+ ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
1583
+ /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet
1584
+ ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [
1585
+ /\b(tm\d{3}\w+) b/i
1586
+ ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
1587
+ /\b(k88) b/i // ZTE K Series Tablet
1588
+ ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
1589
+ /\b(nx\d{3}j) b/i // ZTE Nubia
1590
+ ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
1591
+ /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile
1592
+ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
1593
+ /\b(zur\d{3}) b/i // Swiss ZUR Tablet
1594
+ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
1595
+ /\b((zeki)?tb.*\b) b/i // Zeki Tablets
1596
+ ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
1597
+ /\b([yr]\d{2}) b/i,
1598
+ /\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet
1599
+ ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [
1600
+ /\b(ns-?\w{0,9}) b/i // Insignia Tablets
1601
+ ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
1602
+ /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets
1603
+ ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
1604
+ /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones
1605
+ ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [
1606
+ /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones
1607
+ ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
1608
+ /\b(ph-1) /i // Essential PH-1
1609
+ ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [
1610
+ /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets
1611
+ ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
1612
+ /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets
1613
+ ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
1614
+ /\btu_(1491) b/i // Rotor Tablets
1615
+ ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [
1616
+ /(shield[\w ]+) b/i // Nvidia Shield Tablets
1617
+ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [
1618
+ /(sprint) (\w+)/i // Sprint Phones
1619
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1620
+ /(kin\.[onetw]{3})/i // Microsoft Kin
1621
+ ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [
1622
+ /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra
1623
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [
1624
+ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
1625
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [
1626
+
1627
+ ///////////////////
1628
+ // SMARTTVS
1629
+ ///////////////////
1630
+
1631
+ /smart-tv.+(samsung)/i // Samsung
1632
+ ], [VENDOR, [TYPE, SMARTTV]], [
1633
+ /hbbtv.+maple;(\d+)/i
1634
+ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
1635
+ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV
1636
+ ], [[VENDOR, LG], [TYPE, SMARTTV]], [
1637
+ /(apple) ?tv/i // Apple TV
1638
+ ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
1639
+ /crkey/i // Google Chromecast
1640
+ ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
1641
+ /droid.+aft(\w+)( bui|\))/i // Fire TV
1642
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
1643
+ /\(dtv[\);].+(aquos)/i,
1644
+ /(aquos-tv[\w ]+)\)/i // Sharp
1645
+ ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[
1646
+ /(bravia[\w ]+)( bui|\))/i // Sony
1647
+ ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [
1648
+ /(mitv-\w{5}) bui/i // Xiaomi
1649
+ ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [
1650
+ /Hbbtv.*(technisat) (.*);/i // TechniSAT
1651
+ ], [VENDOR, MODEL, [TYPE, SMARTTV]], [
1652
+ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
1653
+ /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
1654
+ ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [
1655
+ /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors
1656
+ ], [[TYPE, SMARTTV]], [
1657
+
1658
+ ///////////////////
1659
+ // CONSOLES
1660
+ ///////////////////
1661
+
1662
+ /(ouya)/i, // Ouya
1663
+ /(nintendo) ([wids3utch]+)/i // Nintendo
1664
+ ], [VENDOR, MODEL, [TYPE, CONSOLE]], [
1665
+ /droid.+; (shield) bui/i // Nvidia
1666
+ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
1667
+ /(playstation [345portablevi]+)/i // Playstation
1668
+ ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
1669
+ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox
1670
+ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
1671
+
1672
+ ///////////////////
1673
+ // WEARABLES
1674
+ ///////////////////
1675
+
1676
+ /((pebble))app/i // Pebble
1677
+ ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
1678
+ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
1679
+ ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
1680
+ /droid.+; (glass) \d/i // Google Glass
1681
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
1682
+ /droid.+; (wt63?0{2,3})\)/i
1683
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
1684
+ /(quest( \d| pro)?)/i // Oculus Quest
1685
+ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
1686
+
1687
+ ///////////////////
1688
+ // EMBEDDED
1689
+ ///////////////////
1690
+
1691
+ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla
1692
+ ], [VENDOR, [TYPE, EMBEDDED]], [
1693
+ /(aeobc)\b/i // Echo Dot
1694
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [
1695
+
1696
+ ////////////////////
1697
+ // MIXED (GENERIC)
1698
+ ///////////////////
1699
+
1700
+ /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
1701
+ ], [MODEL, [TYPE, MOBILE]], [
1702
+ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
1703
+ ], [MODEL, [TYPE, TABLET]], [
1704
+ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
1705
+ ], [[TYPE, TABLET]], [
1706
+ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile
1707
+ ], [[TYPE, MOBILE]], [
1708
+ /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device
1709
+ ], [MODEL, [VENDOR, 'Generic']]
1710
+ ],
1711
+
1712
+ engine : [[
1713
+
1714
+ /windows.+ edge\/([\w\.]+)/i // EdgeHTML
1715
+ ], [VERSION, [NAME, EDGE+'HTML']], [
1716
+
1717
+ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
1718
+ ], [VERSION, [NAME, 'Blink']], [
1719
+
1720
+ /(presto)\/([\w\.]+)/i, // Presto
1721
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
1722
+ /ekioh(flow)\/([\w\.]+)/i, // Flow
1723
+ /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
1724
+ /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
1725
+ /\b(libweb)/i
1726
+ ], [NAME, VERSION], [
1727
+
1728
+ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko
1729
+ ], [VERSION, NAME]
1730
+ ],
1731
+
1732
+ os : [[
1733
+
1734
+ // Windows
1735
+ /microsoft (windows) (vista|xp)/i // Windows (iTunes)
1736
+ ], [NAME, VERSION], [
1737
+ /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone
1738
+ ], [NAME, [VERSION, strMapper, windowsVersionMap]], [
1739
+ /windows nt 6\.2; (arm)/i, // Windows RT
1740
+ /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i,
1741
+ /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
1742
+ ], [[VERSION, strMapper, windowsVersionMap], [NAME, 'Windows']], [
1743
+
1744
+ // iOS/macOS
1745
+ /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
1746
+ /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,
1747
+ /cfnetwork\/.+darwin/i
1748
+ ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
1749
+ /(mac os x) ?([\w\. ]*)/i,
1750
+ /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
1751
+ ], [[NAME, MAC_OS], [VERSION, /_/g, '.']], [
1752
+
1753
+ // Mobile OSes
1754
+ /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS
1755
+ ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
1756
+ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
1757
+ /(blackberry)\w*\/([\w\.]*)/i, // Blackberry
1758
+ /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
1759
+ /\((series40);/i // Series 40
1760
+ ], [NAME, VERSION], [
1761
+ /\(bb(10);/i // BlackBerry 10
1762
+ ], [VERSION, [NAME, BLACKBERRY]], [
1763
+ /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian
1764
+ ], [VERSION, [NAME, 'Symbian']], [
1765
+ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
1766
+ ], [VERSION, [NAME, FIREFOX+' OS']], [
1767
+ /web0s;.+rt(tv)/i,
1768
+ /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS
1769
+ ], [VERSION, [NAME, 'webOS']], [
1770
+ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
1771
+ ], [VERSION, [NAME, 'watchOS']], [
1772
+
1773
+ // Google Chromecast
1774
+ /crkey\/([\d\.]+)/i // Google Chromecast
1775
+ ], [VERSION, [NAME, CHROME+'cast']], [
1776
+ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
1777
+ ], [[NAME, CHROMIUM_OS], VERSION],[
1778
+
1779
+ // Smart TVs
1780
+ /panasonic;(viera)/i, // Panasonic Viera
1781
+ /(netrange)mmh/i, // Netrange
1782
+ /(nettv)\/(\d+\.[\w\.]+)/i, // NetTV
1783
+
1784
+ // Console
1785
+ /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation
1786
+ /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
1787
+
1788
+ // Other
1789
+ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
1790
+ /(mint)[\/\(\) ]?(\w*)/i, // Mint
1791
+ /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux
1792
+ /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
1793
+ // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire
1794
+ /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux
1795
+ /(gnu) ?([\w\.]*)/i, // GNU
1796
+ /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
1797
+ /(haiku) (\w+)/i // Haiku
1798
+ ], [NAME, VERSION], [
1799
+ /(sunos) ?([\w\.\d]*)/i // Solaris
1800
+ ], [[NAME, 'Solaris'], VERSION], [
1801
+ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris
1802
+ /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX
1803
+ /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS
1804
+ /(unix) ?([\w\.]*)/i // UNIX
1805
+ ], [NAME, VERSION]
1806
+ ]
1807
+ };
1808
+
1809
+ /////////////////
1810
+ // Constructor
1811
+ ////////////////
1812
+
1813
+ var UAParser = function (ua, extensions) {
1814
+
1815
+ if (typeof ua === OBJ_TYPE) {
1816
+ extensions = ua;
1817
+ ua = undefined$1;
1818
+ }
1819
+
1820
+ if (!(this instanceof UAParser)) {
1821
+ return new UAParser(ua, extensions).getResult();
1822
+ }
1823
+
1824
+ var _navigator = (typeof window !== UNDEF_TYPE && window.navigator) ? window.navigator : undefined$1;
1825
+ var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY);
1826
+ var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined$1;
1827
+ var _rgxmap = extensions ? extend(regexes, extensions) : regexes;
1828
+ var _isSelfNav = _navigator && _navigator.userAgent == _ua;
1829
+
1830
+ this.getBrowser = function () {
1831
+ var _browser = {};
1832
+ _browser[NAME] = undefined$1;
1833
+ _browser[VERSION] = undefined$1;
1834
+ rgxMapper.call(_browser, _ua, _rgxmap.browser);
1835
+ _browser[MAJOR] = majorize(_browser[VERSION]);
1836
+ // Brave-specific detection
1837
+ if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) {
1838
+ _browser[NAME] = 'Brave';
1839
+ }
1840
+ return _browser;
1841
+ };
1842
+ this.getCPU = function () {
1843
+ var _cpu = {};
1844
+ _cpu[ARCHITECTURE] = undefined$1;
1845
+ rgxMapper.call(_cpu, _ua, _rgxmap.cpu);
1846
+ return _cpu;
1847
+ };
1848
+ this.getDevice = function () {
1849
+ var _device = {};
1850
+ _device[VENDOR] = undefined$1;
1851
+ _device[MODEL] = undefined$1;
1852
+ _device[TYPE] = undefined$1;
1853
+ rgxMapper.call(_device, _ua, _rgxmap.device);
1854
+ if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) {
1855
+ _device[TYPE] = MOBILE;
1856
+ }
1857
+ // iPadOS-specific detection: identified as Mac, but has some iOS-only properties
1858
+ if (_isSelfNav && _device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) {
1859
+ _device[MODEL] = 'iPad';
1860
+ _device[TYPE] = TABLET;
1861
+ }
1862
+ return _device;
1863
+ };
1864
+ this.getEngine = function () {
1865
+ var _engine = {};
1866
+ _engine[NAME] = undefined$1;
1867
+ _engine[VERSION] = undefined$1;
1868
+ rgxMapper.call(_engine, _ua, _rgxmap.engine);
1869
+ return _engine;
1870
+ };
1871
+ this.getOS = function () {
1872
+ var _os = {};
1873
+ _os[NAME] = undefined$1;
1874
+ _os[VERSION] = undefined$1;
1875
+ rgxMapper.call(_os, _ua, _rgxmap.os);
1876
+ if (_isSelfNav && !_os[NAME] && _uach && _uach.platform && _uach.platform != 'Unknown') {
1877
+ _os[NAME] = _uach.platform
1878
+ .replace(/chrome os/i, CHROMIUM_OS)
1879
+ .replace(/macos/i, MAC_OS); // backward compatibility
1880
+ }
1881
+ return _os;
1882
+ };
1883
+ this.getResult = function () {
1884
+ return {
1885
+ ua : this.getUA(),
1886
+ browser : this.getBrowser(),
1887
+ engine : this.getEngine(),
1888
+ os : this.getOS(),
1889
+ device : this.getDevice(),
1890
+ cpu : this.getCPU()
1891
+ };
1892
+ };
1893
+ this.getUA = function () {
1894
+ return _ua;
1895
+ };
1896
+ this.setUA = function (ua) {
1897
+ _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
1898
+ return this;
1899
+ };
1900
+ this.setUA(_ua);
1901
+ return this;
1902
+ };
1903
+
1904
+ UAParser.VERSION = LIBVERSION;
1905
+ UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
1906
+ UAParser.CPU = enumerize([ARCHITECTURE]);
1907
+ UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1908
+ UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
1909
+
1910
+ ///////////
1911
+ // Export
1912
+ //////////
1913
+
1914
+ // check js environment
1915
+ {
1916
+ // nodejs env
1917
+ if (module.exports) {
1918
+ exports = module.exports = UAParser;
1919
+ }
1920
+ exports.UAParser = UAParser;
1921
+ }
1922
+
1923
+ // jQuery/Zepto specific (optional)
1924
+ // Note:
1925
+ // In AMD env the global scope should be kept clean, but jQuery is an exception.
1926
+ // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
1927
+ // and we should catch that.
1928
+ var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);
1929
+ if ($ && !$.ua) {
1930
+ var parser = new UAParser();
1931
+ $.ua = parser.getResult();
1932
+ $.ua.get = function () {
1933
+ return parser.getUA();
1934
+ };
1935
+ $.ua.set = function (ua) {
1936
+ parser.setUA(ua);
1937
+ var result = parser.getResult();
1938
+ for (var prop in result) {
1939
+ $.ua[prop] = result[prop];
1940
+ }
1941
+ };
1942
+ }
1943
+
1944
+ })(typeof window === 'object' ? window : commonjsGlobal);
1945
+ } (uaParser, uaParser.exports));
1946
+
1947
+ var uaParserExports = uaParser.exports;
1948
+ var UAParser = /*@__PURE__*/getDefaultExportFromCjs(uaParserExports);
1949
+
1950
+ function getBrowserInfo() {
1951
+ var _a = new UAParser().getResult(), browser = _a.browser, device = _a.device, os = _a.os;
1952
+ var data = {
1953
+ H_timezone_offset: new Date().getTimezoneOffset(),
1954
+ H_viewport_width: getScreenWidth(),
1955
+ H_viewport_height: getScreenHeight(),
1956
+ H_screen_width: window.screen.width,
1957
+ H_screen_height: window.screen.height,
1958
+ H_lib_version: PV_LIB_VERSION,
1959
+ H_lib: 'js',
1960
+ H_lib_method: 'code',
1961
+ H_browser: browser.name.toLowerCase(),
1962
+ H_browser_version: browser.version,
1963
+ H_os: os.name,
1964
+ H_os_version: os.version,
1965
+ H_language: isString(navigator.language)
1966
+ ? navigator.language.toLowerCase()
1967
+ : '取值异常',
1968
+ H_network_type: networkType()
1969
+ };
1970
+ if (device.type === 'mobile') {
1971
+ data.H_model = device.vendor ? device.model : 'UnknownPhone';
1972
+ }
1973
+ else {
1974
+ data.H_model = device.model;
1975
+ }
1976
+ return data;
1977
+ }
1978
+
1979
+ var Request = /** @class */ (function () {
1980
+ function Request(options) {
1981
+ this.options = options;
1982
+ }
1983
+ return Request;
1984
+ }());
1985
+ /**
1986
+ * 图片请求
1987
+ */
1988
+ var ImageRequest = /** @class */ (function (_super) {
1989
+ __extends(ImageRequest, _super);
1990
+ function ImageRequest(options) {
1991
+ var _this = _super.call(this, options) || this;
1992
+ _this.options = options;
1993
+ return _this;
1994
+ }
1995
+ ImageRequest.prototype.run = function () {
1996
+ var _this = this;
1997
+ return new Promise(function (resolve) {
1998
+ var _a = _this.options, imgUseCrossOrigin = _a.imgUseCrossOrigin, url = _a.url, data = _a.data;
1999
+ var img = new Image();
2000
+ if (imgUseCrossOrigin) {
2001
+ img.crossOrigin = 'anonymous';
2002
+ }
2003
+ var spliceStr = url.indexOf('?') === -1 ? '?' : '&';
2004
+ img.src = "".concat(url).concat(spliceStr, "data=").concat(data);
2005
+ var callback = function (type) {
2006
+ img.src = null;
2007
+ img = null;
2008
+ resolve({ type: type });
2009
+ };
2010
+ img.onload = function () {
2011
+ callback('success');
2012
+ };
2013
+ img.onerror = function () {
2014
+ callback('error');
2015
+ };
2016
+ img.onabort = function () {
2017
+ callback('abort');
2018
+ };
2019
+ });
2020
+ };
2021
+ return ImageRequest;
2022
+ }(Request));
2023
+ /**
2024
+ * ajax请求
2025
+ */
2026
+ var AjaxRequest = /** @class */ (function (_super) {
2027
+ __extends(AjaxRequest, _super);
2028
+ function AjaxRequest(options) {
2029
+ var _this = _super.call(this, options) || this;
2030
+ _this.options = options;
2031
+ return _this;
2032
+ }
2033
+ AjaxRequest.prototype.run = function () {
2034
+ var _this = this;
2035
+ return new Promise(function (resolve) {
2036
+ var _a = _this.options, url = _a.url, data = _a.data, timeout = _a.timeout;
2037
+ var xhr = new XMLHttpRequest();
2038
+ xhr.open('POST', url, true);
2039
+ xhr.timeout = timeout || 20000;
2040
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
2041
+ xhr.send(data || null);
2042
+ xhr.onreadystatechange = function () {
2043
+ if (xhr.readyState === 4) {
2044
+ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
2045
+ resolve({
2046
+ type: 'success'
2047
+ });
2048
+ }
2049
+ else {
2050
+ resolve({
2051
+ type: 'error',
2052
+ msg: "\u7F51\u7EDC\u5F02\u5E38, \u8BF7\u6C42\u5931\u8D25".concat(xhr.status)
2053
+ });
2054
+ }
2055
+ }
2056
+ };
2057
+ });
2058
+ };
2059
+ return AjaxRequest;
2060
+ }(Request));
2061
+ /**
2062
+ * beacon请求
2063
+ */
2064
+ var BeaconRequest = /** @class */ (function (_super) {
2065
+ __extends(BeaconRequest, _super);
2066
+ function BeaconRequest(options) {
2067
+ var _this = _super.call(this, options) || this;
2068
+ _this.options = options;
2069
+ return _this;
2070
+ }
2071
+ BeaconRequest.prototype.run = function () {
2072
+ var _this = this;
2073
+ return new Promise(function (resolve) {
2074
+ var _a = _this.options, url = _a.url, data = _a.data;
2075
+ if (navigator.sendBeacon) {
2076
+ var isSuccess = navigator.sendBeacon(url, data);
2077
+ if (isSuccess) {
2078
+ resolve({
2079
+ type: 'success'
2080
+ });
2081
+ }
2082
+ else {
2083
+ resolve({
2084
+ type: 'error',
2085
+ msg: 'sendBeacon 请求失败'
2086
+ });
2087
+ }
2088
+ }
2089
+ });
2090
+ };
2091
+ return BeaconRequest;
2092
+ }(Request));
2093
+
2094
+ var Mitt = /** @class */ (function () {
2095
+ function Mitt() {
2096
+ this.all = new Map();
2097
+ }
2098
+ Mitt.prototype.on = function (type, handler) {
2099
+ var handlers = this.all.get(type);
2100
+ if (handlers) {
2101
+ handlers.push(handler);
2102
+ }
2103
+ else {
2104
+ this.all.set(type, [handler]);
2105
+ }
2106
+ };
2107
+ Mitt.prototype.emit = function (type) {
2108
+ var args = [];
2109
+ for (var _i = 1; _i < arguments.length; _i++) {
2110
+ args[_i - 1] = arguments[_i];
2111
+ }
2112
+ var handlers = this.all.get(type);
2113
+ if (handlers) {
2114
+ handlers.forEach(function (handler) {
2115
+ handler.apply(void 0, __spreadArray([], __read(args), false));
2116
+ });
2117
+ }
2118
+ };
2119
+ Mitt.prototype.off = function (type, handler) {
2120
+ var handlers = this.all.get(type);
2121
+ if (handlers) {
2122
+ if (handler) {
2123
+ var index = handlers.indexOf(handler);
2124
+ if (index >= 0) {
2125
+ handlers.splice(index, 1);
2126
+ }
2127
+ }
2128
+ else {
2129
+ this.all.set(type, []);
2130
+ }
2131
+ }
2132
+ };
2133
+ return Mitt;
2134
+ }());
2135
+ var mitt = new Mitt();
2136
+
2137
+ /**
2138
+ * 是否支持console
2139
+ */
2140
+ function supportConsole() {
2141
+ return typeof console !== 'undefined';
2142
+ }
2143
+ /**
2144
+ * 打印日志
2145
+ * @param message
2146
+ * @param type
2147
+ */
2148
+ function log(message, type) {
2149
+ if (type === void 0) { type = ConsoleTypes.LOG; }
2150
+ var func = console[type] || console.log;
2151
+ if (typeof func === 'function') {
2152
+ func(message);
2153
+ }
2154
+ }
2155
+
2156
+ var IS_NEW_USER_KEY = 'hinasdk_isNewUser';
2157
+ var State = /** @class */ (function () {
2158
+ function State(options) {
2159
+ this.options = options;
2160
+ this.storeName = 'hinasdk_crossdata';
2161
+ /**
2162
+ * 存储对象
2163
+ */
2164
+ this.state = {
2165
+ accountId: null,
2166
+ deviceId: null,
2167
+ anonymousId: null,
2168
+ firstVisitTime: nowStamp(),
2169
+ props: {}
2170
+ };
2171
+ /**
2172
+ * 首次触发事件
2173
+ */
2174
+ this.isFirstTime = false;
2175
+ /**
2176
+ * 首日触发事件
2177
+ */
2178
+ this.isFirstDay = false;
2179
+ /**
2180
+ * 是否设置第一次访问属性
2181
+ */
2182
+ this.isSetFirstVisit = true;
2183
+ }
2184
+ State.prototype.log = function (message, type) {
2185
+ if (type === void 0) { type = ConsoleTypes.LOG; }
2186
+ var showLog = this.options.showLog;
2187
+ if (!supportConsole() || !showLog)
2188
+ return;
2189
+ log(message, type);
2190
+ };
2191
+ /**
2192
+ * 初始化存储
2193
+ */
2194
+ State.prototype.init = function () {
2195
+ var cookieStorage = new CookieStorage();
2196
+ var memoryStorage = new MemoryStorage();
2197
+ var localStorage = new LocalStorage();
2198
+ if (cookieStorage.isSupport()) {
2199
+ this.storage = cookieStorage;
2200
+ }
2201
+ else {
2202
+ this.log('Cookie storage is not supported, SDK internal cache has been enabled', ConsoleTypes.WARN);
2203
+ this.storage = memoryStorage;
2204
+ }
2205
+ if (localStorage.isSupport()) {
2206
+ this.localStorage = localStorage;
2207
+ }
2208
+ else {
2209
+ this.log('localStorage is not supported, SDK internal cache has been enabled', ConsoleTypes.WARN);
2210
+ }
2211
+ var oldState;
2212
+ oldState = this.storage.get(this.storeName);
2213
+ if (!oldState && this.localStorage) {
2214
+ oldState = this.localStorage.get(this.storeName);
2215
+ }
2216
+ if (oldState && isJSONString(oldState)) {
2217
+ try {
2218
+ oldState = JSON.parse(oldState);
2219
+ this.state = merge(this.state, oldState);
2220
+ }
2221
+ catch (e) {
2222
+ this.log(e, ConsoleTypes.ERROR);
2223
+ }
2224
+ }
2225
+ // 如果不存在hinasdk_crossdata的存储数据,则说明是第一次访问sdk
2226
+ if (oldState) {
2227
+ this.isSetFirstVisit = false;
2228
+ this.save();
2229
+ }
2230
+ else {
2231
+ this.isFirstDay = true;
2232
+ this.isFirstTime = true;
2233
+ var date = new Date();
2234
+ var dateObj = {
2235
+ h: 23 - date.getHours(),
2236
+ m: 59 - date.getMinutes(),
2237
+ s: 59 - date.getSeconds()
2238
+ };
2239
+ var second = dateObj.h * 3600 + dateObj.m * 60 + dateObj.s;
2240
+ // todo 设置这个值似乎没有什么用
2241
+ this.storage.set(IS_NEW_USER_KEY, 'true', second);
2242
+ }
2243
+ // 第一次需要生成匿名ID和设备ID,此时这两个ID是一致的,其中设备ID可以修改,但是匿名ID设置了之后 就不能再改变了
2244
+ var uuid = generatorUUID();
2245
+ if (!this.getAnonymousId()) {
2246
+ this.setAnonymousId(uuid);
2247
+ }
2248
+ if (!this.getDeviceId()) {
2249
+ this.setDeviceId(uuid);
2250
+ }
2251
+ };
2252
+ /**
2253
+ * 清空state数据
2254
+ */
2255
+ State.prototype.clear = function () {
2256
+ this.state = {};
2257
+ this.save();
2258
+ };
2259
+ /**
2260
+ * 缓存state数据
2261
+ */
2262
+ State.prototype.save = function () {
2263
+ // cookie存于子域名中,用于跨站共享
2264
+ this.storage.setDomain(this.storeName, JSON.stringify(this.state));
2265
+ if (this.localStorage) {
2266
+ this.localStorage.set(this.storeName, JSON.stringify(this.state));
2267
+ }
2268
+ };
2269
+ /**
2270
+ * 设置共享数据
2271
+ * @param name
2272
+ * @param value
2273
+ */
2274
+ State.prototype.set = function (name, value) {
2275
+ this.state[name] = value;
2276
+ this.save();
2277
+ };
2278
+ /**
2279
+ * 检查设置值是否合法
2280
+ * @param name
2281
+ * @param value
2282
+ */
2283
+ State.prototype.checkSetValue = function (name, value) {
2284
+ value = value !== null && value !== void 0 ? value : '';
2285
+ if (isNumber(value) || isString(value)) {
2286
+ return true;
2287
+ }
2288
+ this.log("".concat(name, ": id must be string or number"), ConsoleTypes.WARN);
2289
+ return false;
2290
+ };
2291
+ /**
2292
+ * 设置deviceId
2293
+ * @param id
2294
+ */
2295
+ State.prototype.setDeviceId = function (id) {
2296
+ if (id === void 0) { id = ''; }
2297
+ if (this.checkSetValue('deviceId', id)) {
2298
+ this.set('deviceId', id);
2299
+ }
2300
+ };
2301
+ /**
2302
+ * 设置账号id
2303
+ * @param id
2304
+ */
2305
+ State.prototype.setAccountId = function (id) {
2306
+ if (id === void 0) { id = ''; }
2307
+ if (this.checkSetValue('accountId', id)) {
2308
+ this.set('accountId', id);
2309
+ }
2310
+ };
2311
+ /**
2312
+ * 设置匿名id
2313
+ * @param id
2314
+ */
2315
+ State.prototype.setAnonymousId = function (id) {
2316
+ if (this.state.anonymousId) {
2317
+ this.log("Current anonymousId is ".concat(this.getAnonymousId(), ", it has been set"), ConsoleTypes.WARN);
2318
+ return;
2319
+ }
2320
+ if (this.checkSetValue('anonymousId', id)) {
2321
+ this.set('anonymousId', id);
2322
+ }
2323
+ };
2324
+ /**
2325
+ * 设置广告参数
2326
+ * @param props
2327
+ */
2328
+ State.prototype.setProps = function (props) {
2329
+ var newProps = merge(this.state.props || {}, props);
2330
+ for (var key in newProps) {
2331
+ if (typeof newProps[key] === 'string') {
2332
+ newProps[key] = newProps[key].slice(0, MAX_REFERRER_STRING_LENGTH);
2333
+ }
2334
+ }
2335
+ this.set('props', newProps);
2336
+ };
2337
+ /**
2338
+ * 获取匿名ID
2339
+ */
2340
+ State.prototype.getAnonymousId = function () {
2341
+ return this.state.anonymousId;
2342
+ };
2343
+ /**
2344
+ * 获取设备ID
2345
+ */
2346
+ State.prototype.getDeviceId = function () {
2347
+ return this.state.deviceId;
2348
+ };
2349
+ /**
2350
+ * 获取账户ID
2351
+ */
2352
+ State.prototype.getAccountId = function () {
2353
+ return this.state.accountId;
2354
+ };
2355
+ /**
2356
+ * 获取cookie值
2357
+ */
2358
+ State.prototype.getCookie = function () {
2359
+ return this.storage.get(this.storeName);
2360
+ };
2361
+ return State;
2362
+ }());
2363
+
2364
+ var BaseCore = /** @class */ (function () {
2365
+ function BaseCore(options, useInstancing) {
2366
+ if (useInstancing === void 0) { useInstancing = true; }
2367
+ /**
2368
+ * SDK是否已准备就绪
2369
+ */
2370
+ this.isReady = false;
2371
+ /**
2372
+ * 控制台前缀
2373
+ */
2374
+ this.consolePrefix = '';
2375
+ /**
2376
+ * 初始化SDK的方式,默认为true,即通过new的方式初始化SDK,如果使用函数调用初始化SDK,则设置为false
2377
+ */
2378
+ this.useInstancing = true;
2379
+ this.options = options;
2380
+ this.useInstancing = useInstancing;
2381
+ }
2382
+ /**
2383
+ * 打印日志
2384
+ * @param message 日志消息
2385
+ * @param type 日志类型
2386
+ */
2387
+ BaseCore.prototype.log = function (message, type) {
2388
+ if (type === void 0) { type = ConsoleTypes.LOG; }
2389
+ var showLog = this.options.showLog;
2390
+ if (!supportConsole() || !showLog)
2391
+ return;
2392
+ if (typeof message === 'string' && this.consolePrefix) {
2393
+ message = "".concat(this.consolePrefix, "\uFF1A").concat(message);
2394
+ }
2395
+ log(message, type);
2396
+ };
2397
+ /**
2398
+ * 执行插件
2399
+ * @param plugins
2400
+ */
2401
+ BaseCore.prototype.runPlugins = function (plugins) {
2402
+ var _this = this;
2403
+ var _loop_1 = function (i) {
2404
+ var plugin = plugins[i];
2405
+ plugin.init(function (data) {
2406
+ if (!plugin.transform)
2407
+ return;
2408
+ var result = plugin.transform(data);
2409
+ if (!result)
2410
+ return;
2411
+ _this.report(result);
2412
+ });
2413
+ };
2414
+ for (var i = 0; i < plugins.length; i++) {
2415
+ _loop_1(i);
2416
+ }
2417
+ };
2418
+ return BaseCore;
2419
+ }());
2420
+
2421
+ var GET_DEFAULT_OPTIONS = function () {
2422
+ return {
2423
+ name: '',
2424
+ serverUrl: '',
2425
+ showLog: false,
2426
+ autoTrackConfig: {
2427
+ clickAutoTrack: true,
2428
+ stayAutoTrack: true,
2429
+ isCollectUrl: function () { return true; },
2430
+ isCollectElement: function () { return true; },
2431
+ isCollectInput: function () { return false; },
2432
+ addCustomProperty: function () { },
2433
+ stayDelayTime: 4000,
2434
+ maxStayPageDuration: 18000,
2435
+ collectTags: {
2436
+ div: false
2437
+ },
2438
+ trackAttr: ['hn-click'],
2439
+ pageviewAutoTrack: false,
2440
+ pageLeaveAutoTrack: false
2441
+ },
2442
+ stayAutoTrackConfig: {
2443
+ isCollectUrl: function () { return true; }
2444
+ },
2445
+ imgUseCrossOrigin: false,
2446
+ isSinglePage: false,
2447
+ batchSend: false,
2448
+ appJsBridge: false,
2449
+ sendType: ReportType.IMAGE,
2450
+ dataSendTimeout: 3000,
2451
+ presetProperties: {
2452
+ latest_utm: true,
2453
+ latest_utm_source: true,
2454
+ latest_traffic_source_type: true,
2455
+ latest_search_keyword: true,
2456
+ latest_referrer: true,
2457
+ url: true,
2458
+ title: true
2459
+ }
2460
+ };
2461
+ };
2462
+ var ignoreTags = [
2463
+ 'mark',
2464
+ '/mark',
2465
+ 'strong',
2466
+ 'b',
2467
+ 'em',
2468
+ 'i',
2469
+ 'u',
2470
+ 'abbr',
2471
+ 'ins',
2472
+ 'del',
2473
+ 's',
2474
+ 'sup'
2475
+ ];
2476
+ var defaultTags = ['a', 'input', 'button', 'textarea'];
2477
+
2478
+ /**
2479
+ * @description 批量发送数据
2480
+ */
2481
+ var BatchSend = /** @class */ (function () {
2482
+ function BatchSend(context) {
2483
+ this.context = context;
2484
+ this.batchKey = 'hinasdk_tab';
2485
+ this.batchDataKey = 'hinasdk_data_';
2486
+ this.batchInterval();
2487
+ }
2488
+ BatchSend.prototype.getBatchConfig = function () {
2489
+ var batchSend = this.context.options.batchSend;
2490
+ return batchSend;
2491
+ };
2492
+ BatchSend.prototype.getStorageList = function () {
2493
+ var _a;
2494
+ var list = [];
2495
+ var tabStorage = (_a = this.context.store.localStorage) === null || _a === void 0 ? void 0 : _a.get(this.batchKey);
2496
+ if (tabStorage) {
2497
+ list = safeJSONParse(tabStorage);
2498
+ if (!isArray(list)) {
2499
+ list = [];
2500
+ }
2501
+ }
2502
+ return list;
2503
+ };
2504
+ BatchSend.prototype.batchInterval = function () {
2505
+ var _this = this;
2506
+ var sendInterval = this.getBatchConfig().sendInterval;
2507
+ setTimeout(function () {
2508
+ _this.send().then(function () {
2509
+ _this.batchInterval();
2510
+ });
2511
+ }, sendInterval);
2512
+ };
2513
+ BatchSend.prototype.send = function () {
2514
+ var _this = this;
2515
+ return new Promise(function (resolve) {
2516
+ var _a;
2517
+ var tabStorageList = _this.getStorageList();
2518
+ if (tabStorageList.length > 0) {
2519
+ var _b = _this.getBatchConfig(), storageLimit = _b.storageLimit, dataSendTimeout = _b.dataSendTimeout;
2520
+ var now = nowStamp();
2521
+ var list = [];
2522
+ var removeKeys_1 = [];
2523
+ var len = tabStorageList.length;
2524
+ for (var i = 0; i < len; i++) {
2525
+ var _c = tabStorageList[i], dataKey = _c.dataKey, expireTime = _c.expireTime;
2526
+ removeKeys_1.push(dataKey);
2527
+ if (expireTime >= now) {
2528
+ var data = (_a = _this.context.store.localStorage) === null || _a === void 0 ? void 0 : _a.get(dataKey);
2529
+ if (data) {
2530
+ list.push(safeJSONParse(data));
2531
+ }
2532
+ }
2533
+ }
2534
+ list = list.filter(Boolean);
2535
+ if (list.length > storageLimit) {
2536
+ list = list.slice(0, storageLimit);
2537
+ }
2538
+ if (list.length === 0) {
2539
+ resolve();
2540
+ }
2541
+ else {
2542
+ var serverUrl = _this.context.options.serverUrl;
2543
+ var listStr = JSON.stringify(list);
2544
+ new AjaxRequest({
2545
+ url: serverUrl,
2546
+ data: "data_list=".concat(base64Encode(listStr)),
2547
+ timeout: dataSendTimeout
2548
+ })
2549
+ .run()
2550
+ .then(function (res) {
2551
+ if (res.type === 'success') {
2552
+ _this.remove(removeKeys_1);
2553
+ }
2554
+ resolve();
2555
+ });
2556
+ }
2557
+ }
2558
+ });
2559
+ };
2560
+ BatchSend.prototype.remove = function (removeKeys) {
2561
+ var _this = this;
2562
+ var _a;
2563
+ var firstKey = removeKeys[0];
2564
+ var tabStorageList = this.getStorageList();
2565
+ // 删除hinasdk_data_开头的数据
2566
+ removeKeys.forEach(function (key) {
2567
+ var _a;
2568
+ (_a = _this.context.store.localStorage) === null || _a === void 0 ? void 0 : _a.remove(key);
2569
+ });
2570
+ // 删除hinasdk_tab数据
2571
+ var index = tabStorageList.findIndex(function (item) { return item.dataKey === firstKey; });
2572
+ if (index >= 0) {
2573
+ var list = tabStorageList.slice(0, index);
2574
+ (_a = this.context.store.localStorage) === null || _a === void 0 ? void 0 : _a.set(this.batchKey, JSON.stringify(list));
2575
+ }
2576
+ };
2577
+ BatchSend.prototype.add = function (data) {
2578
+ var _a, _b;
2579
+ var _c = this.getBatchConfig(), sendInterval = _c.sendInterval, storageLimit = _c.storageLimit;
2580
+ var dataKey = this.batchDataKey + getRandom();
2581
+ var tabStorage = this.getStorageList();
2582
+ tabStorage.unshift({
2583
+ dataKey: dataKey,
2584
+ expireTime: nowStamp() + sendInterval * 2
2585
+ });
2586
+ (_a = this.context.store.localStorage) === null || _a === void 0 ? void 0 : _a.set(this.batchKey, JSON.stringify(tabStorage));
2587
+ (_b = this.context.store.localStorage) === null || _b === void 0 ? void 0 : _b.set(dataKey, JSON.stringify(data));
2588
+ /**
2589
+ * 满足以下条件,则发送数据
2590
+ * 1. localStorage 条数超过最大限制
2591
+ * 2. 发送类型为 track_signup 或 H_pageview
2592
+ */
2593
+ if (tabStorage.length > storageLimit ||
2594
+ data.type === 'track_signup' ||
2595
+ data.event === 'H_pageview') {
2596
+ this.send();
2597
+ }
2598
+ };
2599
+ return BatchSend;
2600
+ }());
2601
+
2602
+ var ClickTrackPlugin = /** @class */ (function (_super) {
2603
+ __extends(ClickTrackPlugin, _super);
2604
+ function ClickTrackPlugin(options, context) {
2605
+ var _this = _super.call(this, options, context) || this;
2606
+ _this.options = options;
2607
+ _this.context = context;
2608
+ /**
2609
+ * 插件名
2610
+ */
2611
+ _this.name = 'ClickTrackPlugin';
2612
+ /**
2613
+ * 默认采集标签
2614
+ */
2615
+ _this.isTrackList = {
2616
+ a: true,
2617
+ button: true
2618
+ };
2619
+ return _this;
2620
+ }
2621
+ ClickTrackPlugin.prototype.init = function (notify) {
2622
+ var _this = this;
2623
+ var _a = this.options.autoTrackConfig, clickAutoTrack = _a.clickAutoTrack, isCollectUrl = _a.isCollectUrl, isCollectElement = _a.isCollectElement, addCustomProperty = _a.addCustomProperty;
2624
+ if (clickAutoTrack !== true)
2625
+ return;
2626
+ document.addEventListener('click', function (e) {
2627
+ if (!isCollectUrl())
2628
+ return;
2629
+ var event = e || window.event;
2630
+ if (!event)
2631
+ return;
2632
+ var eventTarget = event.target || event.srcElement;
2633
+ var target = _this.getTargetElement(eventTarget, event);
2634
+ if (target) {
2635
+ // 判断是否要上报此元素的点击事件
2636
+ if (isFunction(isCollectElement) && !isCollectElement(target)) {
2637
+ return false;
2638
+ }
2639
+ var props = _this.getClickElementInfo(target);
2640
+ var _a = _this.getPageXYInfo(event, target), H_page_x = _a.H_page_x, H_page_y = _a.H_page_y;
2641
+ props.H_page_x = H_page_x;
2642
+ props.H_page_y = H_page_y;
2643
+ if (isFunction(addCustomProperty)) {
2644
+ var customProperty = addCustomProperty(target);
2645
+ if (isObject(customProperty)) {
2646
+ props = merge(props, customProperty);
2647
+ }
2648
+ }
2649
+ notify(props);
2650
+ }
2651
+ }, true);
2652
+ };
2653
+ ClickTrackPlugin.prototype.transform = function (data) {
2654
+ var props = this.context.getReportData('track', 'H_WebClick', data);
2655
+ return props;
2656
+ };
2657
+ ClickTrackPlugin.prototype.hasAttribute = function (element, attrName) {
2658
+ var _a;
2659
+ if (element.hasAttribute) {
2660
+ return element.hasAttribute(attrName);
2661
+ }
2662
+ if (element.attributes) {
2663
+ return !!((_a = element.attributes[attrName]) === null || _a === void 0 ? void 0 : _a.value);
2664
+ }
2665
+ };
2666
+ ClickTrackPlugin.prototype.hasAttributes = function (element, attrNames) {
2667
+ if (isArray(attrNames)) {
2668
+ for (var i = 0; i < attrNames.length; i++) {
2669
+ if (this.hasAttribute(element, attrNames[i])) {
2670
+ return true;
2671
+ }
2672
+ }
2673
+ }
2674
+ return false;
2675
+ };
2676
+ ClickTrackPlugin.prototype.hasElement = function (element) {
2677
+ var e_1, _a;
2678
+ var _b;
2679
+ var paths = getElementParents(element);
2680
+ var trackAttr = this.options.autoTrackConfig.trackAttr || [];
2681
+ if (isArray(paths) && paths.length > 0) {
2682
+ try {
2683
+ for (var paths_1 = __values(paths), paths_1_1 = paths_1.next(); !paths_1_1.done; paths_1_1 = paths_1.next()) {
2684
+ var path = paths_1_1.value;
2685
+ var tagName = (_b = path.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
2686
+ if (isElement(path) &&
2687
+ (this.isTrackList[tagName] || this.hasAttributes(path, trackAttr))) {
2688
+ return path;
2689
+ }
2690
+ }
2691
+ }
2692
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2693
+ finally {
2694
+ try {
2695
+ if (paths_1_1 && !paths_1_1.done && (_a = paths_1.return)) _a.call(paths_1);
2696
+ }
2697
+ finally { if (e_1) throw e_1.error; }
2698
+ }
2699
+ }
2700
+ };
2701
+ ClickTrackPlugin.prototype.getDivMaxLevel = function () {
2702
+ var _a;
2703
+ var collectTags = this.options.autoTrackConfig.collectTags;
2704
+ return ((_a = collectTags.div) === null || _a === void 0 ? void 0 : _a.maxLevel) || 1;
2705
+ };
2706
+ /**
2707
+ * 针对div标签,判断是否是忽略的样式标签
2708
+ * @param tagName
2709
+ */
2710
+ ClickTrackPlugin.prototype.isStyleTag = function (tagName) {
2711
+ var _a;
2712
+ var collectTags = this.options.autoTrackConfig.collectTags;
2713
+ var ignoreTags = ((_a = collectTags.div) === null || _a === void 0 ? void 0 : _a.ignoreTags) || [];
2714
+ return ignoreTags === null || ignoreTags === void 0 ? void 0 : ignoreTags.includes(tagName);
2715
+ };
2716
+ /**
2717
+ * 获取可采集元素的父元素
2718
+ * @param target
2719
+ */
2720
+ ClickTrackPlugin.prototype.getCollectableParent = function (target) {
2721
+ var _a;
2722
+ try {
2723
+ var parentNode = target.parentNode;
2724
+ var parentTagName = parentNode ? (_a = parentNode.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase() : '';
2725
+ if (parentTagName === 'body') {
2726
+ return false;
2727
+ }
2728
+ var maxLevel = this.getDivMaxLevel();
2729
+ if (parentTagName === 'div' &&
2730
+ (maxLevel > 1 || this.isCollectableDiv(parentNode))) {
2731
+ return parentNode;
2732
+ }
2733
+ if (parentNode && this.isStyleTag(parentTagName)) {
2734
+ return this.getCollectableParent(parentNode);
2735
+ }
2736
+ }
2737
+ catch (error) {
2738
+ this.context.log(error, ConsoleTypes.ERROR);
2739
+ }
2740
+ return false;
2741
+ };
2742
+ /**
2743
+ * 是否是可以收集的div
2744
+ * @param element
2745
+ */
2746
+ ClickTrackPlugin.prototype.isCollectableDiv = function (element) {
2747
+ var _a;
2748
+ try {
2749
+ var children = element.children || [];
2750
+ if (children.length === 0) {
2751
+ return true;
2752
+ }
2753
+ for (var i = 0; i < children.length; i++) {
2754
+ var child = children[i];
2755
+ if (isElement(child)) {
2756
+ var tagName = (_a = child.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
2757
+ var maxLevel = this.getDivMaxLevel();
2758
+ if ((tagName === 'div' && maxLevel > 1) || this.isStyleTag(tagName)) {
2759
+ if (!this.isCollectableDiv(child)) {
2760
+ return false;
2761
+ }
2762
+ }
2763
+ else {
2764
+ return false;
2765
+ }
2766
+ }
2767
+ }
2768
+ return true;
2769
+ }
2770
+ catch (error) {
2771
+ this.context.log(error, ConsoleTypes.ERROR);
2772
+ }
2773
+ return false;
2774
+ };
2775
+ /**
2776
+ * 判断div的层级是否有效
2777
+ * @param rootElement
2778
+ */
2779
+ ClickTrackPlugin.prototype.isDivLevelValid = function (rootElement) {
2780
+ var maxLevel = this.getDivMaxLevel();
2781
+ var htmlCollection = rootElement.getElementsByTagName('div');
2782
+ for (var i = htmlCollection.length - 1; i >= 0; i--) {
2783
+ if (this.getDivLevels(htmlCollection[i], rootElement) > maxLevel) {
2784
+ return false;
2785
+ }
2786
+ }
2787
+ return true;
2788
+ };
2789
+ /**
2790
+ * 获取指定元素的路径
2791
+ * @param element 当前元素
2792
+ * @param ignoreId 是否忽略id
2793
+ * @param rootElement 根元素
2794
+ */
2795
+ ClickTrackPlugin.prototype.getElementPath = function (element, ignoreId, rootElement) {
2796
+ var _a, _b;
2797
+ var names = [];
2798
+ while (isElement(element) && element.parentNode) {
2799
+ if (element.id &&
2800
+ !ignoreId &&
2801
+ /^[A-Za-z][-A-Za-z0-9_:.]*$/.test(element.id)) {
2802
+ var tagName = element.tagName || '';
2803
+ names.unshift("".concat(tagName.toLowerCase(), "#").concat(element.id));
2804
+ break;
2805
+ }
2806
+ else {
2807
+ if (rootElement && element === rootElement) {
2808
+ names.unshift((_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase());
2809
+ break;
2810
+ }
2811
+ else if (element === document.body) {
2812
+ names.unshift('body');
2813
+ break;
2814
+ }
2815
+ else {
2816
+ names.unshift((_b = element.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase());
2817
+ }
2818
+ element = element.parentNode;
2819
+ }
2820
+ }
2821
+ return names.join(' > ');
2822
+ };
2823
+ ClickTrackPlugin.prototype.getDivLevels = function (element, rootElement) {
2824
+ var path = this.getElementPath(element, true, rootElement);
2825
+ var pathArr = path.split(' > ');
2826
+ var level = 0;
2827
+ pathArr.forEach(function (tag) {
2828
+ if (tag === 'div') {
2829
+ level++;
2830
+ }
2831
+ });
2832
+ return level;
2833
+ };
2834
+ ClickTrackPlugin.prototype.getTargetElement = function (eventTarget, event) {
2835
+ var _a;
2836
+ if (!isElement(eventTarget)) {
2837
+ return null;
2838
+ }
2839
+ var tagName = (_a = eventTarget.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
2840
+ if (!isString(tagName)) {
2841
+ return null;
2842
+ }
2843
+ if (['body', 'html'].includes(tagName)) {
2844
+ return null;
2845
+ }
2846
+ if (this.context.trackTags.includes(tagName) && tagName !== 'div') {
2847
+ return eventTarget;
2848
+ }
2849
+ /**
2850
+ * div处理情况
2851
+ * 1.div为子结点(无子元素)时采集 div 的点击;
2852
+ * 2.div中有且只有样式标签([‘mark’,’strong’,’b’,’em’,’i’,’u’,’abbr’,’ins’,’del’,’s’,’sup’])时,点击 div 或者样式标签都采集 div 的点击。
2853
+ * 3.div 通过配置最多可以采集3层嵌套情况
2854
+ */
2855
+ if (tagName === 'div') {
2856
+ if (this.isDivLevelValid(eventTarget)) {
2857
+ var maxLevel = this.getDivMaxLevel();
2858
+ if (maxLevel > 1 || this.isCollectableDiv(eventTarget)) {
2859
+ return eventTarget;
2860
+ }
2861
+ }
2862
+ }
2863
+ if (this.isStyleTag(tagName) &&
2864
+ this.options.autoTrackConfig.collectTags.div) {
2865
+ var parentTrackDiv = this.getCollectableParent(eventTarget);
2866
+ if (parentTrackDiv && this.isDivLevelValid(parentTrackDiv)) {
2867
+ return parentTrackDiv;
2868
+ }
2869
+ }
2870
+ return this.hasElement(eventTarget) || null;
2871
+ };
2872
+ ClickTrackPlugin.prototype.getPageXYInfo = function (event, target) {
2873
+ if (!event) {
2874
+ return {};
2875
+ }
2876
+ var scrollLeft = getScrollLeft();
2877
+ var scrollTop = getScrollTop();
2878
+ var rect = target.getBoundingClientRect();
2879
+ var pageX = event.pageX ||
2880
+ event.clientX + scrollLeft ||
2881
+ event.offsetX + ((rect === null || rect === void 0 ? void 0 : rect.left) || 0) + scrollLeft;
2882
+ var pageY = event.pageY ||
2883
+ event.clientY + scrollTop ||
2884
+ event.offsetY + ((rect === null || rect === void 0 ? void 0 : rect.top) || 0) + scrollTop;
2885
+ return {
2886
+ H_page_x: formatDecimal(pageX, 3),
2887
+ H_page_y: formatDecimal(pageY, 3)
2888
+ };
2889
+ };
2890
+ ClickTrackPlugin.prototype.getClickElementInfo = function (element) {
2891
+ var isCollectInput = this.options.autoTrackConfig.isCollectInput;
2892
+ var isCollectInputValue = false;
2893
+ if (isFunction(isCollectInput)) {
2894
+ isCollectInputValue = isCollectInput(element);
2895
+ }
2896
+ var selector = this.getDomSelector(element);
2897
+ var props = getElementProperties(element, isCollectInputValue);
2898
+ props.H_element_selector = selector;
2899
+ props.H_element_path = this.getElementPath(element, false);
2900
+ return props;
2901
+ };
2902
+ ClickTrackPlugin.prototype.getDomSelector = function (element) {
2903
+ var _a;
2904
+ var paths = [];
2905
+ while (element) {
2906
+ var tagName = (_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
2907
+ if (tagName === 'body' || !isElement(element)) {
2908
+ paths.unshift('body');
2909
+ break;
2910
+ }
2911
+ paths.unshift(this.getSelector(element));
2912
+ if ((element === null || element === void 0 ? void 0 : element.getAttribute('id')) &&
2913
+ /^[A-Za-z][-A-Za-z0-9_:.]*$/.test(element.getAttribute('id'))) {
2914
+ break;
2915
+ }
2916
+ element = element.parentNode;
2917
+ }
2918
+ return paths.join(' > ');
2919
+ };
2920
+ ClickTrackPlugin.prototype.getSelector = function (element) {
2921
+ var _a, _b;
2922
+ var tagName = (_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
2923
+ var i = -1;
2924
+ if (((_b = element.parentNode) === null || _b === void 0 ? void 0 : _b.nodeType) !== 9) {
2925
+ i = this.getDomIndex(element);
2926
+ }
2927
+ var idValue = element.getAttribute('id');
2928
+ if (idValue && /^[A-Za-z][-A-Za-z0-9_:.]*$/.test(idValue)) {
2929
+ return "#".concat(idValue);
2930
+ }
2931
+ return tagName + (i > -1 ? ":nth-of-type(".concat(i + 1, ")") : '');
2932
+ };
2933
+ ClickTrackPlugin.prototype.getDomIndex = function (element) {
2934
+ var _a, _b;
2935
+ if (element.parentNode) {
2936
+ var index = 0;
2937
+ var tagName = (_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
2938
+ var children = element.parentNode.children;
2939
+ for (var i = 0; i < children.length; i++) {
2940
+ var child = children[i];
2941
+ var childTagName = (_b = child.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
2942
+ if (childTagName === tagName) {
2943
+ if (child === element) {
2944
+ return index;
2945
+ }
2946
+ index++;
2947
+ }
2948
+ }
2949
+ }
2950
+ return -1;
2951
+ };
2952
+ return ClickTrackPlugin;
2953
+ }(PluginBase));
2954
+
2955
+ var StayTrackPlugin = /** @class */ (function (_super) {
2956
+ __extends(StayTrackPlugin, _super);
2957
+ function StayTrackPlugin(options, context) {
2958
+ var _this = _super.call(this, options, context) || this;
2959
+ _this.options = options;
2960
+ _this.context = context;
2961
+ _this.name = 'StayTrackPlugin';
2962
+ _this.timer = null;
2963
+ _this.previousTime = nowStamp();
2964
+ _this.previousOffsetTop = 0;
2965
+ return _this;
2966
+ }
2967
+ StayTrackPlugin.prototype.init = function (notify) {
2968
+ var _this = this;
2969
+ var _a = this.options, autoTrackConfig = _a.autoTrackConfig, stayAutoTrackConfig = _a.stayAutoTrackConfig;
2970
+ if (autoTrackConfig.stayAutoTrack !== true) {
2971
+ return;
2972
+ }
2973
+ var isCollectUrl = stayAutoTrackConfig.isCollectUrl;
2974
+ if (!isFunction(isCollectUrl)) {
2975
+ isCollectUrl = function () { return true; };
2976
+ }
2977
+ if (this.timer) {
2978
+ clearTimeout(this.timer);
2979
+ this.timer = null;
2980
+ }
2981
+ this.previousTime = nowStamp();
2982
+ window.addEventListener('load', function () {
2983
+ _this.previousOffsetTop = getScrollTop();
2984
+ });
2985
+ window.addEventListener('scroll', function () {
2986
+ if (!isCollectUrl())
2987
+ return;
2988
+ if (_this.timer)
2989
+ return;
2990
+ _this.timer = setTimeout(function () {
2991
+ _this.run(notify);
2992
+ clearTimeout(_this.timer);
2993
+ _this.timer = null;
2994
+ }, 1000);
2995
+ });
2996
+ window.addEventListener('unload', function () {
2997
+ if (!isCollectUrl())
2998
+ return;
2999
+ _this.run(notify, true);
3000
+ });
3001
+ };
3002
+ StayTrackPlugin.prototype.transform = function (data) {
3003
+ var props = this.context.getReportData('track', 'H_WebStay', data);
3004
+ return props;
3005
+ };
3006
+ StayTrackPlugin.prototype.run = function (notify, isClosePage) {
3007
+ if (isClosePage === void 0) { isClosePage = false; }
3008
+ var autoTrackConfig = this.options.autoTrackConfig;
3009
+ var stayDelayTime = autoTrackConfig.stayDelayTime, maxStayPageDuration = autoTrackConfig.maxStayPageDuration;
3010
+ var offsetTop = getScrollTop();
3011
+ var nowTime = nowStamp();
3012
+ var duration = nowTime - this.previousTime;
3013
+ if (isClosePage ||
3014
+ (duration > stayDelayTime && offsetTop !== this.previousOffsetTop)) {
3015
+ var props = {
3016
+ H_viewport_position: this.previousOffsetTop,
3017
+ event_duration: Math.min(duration / 1000, maxStayPageDuration)
3018
+ };
3019
+ notify(props);
3020
+ }
3021
+ this.previousTime = nowTime;
3022
+ this.previousOffsetTop = offsetTop;
3023
+ };
3024
+ return StayTrackPlugin;
3025
+ }(PluginBase));
3026
+
3027
+ var PageLeavePluginName = 'PageLeavePlugin';
3028
+ var PageLeavePlugin = /** @class */ (function (_super) {
3029
+ __extends(PageLeavePlugin, _super);
3030
+ function PageLeavePlugin(options, context) {
3031
+ var _this = _super.call(this, options, context) || this;
3032
+ _this.options = options;
3033
+ _this.context = context;
3034
+ _this.name = PageLeavePluginName;
3035
+ _this.pageId = Number(String(getRandom()).slice(2, 5) +
3036
+ String(getRandom()).slice(2, 4) +
3037
+ String(nowStamp()).slice(-4));
3038
+ _this.storageName = 'hinasdk_pageleave_';
3039
+ _this.heartbeatIntervalTime = 5000; // 5s
3040
+ _this.maxDuration = 432000; // 5天
3041
+ _this.heartbeatIntervalTimer = null;
3042
+ _this.startTime = nowStamp();
3043
+ /**
3044
+ * 页面url
3045
+ */
3046
+ _this.url = window.location.href;
3047
+ /**
3048
+ * 上一个页面url
3049
+ */
3050
+ _this.previousUrl = document.referrer;
3051
+ /**
3052
+ * 页面显示状态
3053
+ */
3054
+ _this.pageShowStatus = true;
3055
+ return _this;
3056
+ }
3057
+ PageLeavePlugin.prototype.init = function () {
3058
+ var pageLeaveAutoTrack = this.options.autoTrackConfig.pageLeaveAutoTrack;
3059
+ if (!pageLeaveAutoTrack)
3060
+ return;
3061
+ var _a = this.normalizePageLeaveAutoTrack(), heartbeat_interval_time = _a.heartbeat_interval_time, max_duration = _a.max_duration;
3062
+ if (heartbeat_interval_time && heartbeat_interval_time > 0) {
3063
+ this.heartbeatIntervalTime = heartbeat_interval_time * 1000;
3064
+ }
3065
+ if (max_duration && max_duration > 0) {
3066
+ this.maxDuration = Number(max_duration);
3067
+ }
3068
+ this.startTime = nowStamp();
3069
+ this.addPageLeaveEventListener();
3070
+ if (document.hidden) {
3071
+ this.pageShowStatus = false;
3072
+ }
3073
+ else {
3074
+ this.addHeartBeatInterval();
3075
+ }
3076
+ };
3077
+ PageLeavePlugin.prototype.transform = function (data) {
3078
+ return undefined;
3079
+ };
3080
+ PageLeavePlugin.prototype.normalizePageLeaveAutoTrack = function () {
3081
+ var pageLeaveAutoTrack = this.options.autoTrackConfig.pageLeaveAutoTrack;
3082
+ return isObject(pageLeaveAutoTrack)
3083
+ ? pageLeaveAutoTrack
3084
+ : {};
3085
+ };
3086
+ PageLeavePlugin.prototype.addPageLeaveEventListener = function () {
3087
+ this.addPageStartListener();
3088
+ this.addPageSwitchListener();
3089
+ this.addSinglePageListener();
3090
+ this.addPageEndListener();
3091
+ };
3092
+ PageLeavePlugin.prototype.addPageStartListener = function () {
3093
+ var _this = this;
3094
+ if ('onpageshow' in window) {
3095
+ window.addEventListener('pageshow', function () {
3096
+ _this.pageStartHandler();
3097
+ });
3098
+ }
3099
+ };
3100
+ PageLeavePlugin.prototype.addPageSwitchListener = function () {
3101
+ var _this = this;
3102
+ new ListenPageState({
3103
+ visible: function () {
3104
+ _this.pageStartHandler();
3105
+ _this.addHeartBeatInterval();
3106
+ },
3107
+ hidden: function () {
3108
+ _this.url = window.location.href;
3109
+ _this.pageEndHandler();
3110
+ _this.stopHeartBeatInterval();
3111
+ }
3112
+ });
3113
+ };
3114
+ PageLeavePlugin.prototype.addSinglePageListener = function () {
3115
+ var _this = this;
3116
+ mitt.on('urlChange', function (params) {
3117
+ var fromHref = params.fromHref;
3118
+ if (fromHref !== window.location.href) {
3119
+ _this.url = fromHref;
3120
+ _this.pageEndHandler();
3121
+ _this.stopHeartBeatInterval();
3122
+ _this.pageStartHandler();
3123
+ _this.addHeartBeatInterval();
3124
+ }
3125
+ });
3126
+ };
3127
+ PageLeavePlugin.prototype.addPageEndListener = function () {
3128
+ var _this = this;
3129
+ var events = ['pagehide', 'beforeunload', 'unload'];
3130
+ events.forEach(function (event) {
3131
+ if ("on".concat(events) in window) {
3132
+ window.addEventListener(event, function () {
3133
+ _this.pageEndHandler();
3134
+ _this.stopHeartBeatInterval();
3135
+ });
3136
+ }
3137
+ });
3138
+ };
3139
+ PageLeavePlugin.prototype.pageStartHandler = function () {
3140
+ this.startTime = nowStamp();
3141
+ this.pageShowStatus = !document.hidden;
3142
+ this.url = window.location.href;
3143
+ };
3144
+ PageLeavePlugin.prototype.pageEndHandler = function () {
3145
+ if (!this.pageShowStatus)
3146
+ return;
3147
+ this.pageShowStatus = false;
3148
+ if (this.isCollectUrl()) {
3149
+ var properties = this.getPageLeaveProperties();
3150
+ var data = this.context.getReportData('track', 'H_WebPageLeave', properties);
3151
+ this.context.report(data);
3152
+ }
3153
+ this.delHeartBeatData();
3154
+ };
3155
+ PageLeavePlugin.prototype.addHeartBeatInterval = function () {
3156
+ if (!this.context.store.localStorage)
3157
+ return;
3158
+ this.startHeartBeatInterval();
3159
+ };
3160
+ PageLeavePlugin.prototype.startHeartBeatInterval = function () {
3161
+ var _this = this;
3162
+ if (this.heartbeatIntervalTimer) {
3163
+ this.stopHeartBeatInterval();
3164
+ }
3165
+ if (this.isCollectUrl()) {
3166
+ this.heartbeatIntervalTimer = setInterval(function () {
3167
+ _this.saveHeartBeatData();
3168
+ }, this.heartbeatIntervalTime);
3169
+ this.saveHeartBeatData('first_heartbeat');
3170
+ }
3171
+ this.reissueHeartBeatData();
3172
+ };
3173
+ PageLeavePlugin.prototype.reissueHeartBeatData = function () {
3174
+ var localStorage = this.context.store.localStorage;
3175
+ var storageLen = localStorage.length();
3176
+ for (var i = 0; i < storageLen; i++) {
3177
+ var itemKey = localStorage.key(i);
3178
+ if (itemKey &&
3179
+ itemKey !== this.storageName + this.pageId &&
3180
+ itemKey.includes(this.storageName)) {
3181
+ var value = localStorage.get(itemKey);
3182
+ var result = safeJSONParse(value);
3183
+ if (isObject(result) &&
3184
+ nowStamp() - result.time > result.heartbeat_interval_time + 5000) {
3185
+ delete result.heartbeat_interval_time;
3186
+ this.context.report(result);
3187
+ }
3188
+ this.delHeartBeatData(itemKey);
3189
+ }
3190
+ }
3191
+ };
3192
+ PageLeavePlugin.prototype.stopHeartBeatInterval = function () {
3193
+ if (this.heartbeatIntervalTimer) {
3194
+ clearInterval(this.heartbeatIntervalTimer);
3195
+ this.heartbeatIntervalTimer = null;
3196
+ }
3197
+ };
3198
+ PageLeavePlugin.prototype.delHeartBeatData = function (storageKey) {
3199
+ if (this.context.store.localStorage) {
3200
+ this.context.store.localStorage.remove(storageKey || this.storageName + this.pageId);
3201
+ }
3202
+ };
3203
+ PageLeavePlugin.prototype.isCollectUrl = function () {
3204
+ var isCollectUrl = this.normalizePageLeaveAutoTrack().isCollectUrl;
3205
+ if (isFunction(isCollectUrl)) {
3206
+ return isCollectUrl(this.url);
3207
+ }
3208
+ return true;
3209
+ };
3210
+ PageLeavePlugin.prototype.saveHeartBeatData = function (type) {
3211
+ var properties = this.getPageLeaveProperties();
3212
+ properties.H_time = nowStamp();
3213
+ if (type === 'first_heartbeat') {
3214
+ properties.event_duration = 3;
3215
+ }
3216
+ var props = this.context.getReportData('track', 'H_WebPageLeave', properties);
3217
+ props.heartbeat_interval_time = this.heartbeatIntervalTime;
3218
+ this.context.store.localStorage.set(this.storageName + this.pageId, JSON.stringify(props));
3219
+ };
3220
+ PageLeavePlugin.prototype.getPageLeaveProperties = function () {
3221
+ var duration = (nowStamp() - this.startTime) / 1000;
3222
+ if (duration <= 0 || duration > this.maxDuration) {
3223
+ duration = 0;
3224
+ }
3225
+ else {
3226
+ duration = formatDecimal(duration, 3);
3227
+ }
3228
+ var _a = getURL(this.url), pathname = _a.pathname, hash = _a.hash;
3229
+ var referrer = getReferrer(this.previousUrl);
3230
+ var properties = {
3231
+ H_url: this.url,
3232
+ H_url_path: pathname,
3233
+ H_url_hash: hash,
3234
+ H_referrer: referrer,
3235
+ H_referrer_host: referrer ? getHostname(referrer) : ''
3236
+ };
3237
+ if (duration) {
3238
+ properties.event_duration = duration;
3239
+ }
3240
+ var custom_props = this.normalizePageLeaveAutoTrack().custom_props;
3241
+ if (isObject(custom_props)) {
3242
+ properties = __assign(__assign({}, properties), (custom_props || {}));
3243
+ }
3244
+ return properties;
3245
+ };
3246
+ return PageLeavePlugin;
3247
+ }(PluginBase));
3248
+
3249
+ var SiteLinkerPluginName = 'SiteLinkerPlugin';
3250
+ var SiteLinkerPlugin = /** @class */ (function (_super) {
3251
+ __extends(SiteLinkerPlugin, _super);
3252
+ function SiteLinkerPlugin(options, context) {
3253
+ var _this = _super.call(this, options, context) || this;
3254
+ _this.options = options;
3255
+ _this.context = context;
3256
+ _this.name = SiteLinkerPluginName;
3257
+ _this.linker = [];
3258
+ return _this;
3259
+ }
3260
+ SiteLinkerPlugin.prototype.init = function () {
3261
+ var linker = this.getLinkerConfig().linker;
3262
+ if (!(isArray(linker) && linker.length > 0)) {
3263
+ this.context.log('siteLinker plugin: Please configure the linker parameter', ConsoleTypes.WARN);
3264
+ return;
3265
+ }
3266
+ // 处理配置
3267
+ this.resolveOption();
3268
+ this.setRefferId();
3269
+ this.addClickListen();
3270
+ };
3271
+ SiteLinkerPlugin.prototype.transform = function () {
3272
+ return undefined;
3273
+ };
3274
+ SiteLinkerPlugin.prototype.getLinkerConfig = function () {
3275
+ var _a = this.options.siteLinkerConfig || {}, _b = _a.linker, linker = _b === void 0 ? [] : _b, re_login = _a.re_login;
3276
+ return {
3277
+ linker: linker || [],
3278
+ re_login: re_login
3279
+ };
3280
+ };
3281
+ SiteLinkerPlugin.prototype.resolveOption = function () {
3282
+ var linker = this.getLinkerConfig().linker;
3283
+ var len = linker.length;
3284
+ var arr = [];
3285
+ for (var i = 0; i < len; i++) {
3286
+ var _a = linker[i], part_url = _a.part_url, after_hash = _a.after_hash;
3287
+ if (/[A-Za-z0-9]+\./.test(part_url) && isBoolean(after_hash)) {
3288
+ arr.push({
3289
+ part_url: part_url,
3290
+ after_hash: after_hash
3291
+ });
3292
+ }
3293
+ else {
3294
+ this.context.log("The configuration of linker ".concat(i + 1, " is not supported.Please check format"), ConsoleTypes.WARN);
3295
+ }
3296
+ }
3297
+ this.linker = arr;
3298
+ };
3299
+ /**
3300
+ * 多域名打通设置
3301
+ */
3302
+ SiteLinkerPlugin.prototype.setRefferId = function () {
3303
+ var re_login = this.getLinkerConfig().re_login;
3304
+ var urlId = this.getUrlId();
3305
+ var isAnonymousId = urlId.startsWith('a');
3306
+ urlId = urlId.substring(1);
3307
+ if (urlId === '')
3308
+ return;
3309
+ var anonymousId = this.context.store.getAnonymousId();
3310
+ var accountId = this.context.store.getAccountId();
3311
+ if (isAnonymousId) {
3312
+ if (urlId !== anonymousId) {
3313
+ this.context.store.state.anonymousId = urlId;
3314
+ this.context.store.save();
3315
+ }
3316
+ if (accountId) {
3317
+ var props = this.context.getReportData('track_signup', 'H_SignUp', {});
3318
+ this.context.report(props);
3319
+ }
3320
+ }
3321
+ else if (!accountId || (re_login && accountId !== urlId)) {
3322
+ this.context.setUserUId(urlId);
3323
+ }
3324
+ };
3325
+ /**
3326
+ * 获取链接上的id
3327
+ */
3328
+ SiteLinkerPlugin.prototype.getUrlId = function () {
3329
+ /**
3330
+ * 匿名ID:a 登录ID:u
3331
+ * 如果是匿名ID:返回的是a+匿名ID 如果是登录ID:返回的是u+登录ID
3332
+ */
3333
+ var hnId = window.location.href.match(/_hnsdk=([au][^\?\#\&\=]+)/);
3334
+ if (isArray(hnId) && hnId[1]) {
3335
+ return handleDecodeURLComponent(hnId[1]);
3336
+ }
3337
+ return '';
3338
+ };
3339
+ /**
3340
+ * 判断url链接是否包含part_url
3341
+ * @param url
3342
+ */
3343
+ SiteLinkerPlugin.prototype.getPartUrl = function (url) {
3344
+ var len = this.linker.length;
3345
+ for (var i = 0; i < len; i++) {
3346
+ if (url.includes(this.linker[i].part_url)) {
3347
+ return true;
3348
+ }
3349
+ }
3350
+ return false;
3351
+ };
3352
+ /**
3353
+ * 获取url链接对应的linker配置中after_hash的值
3354
+ * @param url
3355
+ */
3356
+ SiteLinkerPlugin.prototype.getPartHash = function (url) {
3357
+ var len = this.linker.length;
3358
+ for (var i = 0; i < len; i++) {
3359
+ if (url.includes(this.linker[i].part_url)) {
3360
+ return this.linker[i].after_hash;
3361
+ }
3362
+ }
3363
+ return false;
3364
+ };
3365
+ /**
3366
+ * 获取当前的匿名ID和当前的登录ID
3367
+ */
3368
+ SiteLinkerPlugin.prototype.getCurrentId = function () {
3369
+ var accountId = this.context.store.getAccountId();
3370
+ var anonymousId = this.context.store.getAnonymousId();
3371
+ var hnId = accountId ? "u".concat(accountId) : "a".concat(anonymousId);
3372
+ return handleEncodeURLComponent(hnId);
3373
+ };
3374
+ /**
3375
+ * 重写a 标签的href链接
3376
+ * @param url
3377
+ * @param dom
3378
+ */
3379
+ SiteLinkerPlugin.prototype.rewriteUrl = function (url, dom) {
3380
+ /**
3381
+ * ([^?#]+):匹配直到遇到 ? 或 # 之前的任何字符,并将这部分捕获为第一组。
3382
+ * (\?[^#]*)?:可选地匹配 ? 后面直到遇到 # 之前的任何字符,并将这部分捕获为第二组。
3383
+ * (#.*)?:可选地匹配 # 后面的任何字符,并将这部分捕获为第三组。
3384
+ */
3385
+ var reg = /([^?#]+)(\?[^#]*)?(#.*)?/;
3386
+ var arr = reg.exec(url);
3387
+ var normalizeUrl = '';
3388
+ if (!arr)
3389
+ return;
3390
+ var host = arr[1] || ''; // 'http://www.xx.com'
3391
+ var search = arr[2] || ''; // '?xxx=xxx'
3392
+ var hash = arr[3] || ''; // '#xxx=xxx'
3393
+ var hnId = "_hnsdk=".concat(this.getCurrentId());
3394
+ var changeHnId = function (str) {
3395
+ var list = str.split('&');
3396
+ var result = [];
3397
+ list.forEach(function (value) {
3398
+ if (value.includes('_hnsdk')) {
3399
+ result.push(hnId);
3400
+ }
3401
+ else {
3402
+ result.push(value);
3403
+ }
3404
+ });
3405
+ return result.join('&');
3406
+ };
3407
+ if (this.getPartHash(url)) {
3408
+ var hasQuery = hash.includes('?'); // 判断是#xxx?xxx=xxx的格式
3409
+ var index = hash.indexOf('_hnsdk');
3410
+ if (hasQuery) {
3411
+ if (index >= 0) {
3412
+ normalizeUrl = "".concat(host).concat(search, "#").concat(hash.substring(1, index)).concat(changeHnId(hash.substring(index, hash.length)));
3413
+ }
3414
+ else {
3415
+ normalizeUrl = "".concat(host).concat(search, "#").concat(hash.substring(1), "&").concat(hnId);
3416
+ }
3417
+ }
3418
+ else {
3419
+ normalizeUrl = "".concat(host).concat(search, "#").concat(hash.substring(1), "?").concat(hnId);
3420
+ }
3421
+ }
3422
+ else {
3423
+ var hasQuery = /^\?(\w)+/.test(search); // 判断是否有?xxx=xxx的格式
3424
+ if (hasQuery) {
3425
+ if (search.includes('_hnsdk')) {
3426
+ normalizeUrl = "".concat(host, "?").concat(changeHnId(search.substring(1))).concat(hash);
3427
+ }
3428
+ else {
3429
+ normalizeUrl = "".concat(host).concat(search, "&").concat(hnId).concat(hash);
3430
+ }
3431
+ }
3432
+ else {
3433
+ normalizeUrl = "".concat(host, "?").concat(hnId).concat(hash);
3434
+ }
3435
+ }
3436
+ if (dom) {
3437
+ dom.href = normalizeUrl;
3438
+ }
3439
+ return normalizeUrl;
3440
+ };
3441
+ SiteLinkerPlugin.prototype.addClickListen = function () {
3442
+ var _this = this;
3443
+ var handleClick = function (event) {
3444
+ var _a, _b;
3445
+ var target = event.target;
3446
+ if (!target)
3447
+ return;
3448
+ var tagName = (_a = target.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
3449
+ var parentNode = target.parentNode;
3450
+ var parentTagName = (_b = parentNode === null || parentNode === void 0 ? void 0 : parentNode.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
3451
+ if ((tagName === 'a' && target.href) ||
3452
+ (parentTagName === 'a' && parentNode.href)) {
3453
+ var sdkUrl = void 0;
3454
+ var sdkTarget = void 0;
3455
+ if (tagName === 'a' && target.href) {
3456
+ sdkUrl = target.href;
3457
+ sdkTarget = target;
3458
+ }
3459
+ else {
3460
+ sdkUrl = parentNode.href;
3461
+ sdkTarget = parentNode;
3462
+ }
3463
+ var protocol = getURL(sdkUrl).protocol;
3464
+ if (protocol === 'http:' || protocol === 'https:') {
3465
+ if (_this.getPartUrl(sdkUrl)) {
3466
+ _this.rewriteUrl(sdkUrl, sdkTarget);
3467
+ }
3468
+ }
3469
+ }
3470
+ };
3471
+ if ('PointerEvent' in window) {
3472
+ document.addEventListener('pointerdown', handleClick);
3473
+ }
3474
+ else {
3475
+ document.addEventListener('mousedown', handleClick);
3476
+ }
3477
+ };
3478
+ return SiteLinkerPlugin;
3479
+ }(PluginBase));
3480
+
3481
+ var HistoryPlugin = /** @class */ (function (_super) {
3482
+ __extends(HistoryPlugin, _super);
3483
+ function HistoryPlugin(options, context) {
3484
+ var _this = _super.call(this, options, context) || this;
3485
+ _this.options = options;
3486
+ _this.context = context;
3487
+ _this.name = 'HistoryPlugin';
3488
+ /**
3489
+ * 上一次页面url
3490
+ */
3491
+ _this.lastHref = window.location.href;
3492
+ /**
3493
+ * 上一次路由path
3494
+ */
3495
+ _this.lastPath = window.location.pathname;
3496
+ return _this;
3497
+ }
3498
+ HistoryPlugin.prototype.init = function (notify) {
3499
+ if (!supportHistory())
3500
+ return;
3501
+ var _a = this.options, isSinglePage = _a.isSinglePage, pageviewAutoTrack = _a.autoTrackConfig.pageviewAutoTrack;
3502
+ var self = this;
3503
+ var originalOnpopstate = window.onpopstate;
3504
+ var handleRouterChange = function (currentPath, currentHref) {
3505
+ var params = {
3506
+ fromPath: self.lastPath,
3507
+ fromHref: self.lastHref,
3508
+ toPath: currentPath,
3509
+ toHref: currentHref
3510
+ };
3511
+ self.lastPath = currentPath;
3512
+ self.lastHref = currentHref;
3513
+ mitt.emit('urlChange', __assign(__assign({}, params), { mode: 'history' }));
3514
+ if (isSinglePage || pageviewAutoTrack === 'singlePage') {
3515
+ if (isFunction(isSinglePage)) {
3516
+ var extra = isSinglePage();
3517
+ if (isObject(extra)) {
3518
+ params = __assign(__assign({}, params), extra);
3519
+ }
3520
+ }
3521
+ notify(__assign(__assign({}, params), { H_referrer: self.lastHref }));
3522
+ }
3523
+ };
3524
+ window.onpopstate = function () {
3525
+ var args = [];
3526
+ for (var _i = 0; _i < arguments.length; _i++) {
3527
+ args[_i] = arguments[_i];
3528
+ }
3529
+ var currentPath = window.location.pathname;
3530
+ var currentHref = window.location.href;
3531
+ handleRouterChange(currentPath, currentHref);
3532
+ originalOnpopstate && originalOnpopstate.apply(this, args);
3533
+ };
3534
+ function historyReplaceFn(originalHistoryFn) {
3535
+ return function () {
3536
+ var args = [];
3537
+ for (var _i = 0; _i < arguments.length; _i++) {
3538
+ args[_i] = arguments[_i];
3539
+ }
3540
+ var currentPath = args[2];
3541
+ originalHistoryFn.apply(this, args);
3542
+ var currentHref = window.location.href;
3543
+ handleRouterChange(currentPath, currentHref);
3544
+ };
3545
+ }
3546
+ replaceOld(window.history, 'pushState', historyReplaceFn);
3547
+ replaceOld(window.history, 'replaceState', historyReplaceFn);
3548
+ };
3549
+ HistoryPlugin.prototype.transform = function (data) {
3550
+ this.context.autoTrack(data);
3551
+ return undefined;
3552
+ };
3553
+ return HistoryPlugin;
3554
+ }(PluginBase));
3555
+
3556
+ var HashPlugin = /** @class */ (function (_super) {
3557
+ __extends(HashPlugin, _super);
3558
+ function HashPlugin(options, context) {
3559
+ var _this = _super.call(this, options, context) || this;
3560
+ _this.options = options;
3561
+ _this.context = context;
3562
+ _this.name = 'HashPlugin';
3563
+ /**
3564
+ * 上一次页面url
3565
+ */
3566
+ _this.lastHref = window.location.href;
3567
+ /**
3568
+ * 上一次路由path
3569
+ */
3570
+ _this.lastPath = window.location.hash;
3571
+ return _this;
3572
+ }
3573
+ HashPlugin.prototype.init = function (notify) {
3574
+ var _this = this;
3575
+ var _a = this.options, isSinglePage = _a.isSinglePage, pageviewAutoTrack = _a.autoTrackConfig.pageviewAutoTrack;
3576
+ window.addEventListener('hashchange', function (event) {
3577
+ var newURL = event.newURL;
3578
+ var currentPath = getURL(newURL).hash;
3579
+ var params = {
3580
+ fromPath: _this.lastPath,
3581
+ fromHref: _this.lastHref,
3582
+ toPath: currentPath,
3583
+ toHref: newURL
3584
+ };
3585
+ mitt.emit('urlChange', __assign(__assign({}, params), { mode: 'history' }));
3586
+ _this.lastHref = newURL;
3587
+ _this.lastPath = currentPath;
3588
+ if (isSinglePage || pageviewAutoTrack === 'singlePage') {
3589
+ if (isFunction(isSinglePage)) {
3590
+ var extra = isSinglePage();
3591
+ if (isObject(extra)) {
3592
+ params = __assign(__assign({}, params), extra);
3593
+ }
3594
+ }
3595
+ notify(__assign(__assign({}, params), { H_referrer: _this.lastHref }));
3596
+ }
3597
+ });
3598
+ };
3599
+ HashPlugin.prototype.transform = function (data) {
3600
+ this.context.autoTrack(data);
3601
+ return undefined;
3602
+ };
3603
+ return HashPlugin;
3604
+ }(PluginBase));
3605
+
3606
+ var HinaTrack = /** @class */ (function (_super) {
3607
+ __extends(HinaTrack, _super);
3608
+ function HinaTrack(options, useInstancing) {
3609
+ if (useInstancing === void 0) { useInstancing = true; }
3610
+ var _this = _super.call(this, options, useInstancing) || this;
3611
+ /**
3612
+ * 上报数据的dom元素 默认有 'a', 'input', 'button', 'textarea'
3613
+ */
3614
+ _this.trackTags = defaultTags;
3615
+ /**
3616
+ * 事件静态公共属性
3617
+ */
3618
+ _this.presetProps = {};
3619
+ /**
3620
+ * 插件列表
3621
+ */
3622
+ _this.plugins = [];
3623
+ _this.consolePrefix = '埋点SDK';
3624
+ // 使用new的方式初始化SDK,需要默认调用init方法进行初始化
3625
+ if (_this.useInstancing) {
3626
+ _this.init(options);
3627
+ }
3628
+ return _this;
3629
+ }
3630
+ /**
3631
+ * 注册/初始化SDK
3632
+ * @param options
3633
+ */
3634
+ HinaTrack.prototype.init = function (options) {
3635
+ if (this.isReady) {
3636
+ this.log('hinaSDK has been initialized', ConsoleTypes.ERROR);
3637
+ return;
3638
+ }
3639
+ // 默认配置项
3640
+ var default_config = GET_DEFAULT_OPTIONS();
3641
+ // 将用户配置项和默认配置项合并
3642
+ this.options = merge(default_config, options);
3643
+ // 处理配置信息
3644
+ this.normalizeConfig();
3645
+ // 初始化state
3646
+ this.initState();
3647
+ // 处理广告参数
3648
+ this.initAdvProps();
3649
+ // 插件初始化
3650
+ this.initPlugins();
3651
+ // SDK初始化成功,一切准备就绪
3652
+ this.isReady = true;
3653
+ this.log('hinaSDK initialized successfully');
3654
+ };
3655
+ /**
3656
+ * 处理配置信息
3657
+ */
3658
+ HinaTrack.prototype.normalizeConfig = function () {
3659
+ var _a = this.options, serverUrl = _a.serverUrl, sendType = _a.sendType, batchSend = _a.batchSend, _b = _a.autoTrackConfig, _c = _b === void 0 ? {} : _b, _d = _c.trackAttr, trackAttr = _d === void 0 ? [] : _d, collectTags = _c.collectTags, pageLeaveAutoTrack = _c.pageLeaveAutoTrack, pageviewAutoTrack = _c.pageviewAutoTrack;
3660
+ serverUrl = serverUrl || '';
3661
+ serverUrl = serverUrl.trim();
3662
+ if (serverUrl === '') {
3663
+ this.log('当前 serverUrl 为空或不正确,network 中不会发数据,请配置正确的 serverUrl!', ConsoleTypes.WARN);
3664
+ }
3665
+ else {
3666
+ var href = window.location.href;
3667
+ var currentProtocol = getURL(href).protocol || '';
3668
+ var serverProtocol = getURL(serverUrl).protocol || '';
3669
+ if (serverProtocol !== currentProtocol) {
3670
+ this.log('SDK 检测到您的数据发送地址和当前页面地址的协议不一致,建议您修改成一致的协议。因为:https 下面发送 http 的图片请求会失败。', ConsoleTypes.WARN);
3671
+ }
3672
+ }
3673
+ if (![ReportType.IMAGE, ReportType.AJAX, ReportType.BEACON].includes(sendType)) {
3674
+ this.setConfig({
3675
+ sendType: ReportType.IMAGE
3676
+ });
3677
+ }
3678
+ // 处理pageLeaveAutoTrack
3679
+ if (pageLeaveAutoTrack === true) {
3680
+ this.options.autoTrackConfig.pageLeaveAutoTrack = {
3681
+ heartbeat_interval_time: 5000,
3682
+ max_duration: 432000
3683
+ };
3684
+ }
3685
+ // 处理trackAttr
3686
+ if (isArray(trackAttr)) {
3687
+ trackAttr = trackAttr.filter(function (v) { return isString(v); });
3688
+ if (!trackAttr.includes('hn-click'))
3689
+ trackAttr.push('hn-click');
3690
+ }
3691
+ else {
3692
+ trackAttr = ['hn-click'];
3693
+ }
3694
+ this.options.autoTrackConfig.trackAttr = trackAttr;
3695
+ // 处理collectTags
3696
+ if (isObject(collectTags)) {
3697
+ if (collectTags.div === true) {
3698
+ this.options.autoTrackConfig.collectTags.div = {
3699
+ ignoreTags: ignoreTags,
3700
+ maxLevel: 1
3701
+ };
3702
+ }
3703
+ else if (isObject(collectTags.div)) {
3704
+ var maxLevel = 1;
3705
+ var oDiv = collectTags.div;
3706
+ if (isNumber(oDiv.maxLevel) && [1, 2, 3].includes(oDiv.maxLevel)) {
3707
+ maxLevel = oDiv.maxLevel;
3708
+ }
3709
+ this.options.autoTrackConfig.collectTags.div = {
3710
+ ignoreTags: ignoreTags,
3711
+ maxLevel: maxLevel
3712
+ };
3713
+ }
3714
+ else {
3715
+ this.options.autoTrackConfig.collectTags.div = false;
3716
+ }
3717
+ }
3718
+ else {
3719
+ this.options.autoTrackConfig.collectTags = {
3720
+ div: false
3721
+ };
3722
+ }
3723
+ this.updateTrackTags();
3724
+ // 处理批量发送
3725
+ if (batchSend === true || isObject(batchSend)) {
3726
+ this.options.batchSend = __assign({ dataSendTimeout: 6000, sendInterval: 6000, storageLimit: 200 }, batchSend);
3727
+ this.batchSender = new BatchSend(this);
3728
+ }
3729
+ // 处理pageviewAutoTrack
3730
+ if (pageviewAutoTrack === 'auto') {
3731
+ this.autoTrack();
3732
+ }
3733
+ };
3734
+ /**
3735
+ * 初始化广告参数
3736
+ */
3737
+ HinaTrack.prototype.initAdvProps = function () {
3738
+ var advProps = {};
3739
+ var presetProperties = this.options.presetProperties || {};
3740
+ Object.keys(presetProperties).forEach(function (key) {
3741
+ var value = presetProperties[key];
3742
+ if (key.includes('latest_')) {
3743
+ key = key.slice(7);
3744
+ if (value) {
3745
+ var url_domain = getCurrentDomain();
3746
+ if (key !== 'utm' && url_domain === 'url解析失败') {
3747
+ advProps["H_latest_".concat(key)] = 'url的domain解析失败';
3748
+ }
3749
+ else if (isReferralTraffic()) {
3750
+ switch (key) {
3751
+ case 'traffic_source_type':
3752
+ advProps.H_latest_traffic_source_type =
3753
+ SearchKeyword.getSourceFromReferrer();
3754
+ break;
3755
+ case 'search_keyword':
3756
+ var searchKeyword = SearchKeyword.getKeywordFromReferrer();
3757
+ if (searchKeyword) {
3758
+ advProps.H_latest_search_keyword = searchKeyword;
3759
+ }
3760
+ break;
3761
+ case 'referrer': // todo 这块似乎没有什么用
3762
+ advProps.H_latest_referrer = '';
3763
+ break;
3764
+ }
3765
+ }
3766
+ }
3767
+ }
3768
+ });
3769
+ this.store.state.props = advProps;
3770
+ if (presetProperties.latest_utm) {
3771
+ this.getUmtsParams('H_latest_');
3772
+ }
3773
+ this.getUmtsParams('H_');
3774
+ this.store.setProps(this.store.state.props);
3775
+ };
3776
+ /**
3777
+ * 处理广告参数
3778
+ * @param prefix
3779
+ */
3780
+ HinaTrack.prototype.getUmtsParams = function (prefix) {
3781
+ if (prefix === void 0) { prefix = ''; }
3782
+ var allUtms = getUmtsParams(prefix);
3783
+ if (this.store.state.props && this.store.state.props.H_latest_utm_source) {
3784
+ this.store.state.props = __assign(__assign({}, this.store.state.props), allUtms);
3785
+ }
3786
+ return allUtms;
3787
+ };
3788
+ /**
3789
+ * 初始化共享数据
3790
+ */
3791
+ HinaTrack.prototype.initState = function () {
3792
+ this.store = new State(this.options);
3793
+ this.store.init();
3794
+ };
3795
+ /**
3796
+ * 更新采集的dom元素
3797
+ */
3798
+ HinaTrack.prototype.updateTrackTags = function () {
3799
+ var collectTags = this.options.autoTrackConfig.collectTags;
3800
+ var tags = __spreadArray([], __read(defaultTags), false);
3801
+ Object.keys(collectTags || {}).forEach(function (key) {
3802
+ var value = collectTags[key];
3803
+ if ((value === true || isObject(value)) && !tags.includes(key)) {
3804
+ tags.push(key);
3805
+ }
3806
+ });
3807
+ this.trackTags = tags;
3808
+ };
3809
+ /**
3810
+ * 应用插件
3811
+ */
3812
+ HinaTrack.prototype.initPlugins = function () {
3813
+ var _this = this;
3814
+ var _a = this.options.plugins, plugins = _a === void 0 ? [] : _a;
3815
+ plugins = plugins || [];
3816
+ var clickCrackPlugin = new ClickTrackPlugin(this.options, this);
3817
+ var stayTrackPlugin = new StayTrackPlugin(this.options, this);
3818
+ var pageLeavePlugin = new PageLeavePlugin(this.options, this);
3819
+ var siteLinkerPlugin = new SiteLinkerPlugin(this.options, this);
3820
+ var historyPlugin = new HistoryPlugin(this.options, this);
3821
+ var hashPlugin = new HashPlugin(this.options, this);
3822
+ this.plugins = [
3823
+ clickCrackPlugin,
3824
+ stayTrackPlugin,
3825
+ pageLeavePlugin,
3826
+ siteLinkerPlugin,
3827
+ historyPlugin,
3828
+ hashPlugin
3829
+ ];
3830
+ plugins.forEach(function (Plugin) {
3831
+ var instance = new Plugin(_this.options, _this);
3832
+ _this.plugins.push(instance);
3833
+ });
3834
+ this.runPlugins(this.plugins);
3835
+ };
3836
+ /**
3837
+ * @deprecated
3838
+ * 启动内置插件,v4版本后不建议使用该方法启动插件
3839
+ * 建议通过配置项的方式启动内置插件
3840
+ */
3841
+ HinaTrack.prototype.use = function (pluginName, options) {
3842
+ var _this = this;
3843
+ var _a = this.options, autoTrackConfig = _a.autoTrackConfig, siteLinkerConfig = _a.siteLinkerConfig;
3844
+ var pageLeaveAutoTrack = autoTrackConfig.pageLeaveAutoTrack;
3845
+ var startPlugin = function (pluginName) {
3846
+ var pluginInstance = _this.plugins.find(function (plugin) { return plugin.name === pluginName; });
3847
+ if (pluginInstance)
3848
+ pluginInstance.init();
3849
+ };
3850
+ if (!isObject(options)) {
3851
+ this.log("".concat(pluginName, "\u63D2\u4EF6\u914D\u7F6E\u9879\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61\u7C7B\u578B"), ConsoleTypes.WARN);
3852
+ return;
3853
+ }
3854
+ if (pluginName === 'PageLeave') {
3855
+ if (isObject(pageLeaveAutoTrack)) {
3856
+ this.log('PageLeave插件已通过pageLeaveAutoTrack的配置参数启动,不可重复启动,如果想通过use方式启动,请删除配置项中的pageLeaveAutoTrack', ConsoleTypes.WARN);
3857
+ }
3858
+ else {
3859
+ this.options.autoTrackConfig.pageLeaveAutoTrack =
3860
+ options;
3861
+ startPlugin(PageLeavePluginName);
3862
+ }
3863
+ }
3864
+ else if (pluginName === 'SiteLinker') {
3865
+ if (isObject(siteLinkerConfig)) {
3866
+ this.log('SiteLinker插件已通过siteLinkerConfig的配置参数启动,不可重复启动,如果想通过use方式启动,请删除配置项中的siteLinkerConfig', ConsoleTypes.WARN);
3867
+ }
3868
+ else {
3869
+ this.options.siteLinkerConfig = options;
3870
+ startPlugin(SiteLinkerPluginName);
3871
+ }
3872
+ }
3873
+ };
3874
+ /**
3875
+ * 设置配置选项
3876
+ * @param options 配置对象
3877
+ */
3878
+ HinaTrack.prototype.setConfig = function (options) {
3879
+ this.options = merge(this.options, options);
3880
+ this.normalizeConfig();
3881
+ };
3882
+ /**
3883
+ * 获取配置选项 参数为空时 返回整个配置对象
3884
+ * @param key
3885
+ */
3886
+ HinaTrack.prototype.getConfig = function (key) {
3887
+ if (!key) {
3888
+ return this.options;
3889
+ }
3890
+ return this.options[key];
3891
+ };
3892
+ /**
3893
+ * 上报数据
3894
+ * @param data
3895
+ * @param callback
3896
+ * @param type
3897
+ */
3898
+ HinaTrack.prototype.report = function (data, callback, type) {
3899
+ console.log('report', data);
3900
+ var _a = this.options, batchSend = _a.batchSend, globalCallback = _a.globalCallback, serverUrl = _a.serverUrl, dataSendTimeout = _a.dataSendTimeout, sendType = _a.sendType, imgUseCrossOrigin = _a.imgUseCrossOrigin;
3901
+ sendType = type || sendType;
3902
+ // 批量发送
3903
+ if (batchSend) {
3904
+ this.batchSender.add(data);
3905
+ }
3906
+ else {
3907
+ var dataStr_1 = data;
3908
+ if (!isString(data)) {
3909
+ dataStr_1 = JSON.stringify(data);
3910
+ }
3911
+ var base64Data = base64Encode(dataStr_1);
3912
+ var params = {
3913
+ data: "data=".concat(base64Data),
3914
+ url: serverUrl,
3915
+ timeout: dataSendTimeout,
3916
+ imgUseCrossOrigin: imgUseCrossOrigin
3917
+ };
3918
+ var request = void 0;
3919
+ if (sendType === ReportType.BEACON && navigator.sendBeacon) {
3920
+ request = new BeaconRequest(params);
3921
+ }
3922
+ else if (sendType === ReportType.IMAGE && params.data.length < 2048) {
3923
+ request = new ImageRequest(params);
3924
+ }
3925
+ else {
3926
+ request = new AjaxRequest(params);
3927
+ }
3928
+ return request.run().then(function (res) {
3929
+ if (isFunction(globalCallback)) {
3930
+ globalCallback(serverUrl, dataStr_1, res.type, res.msg);
3931
+ }
3932
+ if (isFunction(callback)) {
3933
+ callback(serverUrl, dataStr_1, res.type, res.msg);
3934
+ }
3935
+ return res;
3936
+ });
3937
+ }
3938
+ };
3939
+ /**
3940
+ * 设置用户登录的唯一标识
3941
+ * @param uid
3942
+ * @param callback
3943
+ */
3944
+ HinaTrack.prototype.setUserUId = function (uid, callback) {
3945
+ uid = uid !== null && uid !== void 0 ? uid : '';
3946
+ if (isNumber(uid) || isString(uid)) {
3947
+ uid = String(uid).trim();
3948
+ if (!uid) {
3949
+ this.log('setUserUId: uid is empty', ConsoleTypes.WARN);
3950
+ }
3951
+ var accountId = this.store.getAccountId();
3952
+ if (accountId !== uid) {
3953
+ this.store.setAccountId(uid);
3954
+ var props = this.getReportData('track_signup', 'H_SignUp', {});
3955
+ this.report(props, callback);
3956
+ }
3957
+ else {
3958
+ this.log('setUserUId: uid is equal to account_id, , failed to execute setUserUId', ConsoleTypes.WARN);
3959
+ }
3960
+ }
3961
+ else {
3962
+ this.log('setUserUId: uid must be string or number', ConsoleTypes.WARN);
3963
+ }
3964
+ };
3965
+ /**
3966
+ * 设置设备ID
3967
+ * @param uid
3968
+ */
3969
+ HinaTrack.prototype.setDeviceUId = function (uid) {
3970
+ this.store.setDeviceId(uid);
3971
+ };
3972
+ /**
3973
+ * 获取设备ID
3974
+ */
3975
+ HinaTrack.prototype.getDeviceUId = function () {
3976
+ return this.store.getDeviceId();
3977
+ };
3978
+ /**
3979
+ * 自定义埋点事件
3980
+ * @param event
3981
+ * @param properties
3982
+ * @param callback
3983
+ */
3984
+ HinaTrack.prototype.track = function (event, properties, callback) {
3985
+ callback = callback || (function () { });
3986
+ if (isString(event)) {
3987
+ properties = isObject(properties) ? properties : {};
3988
+ var props = this.getReportData('track', event, properties);
3989
+ this.report(props, callback);
3990
+ }
3991
+ else {
3992
+ this.log('eventName must be a sting and properties must be an object', ConsoleTypes.WARN);
3993
+ }
3994
+ };
3995
+ /**
3996
+ * @param name
3997
+ * @param data
3998
+ * @param callback
3999
+ */
4000
+ HinaTrack.prototype.quick = function (name, data, callback) {
4001
+ var params = {};
4002
+ callback = callback || (function () { });
4003
+ if (isObject(data)) {
4004
+ params = data;
4005
+ }
4006
+ else if (isFunction(data)) {
4007
+ callback = data;
4008
+ }
4009
+ this.autoTrack(params, callback);
4010
+ };
4011
+ /**
4012
+ * 开启页面浏览采集
4013
+ * @param data
4014
+ * @param callback
4015
+ */
4016
+ HinaTrack.prototype.autoTrack = function (data, callback) {
4017
+ if (data === void 0) { data = {}; }
4018
+ if (callback === void 0) { callback = noop; }
4019
+ var props = this.getReportData('track', 'H_pageview', data);
4020
+ this.report(props, callback);
4021
+ if (this.store.isSetFirstVisit) {
4022
+ this.store.isSetFirstVisit = false;
4023
+ var referrer = getReferrer();
4024
+ this.userSetOnce({
4025
+ H_first_visit_time: nowStamp(),
4026
+ H_first_referrer: referrer,
4027
+ H_first_host: referrer ? getHostname(referrer, '取值异常') : '',
4028
+ H_first_browser_language: isString(navigator.language)
4029
+ ? navigator.language.toLowerCase()
4030
+ : '取值异常',
4031
+ H_first_traffic_source_type: SearchKeyword.getSourceFromReferrer(),
4032
+ H_first_search_keyword: SearchKeyword.getKeywordFromReferrer()
4033
+ });
4034
+ }
4035
+ };
4036
+ /**
4037
+ * 添加用户属性
4038
+ * 直接设置用户的属性,如果存在则覆盖。
4039
+ * @param data
4040
+ * @param callback
4041
+ */
4042
+ HinaTrack.prototype.userSet = function (data, callback) {
4043
+ if (isObject(data) && !isEmptyObject(data)) {
4044
+ var props = this.getReportData('user_set', '', data);
4045
+ this.report(props, callback);
4046
+ }
4047
+ };
4048
+ /**
4049
+ * 添加用户属性
4050
+ * 如果不存在则设置,存在就不设置
4051
+ * @param data
4052
+ * @param callback
4053
+ */
4054
+ HinaTrack.prototype.userSetOnce = function (data, callback) {
4055
+ if (isObject(data) && !isEmptyObject(data)) {
4056
+ var props = this.getReportData('user_setOnce', '', data);
4057
+ this.report(props, callback);
4058
+ }
4059
+ };
4060
+ /**
4061
+ * 对当前用户的属性做递增或者递减
4062
+ * @param data
4063
+ * @param callback
4064
+ */
4065
+ HinaTrack.prototype.userAdd = function (data, callback) {
4066
+ var _a;
4067
+ var _this = this;
4068
+ if (isString(data)) {
4069
+ data = (_a = {},
4070
+ _a[data] = 1,
4071
+ _a);
4072
+ }
4073
+ var isValid = function (params) {
4074
+ for (var key in params) {
4075
+ if (!/-*\d+/.test(String(params[key]))) {
4076
+ _this.log('userAdd: value is must be number', ConsoleTypes.WARN);
4077
+ return false;
4078
+ }
4079
+ }
4080
+ return true;
4081
+ };
4082
+ if (isObject(data) && !isEmptyObject(data) && isValid(data)) {
4083
+ var props = this.getReportData('user_add', '', data);
4084
+ this.report(props, callback);
4085
+ }
4086
+ };
4087
+ /**
4088
+ * 删除当前用户的一些属性
4089
+ * @param data
4090
+ * @param callback
4091
+ */
4092
+ HinaTrack.prototype.userUnset = function (data, callback) {
4093
+ var _this = this;
4094
+ var obj = {};
4095
+ if (isString(data)) {
4096
+ data = [data];
4097
+ }
4098
+ if (isArray(data)) {
4099
+ data.forEach(function (value) {
4100
+ if (isString(value)) {
4101
+ obj[value] = true;
4102
+ }
4103
+ else {
4104
+ _this.log("userUnset: value inside the array must be string and have already been filtered out:".concat(value), ConsoleTypes.WARN);
4105
+ }
4106
+ });
4107
+ if (!isEmptyObject(obj)) {
4108
+ var props = this.getReportData('user_unset', '', obj);
4109
+ this.report(props, callback);
4110
+ }
4111
+ }
4112
+ else {
4113
+ this.log('userUnset: param must be an array or string', ConsoleTypes.WARN);
4114
+ }
4115
+ };
4116
+ /**
4117
+ * 删除当前用户及他的所有属性。
4118
+ * @param callback
4119
+ */
4120
+ HinaTrack.prototype.userDelete = function (callback) {
4121
+ var props = this.getReportData('user_delete', '', {});
4122
+ this.report(props, callback);
4123
+ this.store.setAccountId('');
4124
+ };
4125
+ /**
4126
+ * 添加事件属性
4127
+ * 当使用函数类型作为属性值、函数返回值只能是string、bool、number、date、array类型
4128
+ * @param params
4129
+ */
4130
+ HinaTrack.prototype.registerCommonProperties = function (params) {
4131
+ this.presetProps = merge(this.presetProps, params);
4132
+ };
4133
+ /**
4134
+ * 获取预置属性
4135
+ * 此方法可获取,页面地址,页面标题,前向地址,SDK 类型及版本,屏幕宽高,最近一次的相关属性
4136
+ */
4137
+ HinaTrack.prototype.getPresetProperties = function () {
4138
+ return {
4139
+ H_is_first_day: this.store.isFirstDay,
4140
+ H_is_first_time: this.store.isFirstTime,
4141
+ device_id: this.store.getDeviceId(),
4142
+ anonymous_id: this.store.getAnonymousId(),
4143
+ account_id: this.store.getAccountId(),
4144
+ properties: __assign(__assign(__assign({}, this.presetProps), getPageProperties()), getBrowserInfo())
4145
+ };
4146
+ };
4147
+ /**
4148
+ * 清空预置属性
4149
+ * @param payload
4150
+ */
4151
+ HinaTrack.prototype.clearPageRegister = function (payload) {
4152
+ var _this = this;
4153
+ if (payload === void 0) { payload = true; }
4154
+ if (payload === true) {
4155
+ this.presetProps = {};
4156
+ }
4157
+ else if (isArray(payload)) {
4158
+ payload.forEach(function (key) {
4159
+ if (key in _this.presetProps)
4160
+ delete _this.presetProps[key];
4161
+ });
4162
+ }
4163
+ };
4164
+ /**
4165
+ * 检查发送数据
4166
+ * @param props
4167
+ */
4168
+ HinaTrack.prototype.checkReportProperties = function (props) {
4169
+ var _this = this;
4170
+ Object.keys(props).forEach(function (key) {
4171
+ var value = props[key];
4172
+ if (isString(value) && value.length > MAX_STRING_LENGTH) {
4173
+ _this.log("\u5C5E\u6027--".concat(key, " \u5185\u5BB9\u8FC7\u957F\uFF0C\u5DF2\u88AB\u5220\u9664"), ConsoleTypes.WARN);
4174
+ delete props[key];
4175
+ }
4176
+ else if (isObject(value)) {
4177
+ _this.checkReportProperties(value);
4178
+ }
4179
+ else if (isFunction(value)) {
4180
+ props[key] = value(props);
4181
+ if (isObject(props[key])) {
4182
+ _this.checkReportProperties(props[key]);
4183
+ }
4184
+ else if (isString(props[key]) &&
4185
+ props[key].length > MAX_STRING_LENGTH) {
4186
+ _this.log("\u5C5E\u6027--".concat(key, " \u5185\u5BB9\u8FC7\u957F\uFF0C\u5DF2\u88AB\u5220\u9664"), ConsoleTypes.WARN);
4187
+ delete props[key];
4188
+ }
4189
+ }
4190
+ });
4191
+ };
4192
+ /**
4193
+ * 获取上报数据
4194
+ * @param type
4195
+ * @param event
4196
+ * @param data
4197
+ */
4198
+ HinaTrack.prototype.getReportData = function (type, event, data) {
4199
+ var anonymous_id = this.store.getAnonymousId();
4200
+ var accountId = this.store.getAccountId();
4201
+ var time = nowStamp();
4202
+ var reportProperties = this.getReportProperties(type, event);
4203
+ var properties = __assign(__assign({}, reportProperties), (data || {}));
4204
+ this.checkReportProperties(properties);
4205
+ var props = {
4206
+ anonymous_id: anonymous_id,
4207
+ type: type,
4208
+ event: event,
4209
+ time: time,
4210
+ _track_id: Number(String(getRandom()).slice(2, 5) +
4211
+ String(getRandom()).slice(2, 4) +
4212
+ String(nowStamp()).slice(-4)),
4213
+ properties: properties
4214
+ };
4215
+ if (accountId) {
4216
+ props.account_id = accountId;
4217
+ }
4218
+ props.send_time = nowStamp();
4219
+ return props;
4220
+ };
4221
+ /**
4222
+ * 获取通用的上报数据
4223
+ * @param type 上报类型
4224
+ * @param event 事件名称
4225
+ */
4226
+ HinaTrack.prototype.getReportProperties = function (type, event) {
4227
+ if (type === void 0) { type = ''; }
4228
+ if (event === void 0) { event = ''; }
4229
+ // 这里对预置属性进行merge是为了防止影响this.presetProps的自身结构,深拷贝的操作
4230
+ var presetProps = merge(this.presetProps);
4231
+ var properties = __assign(__assign({ device_id: this.store.getDeviceId() }, this.store.state.props), presetProps);
4232
+ // user_set、user_setOnce、user_add、user_unset、user_delete
4233
+ if (!type || type.slice(0, 4) !== 'user') {
4234
+ properties = __assign(__assign(__assign({}, properties), getPageProperties()), getBrowserInfo());
4235
+ }
4236
+ if (type === 'track') {
4237
+ properties.H_is_first_day = this.store.isFirstDay;
4238
+ this.store.isFirstDay = false;
4239
+ if (event === 'H_pageview') {
4240
+ properties.H_is_first_time = this.store.isFirstTime;
4241
+ this.store.isFirstTime = false;
4242
+ }
4243
+ }
4244
+ return properties;
4245
+ };
4246
+ return HinaTrack;
4247
+ }(BaseCore));
4248
+
4249
+ function createInstance(options) {
4250
+ return new HinaTrack(options, false);
4251
+ }
4252
+ var hinaSdk = createInstance({});
4253
+
4254
+ exports.HinaTrack = HinaTrack;
4255
+ exports.default = hinaSdk;
4256
+
4257
+ Object.defineProperty(exports, '__esModule', { value: true });
4258
+
4259
+ }));
4260
+ //# sourceMappingURL=index.js.map