@fle-sdk/event-tracking-web 1.2.3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  > **构建用户数据体系,让用户行为数据发挥深远的价值。**
2
2
 
3
- **当前版本**: v1.2.3
3
+ **当前版本**: v1.2.4
4
4
 
5
5
  ## 前言
6
6
 
@@ -209,6 +209,10 @@ WebTracking
209
209
  | sendMethod | string | 数据发送方式:auto(自动选择)、xhr(XMLHttpRequest)、beacon(sendBeacon) | 否 | auto |
210
210
  | autoTrackPageDurationInterval | boolean | 是否定时上报页面停留时长 | 否 | false |
211
211
  | pageDurationInterval | number | 定时上报页面停留时长的间隔时间(毫秒) | 否 | 30000 |
212
+ | autoTrackExposure | boolean | 是否启用曝光埋点 | 否 | false |
213
+ | exposureThreshold | number | 曝光进入可视区判定阈值(0-1之间) | 否 | 0.5 |
214
+ | exposureTime | number | 曝光可见停留时长阈值(毫秒) | 否 | 500 |
215
+ | exposureNum | number | 同一元素允许上报的最大曝光次数(不传则不限制) | 否 | 不限制 |
212
216
  | pageKey | string | 自定义页面唯一标识,如果不传则自动从路由获取 | 否 | 自动生成 |
213
217
 
214
218
  #### 例子
@@ -276,6 +280,10 @@ export default App;
276
280
  | sendMethod | string | 数据发送方式:auto(自动选择)、xhr(XMLHttpRequest)、beacon(sendBeacon) | 否 | auto |
277
281
  | autoTrackPageDurationInterval | boolean | 是否定时上报页面停留时长 | 否 | false |
278
282
  | pageDurationInterval | number | 定时上报页面停留时长的间隔时间(毫秒) | 否 | 30000 |
283
+ | autoTrackExposure | boolean | 是否启用曝光埋点 | 否 | false |
284
+ | exposureThreshold | number | 曝光进入可视区判定阈值(0-1之间) | 否 | 0.5 |
285
+ | exposureTime | number | 曝光可见停留时长阈值(毫秒) | 否 | 500 |
286
+ | exposureNum | number | 同一元素允许上报的最大曝光次数(不传则不限制) | 否 | 不限制 |
279
287
  | pageKey | string | 自定义页面唯一标识,如果不传则自动从路由获取 | 否 | 自动生成 |
280
288
 
281
289
  #### 例子
@@ -969,11 +977,123 @@ WebTracking.init({
969
977
 
970
978
  两种方式可以同时使用,互不冲突。
971
979
 
980
+ ### 5.8 元素曝光埋点
981
+
982
+ SDK 支持自动监听元素曝光事件,适用于需要追踪元素可见性的场景(如商品卡片曝光、广告曝光等)。
983
+
984
+ #### 触发条件
985
+
986
+ 仅对包含 `data-exposure="true"` 的 DOM 元素做曝光监听与上报(区分大小写,建议统一为字符串 "true")。
987
+
988
+ #### 配置参数
989
+
990
+ - `autoTrackExposure`: 是否启用曝光埋点(默认:false)
991
+ - `exposureThreshold`: 曝光进入可视区判定阈值,0-1之间(默认:0.5)
992
+ - `exposureTime`: 曝光可见停留时长阈值,单位毫秒(默认:500)
993
+ - `exposureNum`: 同一元素允许上报的最大曝光次数(默认:不限制)
994
+
995
+ #### 工作原理
996
+
997
+ 1. 使用 `IntersectionObserver` API 判定元素是否进入可视区
998
+ 2. 元素进入可视区后开始计时
999
+ 3. 元素离开可视区时,如果可见时长达到 `exposureTime` 阈值,则上报曝光事件
1000
+ 4. 如果设置了 `exposureNum`,同一元素超过该次数后不再上报
1001
+
1002
+ #### 上报参数提取
1003
+
1004
+ 从目标元素(或其祖先节点,按"就近原则")提取所有 `data-*` 属性作为埋点业务参数,规则如下:
1005
+
1006
+ - 属性名从 `data-xxx-yyy` 转为 `xxxYyy`(camelCase)
1007
+ - 示例:`data-goods-id` → `goodsId`,`data-list-id` → `listId`
1008
+ - 排除属性:`data-exposure`、`data-part-key`、`data-desc`
1009
+
1010
+ #### 使用示例
1011
+
1012
+ ```jsx
1013
+ WebTracking.init({
1014
+ appKey: "218844",
1015
+ serverUrl: "https://xxx/push",
1016
+ // 启用曝光埋点
1017
+ autoTrackExposure: true,
1018
+ // 元素进入可视区 50% 时判定为可见
1019
+ exposureThreshold: 0.5,
1020
+ // 元素连续可见 500ms 才算一次有效曝光
1021
+ exposureTime: 500,
1022
+ // 同一元素最多上报 3 次曝光
1023
+ exposureNum: 3,
1024
+ });
1025
+ ```
1026
+
1027
+ #### HTML 使用示例
1028
+
1029
+ ```jsx
1030
+ <div className="goods-list">
1031
+ <div
1032
+ data-exposure="true"
1033
+ data-part-key="goods_card"
1034
+ data-desc="商品卡片曝光"
1035
+ data-goods-id="12345"
1036
+ data-goods-name="测试商品"
1037
+ data-list-id="home_list"
1038
+ >
1039
+ <img src="goods.jpg" alt="商品图片" />
1040
+ <h3>商品名称</h3>
1041
+ </div>
1042
+
1043
+ <div
1044
+ data-exposure="true"
1045
+ data-part-key="ad_banner"
1046
+ data-desc="广告横幅曝光"
1047
+ data-ad-id="999"
1048
+ data-ad-position="top"
1049
+ >
1050
+ <img src="ad.jpg" alt="广告图片" />
1051
+ </div>
1052
+ </div>
1053
+ ```
1054
+
1055
+ #### 上报数据示例
1056
+
1057
+ ```json
1058
+ {
1059
+ "event": "WebExposure",
1060
+ "desc": "商品卡片曝光",
1061
+ "itemKey": "218844.home_page.goods_card",
1062
+ "requestTime": 1709524231171,
1063
+ "deviceId": "1dd539cdea9332ebb9d5c087f9d4471f",
1064
+ "privateParamMap": {
1065
+ "business": {
1066
+ "goodsId": "12345",
1067
+ "goodsName": "测试商品",
1068
+ "listId": "home_list"
1069
+ }
1070
+ }
1071
+ }
1072
+ ```
1073
+
1074
+ #### 注意事项
1075
+
1076
+ 1. **浏览器兼容性**:需要浏览器支持 `IntersectionObserver` API,不支持时会自动禁用曝光埋点
1077
+ 2. **性能优化**:SDK 会自动去重,避免重复监听同一元素
1078
+ 3. **动态元素**:如果页面中有动态添加的元素,需要手动调用 `observeExposureElements()` 方法(暂未公开)
1079
+ 4. **数据提取**:`data-*` 属性会从目标元素向上遍历到 BODY 标签,按"就近原则"提取
1080
+
972
1081
  ---
973
1082
 
974
1083
  ## 六、版本更新日志
975
1084
 
976
- ### v1.2.3 (最新)
1085
+ ### v1.2.4 (最新)
1086
+
1087
+ - ✨ 新增元素曝光埋点功能
1088
+ - `autoTrackExposure` - 是否启用曝光埋点
1089
+ - `exposureThreshold` - 曝光进入可视区判定阈值(0-1之间)
1090
+ - `exposureTime` - 曝光可见停留时长阈值(毫秒)
1091
+ - `exposureNum` - 同一元素允许上报的最大曝光次数
1092
+ - 使用 `IntersectionObserver` API 判定元素可见性
1093
+ - 自动提取 `data-*` 属性作为业务参数
1094
+ - 支持自定义曝光次数限制
1095
+
1096
+ ### v1.2.3
977
1097
 
978
1098
  - 🐛 修复批量发送数据格式问题
979
1099
  - 批量发送时直接发送数组,不再包装在 `events` 参数中
package/lib/index.esm.js CHANGED
@@ -1253,7 +1253,11 @@ function (_super) {
1253
1253
 
1254
1254
  _this.DEFAULT_PENDING_REQUESTS_MAX_SIZE = 50; // LocalStorage 最大大小限制(4MB)
1255
1255
 
1256
- _this.MAX_STORAGE_SIZE = 4 * 1024 * 1024; // 用户信息
1256
+ _this.MAX_STORAGE_SIZE = 4 * 1024 * 1024; // IntersectionObserver 实例
1257
+
1258
+ _this.exposureObserver = null; // 曝光元素映射
1259
+
1260
+ _this.exposureElementsMap = new Map(); // 用户信息
1257
1261
 
1258
1262
  _this.userInfo = null; // 当前路由
1259
1263
 
@@ -1267,7 +1271,8 @@ function (_super) {
1267
1271
  PageView: "Web 浏览页面",
1268
1272
  WebClick: "Web 元素点击",
1269
1273
  PageRetained: "Web 页面浏览时长",
1270
- CustomTrack: "Web 自定义代码上报"
1274
+ CustomTrack: "Web 自定义代码上报",
1275
+ WebExposure: "Web 元素曝光"
1271
1276
  };
1272
1277
  /**
1273
1278
  * @description 初始化函数
@@ -1312,6 +1317,11 @@ function (_super) {
1312
1317
 
1313
1318
  if (_this.initConfig.autoTrackPageDurationInterval) {
1314
1319
  _this.startPageDurationTimer();
1320
+ } // 如果启用了曝光监听,初始化曝光监听
1321
+
1322
+
1323
+ if (_this.initConfig.autoTrackExposure) {
1324
+ _this.initExposureObserver();
1315
1325
  }
1316
1326
  };
1317
1327
  /**
@@ -1372,6 +1382,13 @@ function (_super) {
1372
1382
  _this.startPageDurationTimer();
1373
1383
  } else {
1374
1384
  _this.stopPageDurationTimer();
1385
+ } // 处理曝光监听配置
1386
+
1387
+
1388
+ if (_this.initConfig.autoTrackExposure) {
1389
+ _this.initExposureObserver();
1390
+ } else {
1391
+ _this.stopExposureObserver();
1375
1392
  }
1376
1393
  };
1377
1394
  /**
@@ -1454,6 +1471,36 @@ function (_super) {
1454
1471
 
1455
1472
  break;
1456
1473
 
1474
+ case 'exposureThreshold':
1475
+ if (typeof value !== 'number' || value < 0 || value > 1) {
1476
+ return {
1477
+ valid: false,
1478
+ message: 'exposureThreshold 必须是 0-1 之间的数字'
1479
+ };
1480
+ }
1481
+
1482
+ break;
1483
+
1484
+ case 'exposureTime':
1485
+ if (typeof value !== 'number' || value <= 0) {
1486
+ return {
1487
+ valid: false,
1488
+ message: 'exposureTime 必须是大于 0 的数字'
1489
+ };
1490
+ }
1491
+
1492
+ break;
1493
+
1494
+ case 'exposureNum':
1495
+ if (value !== undefined && (typeof value !== 'number' || value <= 0 || !Number.isInteger(value))) {
1496
+ return {
1497
+ valid: false,
1498
+ message: 'exposureNum 必须是大于 0 的整数或不限制'
1499
+ };
1500
+ }
1501
+
1502
+ break;
1503
+
1457
1504
  case 'showLog':
1458
1505
  case 'autoTrack':
1459
1506
  case 'isTrackSinglePage':
@@ -2780,8 +2827,216 @@ function (_super) {
2780
2827
  return str + ("" + (str.length ? "." : "")) + key;
2781
2828
  }, "");
2782
2829
  };
2830
+ /**
2831
+ * @description 从元素或其祖先节点提取 data-* 属性
2832
+ * @param element 目标元素
2833
+ * @returns 提取的业务参数对象
2834
+ */
2835
+
2836
+
2837
+ _this.extractDataAttributes = function (element) {
2838
+ var business = {};
2839
+ var currentElement = element;
2840
+
2841
+ while (currentElement) {
2842
+ var attributes = currentElement.attributes;
2843
+
2844
+ for (var i = 0; i < attributes.length; i++) {
2845
+ var attr = attributes[i];
2846
+ var name_1 = attr.name;
2847
+
2848
+ if (name_1.startsWith('data-') && name_1 !== 'data-exposure' && name_1 !== 'data-part-key' && name_1 !== 'data-desc') {
2849
+ var value = attr.value;
2850
+
2851
+ if (value) {
2852
+ var camelCaseKey = name_1.replace(/^data-/, '').split('-').map(function (part, index) {
2853
+ return index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1);
2854
+ }).join('');
2855
+ business[camelCaseKey] = value;
2856
+ }
2857
+ }
2858
+ }
2859
+
2860
+ currentElement = currentElement.parentElement;
2861
+
2862
+ if (currentElement && currentElement.tagName === 'BODY') {
2863
+ break;
2864
+ }
2865
+ }
2866
+
2867
+ return business;
2868
+ };
2869
+ /**
2870
+ * @description 初始化曝光监听
2871
+ */
2872
+
2873
+
2874
+ _this.initExposureObserver = function () {
2875
+ if (!_this.initConfig.autoTrackExposure) {
2876
+ return;
2877
+ }
2878
+
2879
+ if (!('IntersectionObserver' in window)) {
2880
+ if (_this.initConfig.showLog) {
2881
+ _this.printLog('当前浏览器不支持 IntersectionObserver,无法启用曝光埋点');
2882
+ }
2883
+
2884
+ return;
2885
+ }
2886
+
2887
+ var threshold = _this.initConfig.exposureThreshold || 0.5;
2888
+ _this.exposureObserver = new IntersectionObserver(function (entries) {
2889
+ entries.forEach(function (entry) {
2890
+ var element = entry.target;
2891
+
2892
+ var elementInfo = _this.exposureElementsMap.get(element);
2893
+
2894
+ if (!elementInfo) {
2895
+ return;
2896
+ }
2897
+
2898
+ var exposureTime = _this.initConfig.exposureTime || 500;
2899
+
2900
+ if (entry.isIntersecting) {
2901
+ elementInfo.isVisible = true;
2902
+ elementInfo.visibleStartTime = _this.getTimeStamp();
2903
+
2904
+ if (elementInfo.exposureTimer) {
2905
+ clearTimeout(elementInfo.exposureTimer);
2906
+ }
2907
+
2908
+ elementInfo.exposureTimer = window.setTimeout(function () {
2909
+ if (elementInfo.isVisible) {
2910
+ _this.reportExposure(element);
2911
+ }
2912
+ }, exposureTime);
2913
+ } else {
2914
+ elementInfo.isVisible = false;
2915
+
2916
+ if (elementInfo.exposureTimer) {
2917
+ clearTimeout(elementInfo.exposureTimer);
2918
+ elementInfo.exposureTimer = null;
2919
+ }
2920
+ }
2921
+ });
2922
+ }, {
2923
+ threshold: threshold
2924
+ });
2925
+
2926
+ _this.observeExposureElements();
2927
+ };
2928
+ /**
2929
+ * @description 监听页面上的曝光元素
2930
+ */
2931
+
2932
+
2933
+ _this.observeExposureElements = function () {
2934
+ if (!_this.exposureObserver) {
2935
+ return;
2936
+ }
2937
+
2938
+ var elements = document.querySelectorAll('[data-exposure="true"]');
2939
+ elements.forEach(function (element) {
2940
+ if (!_this.exposureElementsMap.has(element)) {
2941
+ var htmlElement = element;
2942
+
2943
+ _this.exposureElementsMap.set(htmlElement, {
2944
+ element: htmlElement,
2945
+ visibleStartTime: 0,
2946
+ exposureCount: 0,
2947
+ isVisible: false,
2948
+ exposureTimer: null
2949
+ });
2950
+
2951
+ _this.exposureObserver.observe(htmlElement);
2952
+ }
2953
+ });
2954
+
2955
+ if (_this.initConfig.showLog && elements.length > 0) {
2956
+ _this.printLog("\u5DF2\u76D1\u542C " + elements.length + " \u4E2A\u66DD\u5149\u5143\u7D20");
2957
+ }
2958
+ };
2959
+ /**
2960
+ * @description 上报曝光事件
2961
+ * @param element 曝光元素
2962
+ */
2963
+
2964
+
2965
+ _this.reportExposure = function (element) {
2966
+ var elementInfo = _this.exposureElementsMap.get(element);
2967
+
2968
+ if (!elementInfo) {
2969
+ return;
2970
+ }
2971
+
2972
+ var exposureNum = _this.initConfig.exposureNum;
2973
+
2974
+ if (exposureNum !== undefined && elementInfo.exposureCount >= exposureNum) {
2975
+ if (_this.initConfig.showLog) {
2976
+ _this.printLog("\u5143\u7D20\u5DF2\u8FBE\u5230\u6700\u5927\u66DD\u5149\u6B21\u6570\u9650\u5236: " + exposureNum);
2977
+ }
2978
+
2979
+ return;
2980
+ }
2981
+
2982
+ var business = _this.extractDataAttributes(element);
2983
+
2984
+ var desc = element.getAttribute('data-desc') || _this.eventDescMap['WebExposure'];
2985
+
2986
+ var partkey = element.getAttribute('data-part-key') || 'exposure';
2987
+
2988
+ var params = _this.getParams({
2989
+ event: 'WebExposure',
2990
+ desc: desc,
2991
+ itemKey: _this.getItemKey(partkey),
2992
+ privateParamMap: {
2993
+ business: business
2994
+ }
2995
+ });
2996
+
2997
+ _this.sendData(params).then(function () {
2998
+ elementInfo.exposureCount++;
2999
+
3000
+ if (elementInfo.exposureTimer) {
3001
+ clearTimeout(elementInfo.exposureTimer);
3002
+ elementInfo.exposureTimer = null;
3003
+ }
3004
+
3005
+ if (_this.initConfig.showLog) {
3006
+ _this.printLog("\u66DD\u5149\u4E0A\u62A5\u6210\u529F\uFF0C\u5F53\u524D\u66DD\u5149\u6B21\u6570: " + elementInfo.exposureCount);
3007
+ }
3008
+ }).catch(function (err) {
3009
+ if (_this.initConfig.showLog) {
3010
+ _this.printLog("\u66DD\u5149\u4E0A\u62A5\u5931\u8D25: " + err);
3011
+ }
3012
+ });
3013
+ };
3014
+ /**
3015
+ * @description 停止曝光监听
3016
+ */
3017
+
3018
+
3019
+ _this.stopExposureObserver = function () {
3020
+ if (_this.exposureObserver) {
3021
+ _this.exposureObserver.disconnect();
3022
+
3023
+ _this.exposureObserver = null;
3024
+
3025
+ _this.exposureElementsMap.forEach(function (elementInfo) {
3026
+ if (elementInfo.exposureTimer) {
3027
+ clearTimeout(elementInfo.exposureTimer);
3028
+ }
3029
+ });
3030
+
3031
+ _this.exposureElementsMap.clear();
3032
+
3033
+ if (_this.initConfig.showLog) {
3034
+ _this.printLog('曝光监听已停止');
3035
+ }
3036
+ }
3037
+ };
2783
3038
 
2784
- _this.sdkVersion = "1.2.3"; // sdk版本
3039
+ _this.sdkVersion = "1.2.4"; // sdk版本
2785
3040
 
2786
3041
  _this.initConfig = {
2787
3042
  appKey: "",
@@ -2802,7 +3057,11 @@ function (_super) {
2802
3057
  pendingRequestsMaxSize: 50,
2803
3058
  autoTrackPageDurationInterval: false,
2804
3059
  pageDurationInterval: 30000,
2805
- sendMethod: "auto" // 数据发送方式:auto(自动选择)、xhr(XMLHttpRequest)、beacon(sendBeacon)
3060
+ sendMethod: "auto",
3061
+ autoTrackExposure: false,
3062
+ exposureThreshold: 0.5,
3063
+ exposureTime: 500,
3064
+ exposureNum: undefined // 同一元素允许上报的最大曝光次数,不限制
2806
3065
 
2807
3066
  }; // 系统信息
2808
3067
 
@@ -1 +1 @@
1
- function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,n)};var n=function(){return(n=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)};function r(e,t){for(var n=0,r=t.length,i=e.length;n<r;n++,i++)e[i]=t[n];return e}var i=new(function(i){function a(){var t=i.call(this)||this;return t.batchTimer=null,t.BATCH_QUEUE_STORAGE_KEY="web_tracking_batch_queue",t.useCustomPageKey=!1,t.isUnloadListenerSetup=!1,t.pageDurationTimer=null,t.PENDING_REQUESTS_STORAGE_KEY="web_tracking_pending_requests",t.DEFAULT_PENDING_REQUESTS_MAX_SIZE=50,t.MAX_STORAGE_SIZE=4194304,t.userInfo=null,t.currentUrl="",t.pageKey="",t.deviceId="",t.eventDescMap={PageView:"Web 浏览页面",WebClick:"Web 元素点击",PageRetained:"Web 页面浏览时长",CustomTrack:"Web 自定义代码上报"},t.init=function(e){t.preset(e);var n=window.location.pathname;t.currentUrl=window.location.href,e.pageKey?(t.pageKey=e.pageKey,t.useCustomPageKey=!0):(t.pageKey=n.replace(/\//g,"_").substring(1),t.useCustomPageKey=!1),t.systemsInfo=t.getSystemsInfo(e.platform),t.deviceId=t.getDeviceId(),e.userInfo&&t.isObject(e.userInfo)&&(t.userInfo=e.userInfo),t.setCookie("retainedStartTime",t.getTimeStamp()),t.initConfig.batchSend&&t.restoreBatchQueueFromStorage(),t.restorePendingRequestsFromStorage(),t.setupBeforeUnloadListener(),t.initConfig.autoTrackPageDurationInterval&&t.startPageDurationTimer()},t.preset=function(e){if(e instanceof Object){if(void 0!==e.pageKey)if(null===e.pageKey||""===e.pageKey){t.useCustomPageKey=!1;var n=window.location.pathname;t.pageKey=n.replace(/\//g,"_").substring(1)}else t.pageKey=e.pageKey,t.useCustomPageKey=!0;t.each(e,(function(e,n){if("pageKey"!==n&&t.initConfig.hasOwnProperty(n)){var r=t.validateConfigParam(String(n),e);r.valid?t.initConfig[n]=e:t.printLog("配置参数验证失败: "+String(n)+" = "+e+", 原因: "+r.message)}}))}/^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-\(\)]*[\w@?^=%&/~+#-\(\)])?$/.test(t.initConfig.serverUrl)||(t.printLog("当前 server_url 为空或不正确,只在控制台打印日志,network 中不会发数据,请配置正确的 server_url!"),t.initConfig.showLog=!0),t.initConfig.autoTrack||t.initConfig.trackPartKeyClick?t.listener():t.unlistener(),t.initConfig.autoTrackPageDurationInterval?t.startPageDurationTimer():t.stopPageDurationTimer()},t.validateConfigParam=function(t,n){switch(t){case"sampleRate":if("number"!=typeof n||n<0||n>1)return{valid:!1,message:"sampleRate 必须是 0-1 之间的数字"};break;case"sendTimeout":if("number"!=typeof n||n<=0)return{valid:!1,message:"sendTimeout 必须是大于 0 的数字"};break;case"batchInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"batchInterval 必须是大于 0 的数字"};break;case"batchMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"batchMaxSize 必须是大于 0 的整数"};break;case"pendingRequestsMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"pendingRequestsMaxSize 必须是大于 0 的整数"};break;case"pageDurationInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"pageDurationInterval 必须是大于 0 的数字"};break;case"sendMethod":if("string"!=typeof n||!["auto","xhr","beacon"].includes(n))return{valid:!1,message:"sendMethod 必须是 auto、xhr 或 beacon"};break;case"showLog":case"autoTrack":case"isTrackSinglePage":case"batchSend":case"trackPartKeyClick":case"autoTrackPageDurationInterval":if("boolean"!=typeof n)return{valid:!1,message:t+" 必须是布尔值"};break;case"business":case"header":if(null!==n&&"object"!==e(n))return{valid:!1,message:t+" 必须是对象或 null"};break;case"contentType":if("application/json"!==n&&"application/x-www-form-urlencoded"!==n)return{valid:!1,message:"contentType 必须是 application/json 或 application/x-www-form-urlencoded"};break;case"platform":if("string"!=typeof n)return{valid:!1,message:"platform 必须是字符串"}}return{valid:!0}},t.login=function(e){t.isObject(e)&&(t.userInfo=e)},t.getDeviceId=function(){if(t.deviceId)return t.deviceId;var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return t.deviceId=e,t.deviceId;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),t.deviceId=r,t.deviceId},t.resetDeviceId=function(){return document.cookie="device_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;",localStorage.removeItem("device_id"),t.deviceId="",t.getDeviceId()},t.track=function(e){var n=e.desc,r=e.pageKey,i=e.partkey,a=e.business,o=e.header,s=t.getParams({desc:n,event:"CustomTrack",itemKey:t.getItemKey(i,r),privateParamMap:{business:a}});return t.sendData(s,o)},t.listener=function(){t.unlistener(),t.initConfig.autoTrack&&(t.initConfig.isTrackSinglePage&&(t.rewriteHistory(),t.addSinglePageEvent(t.onPageViewCallback)),t.each(["load","beforeunload"],(function(e){t.addEventListener(window,e,t.onPageViewCallback)}))),(t.initConfig.autoTrack||t.initConfig.trackPartKeyClick)&&t.addEventListener(window,"click",t.onClickCallback)},t.unlistener=function(){if(t.initConfig.isTrackSinglePage){var e=window.history.pushState?"popstate":"hashchange";t.each(["pushState","replaceState",e],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)}))}t.each(["load","beforeunload"],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)})),t.removeEventListener(window,"click",t.onClickCallback),t.clearBatchTimer(),t.stopPageDurationTimer()},t.clearBatchTimer=function(){null!==t.batchTimer&&(clearTimeout(t.batchTimer),t.batchTimer=null)},t.clearBatchQueue=function(){t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("批量队列已清空")},t.getBatchQueueFromStorage=function(){try{var e=t.getLocalStorage(t.BATCH_QUEUE_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取批量队列失败: "+e),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]")}return[]},t.saveBatchQueueToStorage=function(e){try{var n=JSON.stringify(e);if(n.length>t.MAX_STORAGE_SIZE){var r=Math.floor(.8*e.length),i=e.slice(-r);t.printLog("队列过大,已截断保留最新 "+r+" 条数据(限制: "+t.MAX_STORAGE_SIZE/1024/1024+"MB)"),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(i))}else t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,n)}catch(e){t.printLog("保存批量队列到 LocalStorage 失败: "+e)}},t.getPendingRequestsFromStorage=function(){try{var e=t.getLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取待发送请求失败: "+e),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]")}return[]},t.savePendingRequestsToStorage=function(e){try{t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}},t.setPageKey=function(e,n){if(void 0===n&&(n=!1),null===e||""===e){t.useCustomPageKey=!1;var r=window.location.pathname;t.pageKey=r.replace(/\//g,"_").substring(1),t.initConfig.showLog&&t.printLog("页面标识已恢复自动生成: "+t.pageKey)}else t.pageKey=e,t.useCustomPageKey=!n,t.initConfig.showLog&&t.printLog("页面标识已设置为: "+e+", 自动更新: "+n)},t.getPageKey=function(){return t.pageKey},t.onClickCallback=function(e){var n,r=e.target;if(null===(n=null==r?void 0:r.dataset)||void 0===n?void 0:n.partKey){var i=[e.pageX,e.pageY],a=r.id,o=r.className,s={id:a,nodeName:r.nodeName,className:o,position:i},c=t.getParams({event:"WebClick",desc:t.eventDescMap.WebClick,itemKey:t.getItemKey(r.dataset.partKey),privateParamMap:{targetEle:s,pointerType:e.pointerType,currentUrl:t.currentUrl,elementSelector:t.getDomSelector(r)||""}});t.sendData(c)}},t.onPageViewCallback=function(e){var n,r,i=t.getPendingRequestsFromStorage(),a=t.initConfig.batchSend?t.getBatchQueueFromStorage():[];(i.length>0||a.length>0)&&t.flushPendingData();var o=window.location.origin,s=t.getParams({event:"PageView",desc:t.eventDescMap.PageView,privateParamMap:{currentUrl:t.currentUrl,targetUrl:(null===(n=e.arguments)||void 0===n?void 0:n[2])?o+(null===(r=e.arguments)||void 0===r?void 0:r[2]):null}});t.currentUrl=window.location.href,t.useCustomPageKey||(t.pageKey=window.location.pathname.replace(/\//g,"_").substring(1)),t.initConfig.autoTrackPageDurationInterval&&(t.stopPageDurationTimer(),t.startPageDurationTimer()),t.sendRetained(e.type),t.sendData(s)},t.getParams=function(e){var n=e.event,r=e.desc,i=e.privateParamMap,a=void 0===i?{}:i,o=e.itemKey,s=t.initConfig.business,c=window.innerWidth,u=window.innerHeight,g=window.screen.width,l=window.screen.height,d=t.filterSensitiveData(s||{}),p=t.filterSensitiveData(t.userInfo||{}),f=t.filterSensitiveData(a||{}),h=t.filterSensitiveData(t.getQueryValue()||{}),m={currentUrl:f.currentUrl||t.currentUrl,business:Object.assign({},d,f.business||{}),pageWidth:c,pageHeight:u,screenWidth:g,screenHeight:l,sdkVersion:t.sdkVersion,systemsInfo:t.systemsInfo,urlParams:h,userInfo:p,deviceId:t.deviceId};return f.targetEle&&(m.targetEle=f.targetEle),f.targetUrl&&(m.targetUrl=f.targetUrl),f.pointerType&&(m.pointerType=f.pointerType),f.elementSelector&&(m.elementSelector=f.elementSelector),f.retainedDuration&&(m.retainedDuration=f.retainedDuration),{event:n,desc:r,itemKey:o||t.getItemKey(),requestTime:t.getTimeStamp(),privateParamMap:m}},t.shouldSample=function(){var e=t.initConfig.sampleRate;return e>=1||!(e<=0)&&Math.random()<e},t.flushBatchQueue=function(){var e=t.getBatchQueueFromStorage();if(0!==e.length){var n=t.getTimeStamp(),r=e.filter((function(e){return!e._nextRetryTime||e._nextRetryTime<=n}));if(0!==r.length){var i=e.filter((function(e){return!!e._nextRetryTime&&e._nextRetryTime>n}));t.saveBatchQueueToStorage(i),t.sendBatchData(r)}else t.initConfig.showLog&&t.printLog("批量队列中有 "+e.length+" 条数据等待重试")}},t.sendBatchData=function(e){var n=t.initConfig,r=n.serverUrl,i=n.contentType,a=n.showLog,o=n.sendMethod,s=n.header;if(a&&(t.printLog("批量发送 "+e.length+" 条数据"),e.forEach((function(e){return t.printLog(e)}))),t.shouldUseBeacon(o,void 0,s))try{var c=new Blob([JSON.stringify(e)],{type:i||"application/json"});navigator.sendBeacon(r,c)?(t.saveBatchQueueToStorage([]),a&&t.printLog("批量发送成功: "+e.length+" 条数据")):(t.printLog("批量发送失败: sendBeacon 返回 false,数据已重新加入队列"),t.retryBatchData(e))}catch(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}else t.ajax({url:r,type:"POST",data:JSON.stringify({events:e}),contentType:i,credentials:!1,timeout:t.initConfig.sendTimeout,cors:!0,success:function(){t.saveBatchQueueToStorage([]),t.initConfig.showLog&&t.printLog("批量发送成功: "+e.length+" 条数据")},error:function(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}})},t.retryBatchData=function(e){var n=t.getBatchQueueFromStorage(),i=function(e){return e.event+"_"+e.itemKey+"_"+e.requestTime},a=new Set(n.map(i)),o=t.getTimeStamp(),s=e.filter((function(e){var n=i(e);if(a.has(n))return!1;var r=(e._retryCount||0)+1;return r>3?(t.initConfig.showLog&&t.printLog("数据已达到最大重试次数,放弃重试: "+n),!1):(e._retryCount=r,e._nextRetryTime=o+1e3*Math.pow(2,r),a.add(n),!0)})),c=r(r([],s),n),u=2*t.initConfig.batchMaxSize,g=c.length>u?c.slice(0,u):c;t.saveBatchQueueToStorage(g),t.initConfig.showLog&&t.printLog("已将 "+s.length+" 条数据加入重试队列")},t.addToBatchQueue=function(e){var n=t.initConfig,r=n.batchInterval,i=n.batchMaxSize;if(t.shouldSample()){var a=t.getBatchQueueFromStorage();a.push(e),t.saveBatchQueueToStorage(a),a.length>=i?t.flushBatchQueue():t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}else t.initConfig.showLog&&t.printLog("数据已采样跳过(批量模式)")},t.restoreBatchQueueFromStorage=function(){var e=t.getBatchQueueFromStorage();if(e.length>0){t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送数据");var n=t.initConfig.batchMaxSize;if(e.length>=n)t.flushBatchQueue();else{var r=t.initConfig.batchInterval;t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}}},t.addToPendingRequests=function(e){var n=t.getPendingRequestsFromStorage();n.push(e);var r=t.initConfig.pendingRequestsMaxSize||t.DEFAULT_PENDING_REQUESTS_MAX_SIZE;if(n.length>r){var i=n.slice(-r);t.initConfig.showLog&&t.printLog("待发送请求队列已满,已移除最旧的数据(最大限制: "+r+")"),t.savePendingRequestsToStorage(i)}else t.savePendingRequestsToStorage(n)},t.restorePendingRequestsFromStorage=function(){var e=t.getPendingRequestsFromStorage();e.length>0&&t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送请求")},t.isPageUnloading=function(){return"hidden"===document.visibilityState},t.sendWithBeacon=function(e,n,r){try{var i=new Blob([JSON.stringify(e)],{type:r||"application/json"});return navigator.sendBeacon(n,i)}catch(e){return t.initConfig.showLog&&t.printLog("sendBeacon 发送失败: "+e),!1}},t.flushPendingRequests=function(){var e=t.getPendingRequestsFromStorage();if(0!==e.length){t.savePendingRequestsToStorage([]);var n=t.initConfig,r=n.serverUrl,i=n.sendTimeout,a=n.contentType,o=n.showLog,s=n.header;e.forEach((function(e){t.shouldSample()?(o&&t.printLog(e),t.ajax({header:s,url:r,type:"POST",data:JSON.stringify(e),contentType:a,credentials:!1,timeout:i,cors:!0,success:function(){o&&t.printLog("待发送请求发送成功")},error:function(e){o&&t.printLog("待发送请求发送失败(不再重试): "+e)}})):o&&t.printLog("待发送请求已采样跳过")}))}},t.setupBeforeUnloadListener=function(){t.isUnloadListenerSetup||(t.isUnloadListenerSetup=!0,document.addEventListener("visibilitychange",(function(){t.isPageUnloading()&&t.flushPendingData()})),window.addEventListener("beforeunload",(function(){t.flushPendingData()})),window.addEventListener("pagehide",(function(){t.flushPendingData()})))},t.isFlushingPendingData=!1,t.flushPendingData=function(){if(!t.isFlushingPendingData){t.stopPageDurationTimer();var e=[],n=t.getBatchQueueFromStorage();n.length>0&&e.push.apply(e,n);var r=t.getPendingRequestsFromStorage();if(r.length>0&&e.push.apply(e,r),0!==e.length){t.isFlushingPendingData=!0;try{t.initConfig.batchSend?t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(e)):t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.initConfig.showLog&&t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}if(navigator.sendBeacon&&t.initConfig.serverUrl)try{var i=1===e.length?e[0]:e,a=new Blob([JSON.stringify(i)],{type:t.initConfig.contentType||"application/json"});navigator.sendBeacon(t.initConfig.serverUrl,a)?(t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("页面卸载时成功发送 "+e.length+" 条数据")):t.initConfig.showLog&&t.printLog("sendBeacon 返回 false,数据已保存到 LocalStorage 等待下次恢复")}catch(e){t.initConfig.showLog&&t.printLog("页面卸载时发送数据失败: "+e+",数据已保存到 LocalStorage")}finally{t.isFlushingPendingData=!1}else t.initConfig.showLog&&t.printLog("不支持 sendBeacon,数据已保存到 LocalStorage 等待下次恢复"),t.isFlushingPendingData=!1}}},t.sendData=function(e,n){if(!t.shouldSample())return Promise.resolve({success:!0,message:"数据已采样跳过"});var r=t.initConfig,i=r.serverUrl,a=r.sendTimeout,o=r.contentType,s=r.showLog,c=r.header,u=r.batchSend,g=r.sendMethod;return s&&t.printLog(e),u?(t.addToBatchQueue(e),Promise.resolve({success:!0,message:"已添加到批量队列"})):t.shouldUseBeacon(g,n,c)?t.isPageUnloading()?t.sendWithBeacon(e,i,o)?Promise.resolve({success:!0,message:"页面卸载时发送成功"}):(t.addToPendingRequests(e),Promise.resolve({success:!0,message:"已添加到待发送队列"})):t.sendBeacon({contentType:o,url:i,data:e}).catch((function(n){return t.addToPendingRequests(e),Promise.resolve({success:!0,message:"sendBeacon 失败,已添加到待发送队列"})})):new Promise((function(r,s){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!c&&t.sendWithBeacon(e,i,o))return void r({success:!0,message:"页面卸载时使用 sendBeacon 发送成功"});t.ajax({header:n||c,url:i,type:"POST",data:JSON.stringify(e),contentType:o,credentials:!1,timeout:a,cors:!0,success:function(e){return r({success:!0,data:e})},error:function(a,u){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!c&&t.sendWithBeacon(e,i,o))return void r({success:!0,message:"XMLHttpRequest 失败,已使用 sendBeacon 发送"});s({success:!1,message:String(a),code:u})}})}))},t.shouldUseBeacon=function(e,n,r){return"xhr"!==e&&("beacon"===e?!0===t.isSupportBeaconSend():!0===t.isSupportBeaconSend()&&!n&&!r)},t.sendRetained=function(e){var r=t.getParams({event:"PageRetained",desc:t.eventDescMap.PageRetained});if(["beforeunload","pushState","replaceState","hashchange","popstate"].indexOf(e)>=0){var i=t.getCookie("retainedStartTime"),a=i?+i:t.getTimeStamp(),o=n(n({},r),{privateParamMap:n(n({},r.privateParamMap),{retainedDuration:Math.max(r.requestTime-a,0)})});t.sendData(o),t.setCookie("retainedStartTime",t.getTimeStamp())}},t.trackPageDuration=function(e,n,r){var i;if(void 0===r&&(r=!0),null!=e)i=Math.max(e,0);else{var a=t.getCookie("retainedStartTime"),o=a?+a:t.getTimeStamp(),s=t.getTimeStamp();i=Math.max(s-o,0)}var c=(null==n?void 0:n.desc)||t.eventDescMap.PageRetained,u=(null==n?void 0:n.pageKey)||t.pageKey,g=(null==n?void 0:n.business)||{},l=null==n?void 0:n.header,d=t.getParams({event:"PageRetained",desc:c,itemKey:t.getItemKey(void 0,u),privateParamMap:{business:g,retainedDuration:i}}),p=t.sendData(d,l);return r&&t.setCookie("retainedStartTime",t.getTimeStamp()),p},t.startPageDurationTimer=function(){t.stopPageDurationTimer();var e=t.initConfig.pageDurationInterval||3e4;e<=0?t.initConfig.showLog&&t.printLog("定时上报间隔时间无效,已禁用定时上报"):(t.pageDurationTimer=window.setInterval((function(){"visible"===document.visibilityState&&t.trackPageDuration(e,{desc:"定时上报页面停留时长",business:{reportType:"interval",interval:e}},!0).catch((function(e){t.initConfig.showLog&&t.printLog("定时上报页面停留时长失败: "+e)}))}),e),t.initConfig.showLog&&t.printLog("定时上报页面停留时长已启动,间隔: "+e+"ms"))},t.stopPageDurationTimer=function(){null!==t.pageDurationTimer&&(clearInterval(t.pageDurationTimer),t.pageDurationTimer=null,t.initConfig.showLog&&t.printLog("定时上报页面停留时长已停止"))},t.getItemKey=function(e,n){return[t.initConfig.appKey,(n||t.pageKey).toString(),e?e.toString():void 0].filter((function(e){return!!e})).reduce((function(e,t){return e+(e.length?".":"")+t}),"")},t.sdkVersion="1.2.3",t.initConfig={appKey:"",platform:void 0,showLog:!1,serverUrl:"",autoTrack:!1,sendTimeout:3e3,isTrackSinglePage:!1,contentType:"application/json",business:{},header:void 0,sampleRate:1,batchSend:!1,batchInterval:5e3,batchMaxSize:10,trackPartKeyClick:!1,pendingRequestsMaxSize:50,autoTrackPageDurationInterval:!1,pageDurationInterval:3e4,sendMethod:"auto"},t.systemsInfo={},t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(a,i),a.prototype.addSinglePageEvent=function(e){var t=this,n=window.history.pushState?"popstate":"hashchange";this.each(["pushState","replaceState",n],(function(n){t.addEventListener(window,n,e)}))},a}(function(){function t(){var t=this;this.getSystemsInfo=function(e){var t=navigator.userAgent,n="other",r=[],i={language:navigator.language},a=t.match(/MicroMessenger\/([\d\.]+)/i),o=a&&a[1]?a[1]:null,s=t.match(/(ipod).*\s([\d_]+)/i),c=t.match(/(ipad).*\s([\d_]+)/i),u=t.match(/(iphone)\sos\s([\d_]+)/i),g=t.match(/(android)\s([\d\.]+)/i),l=t.match(/(Windows NT)\s([\d\.]+)/i),d=t.match(/(Mac OS X)\s([\d_]+)/i);r=[],g?(r.push("Android "+g[2]),n="h5"):u?(r.push("iPhone, iOS "+u[2].replace(/_/g,".")),n="h5"):c?(r.push("iPad, iOS "+c[2].replace(/_/g,".")),n="ipad"):s?(r.push("iPod, iOS "+s[2].replace(/_/g,".")),n="h5"):l?(r.push("Windows "+l[2].replace(/_/g,".")),n="pc"):d&&(r.push("Mac, MacOS "+d[2].replace(/_/g,".")),n="pc"),o&&r.push("WeChat "+o),i.client=r.length?r.join(", "):"Unknown",i.platform=e||n;var p=t.toLowerCase().match(/ nettype\/([^ ]+)/g);return p&&p[0]&&(r=[(p=p[0].split("/"))[1]],i.network=r.length?r.join(", "):"Unknown"),i.ua=t,i},this.addEventListener=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,(function(t){return n.call(e,t)}),!1)},this.removeEventListener=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n):e.detachEvent&&e.detachEvent("on"+t,(function(t){return n.call(e,t)}),!0)},this.rewriteHistory=function(){var e=window.history,t=function(e){var t=window.history,n=t[e],r=new Event(e);return function(){var e=n.apply(t,arguments);return r.arguments=arguments,window.dispatchEvent(r),e}};window.history.pushState&&(e.pushState=t("pushState"),e.replaceState=t("replaceState"))},this.isArray=Array.isArray||function(e){return"[object Array]"===toString.call(e)},this.formatJsonString=function(e){try{return JSON.stringify(e,null," ")}catch(t){return JSON.stringify(e)}},this.nativeForEach=Array.prototype.forEach,this.slice=Array.prototype.slice,this.hasOwnProperty=Object.prototype.hasOwnProperty,this.breaker={},this.each=function(e,n,r){if(null==e)return!1;if(t.nativeForEach&&e.forEach===t.nativeForEach)e.forEach(n,r);else if(t.isArray(e)&&e.length===+e.length){for(var i=0,a=e.length;i<a;i++)if(i in e&&n.call(r,e[i],i,e)===t.breaker)return!1}else for(var o in e)if(t.hasOwnProperty.call(e,o)&&n.call(r,e[o],o,e)===t.breaker)return!1;return!0},this.getDomIndex=function(e){if(!e.parentNode)return-1;for(var t=0,n=e.tagName,r=e.parentNode.children,i=0;i<r.length;i++)if(r[i].tagName===n){if(e===r[i])return t;t++}return-1},this.selector=function(e){var n=e.parentNode&&9==e.parentNode.nodeType?-1:t.getDomIndex(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~n?":nth-of-type("+(n+1)+")":"")},this.getDomSelector=function(e,n){if(!e||!e.parentNode||!e.parentNode.children)return!1;n=n&&n.join?n:[];var r=e.nodeName.toLowerCase();return e&&"body"!==r&&1==e.nodeType?(n.unshift(t.selector(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?n.join(" > "):t.getDomSelector(e.parentNode,n)):(n.unshift("body"),n.join(" > "))},this.getCookie=function(e){for(var t=e+"=",n=document.cookie.split(";"),r=0;r<n.length;r++){for(var i=n[r];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(t))return this._decodeURIComponent(i.substring(t.length,i.length))}return null},this.setCookie=function(e,t,n){var r,i="";n=null==n?73e3:n;var a=this.getMainHost();if(r=a?"; domain="+a:"",0!==n){var o=new Date;"s"===String(n).slice(-1)?o.setTime(o.getTime()+1e3*Number(String(n).slice(0,-1))):o.setTime(o.getTime()+24*n*60*60*1e3),i="; expires="+o.toUTCString()}function s(e){return e||!1}var c="",u="",g="";e&&(c=s(e)),t&&(u=s(t)),r&&(g=s(r)),c&&u&&(document.cookie=c+"="+encodeURIComponent(u)+i+"; path=/"+g)},this.getLocalStorage=function(e){try{return localStorage.getItem(e)}catch(e){return null}},this.setLocalStorage=function(e,t){try{localStorage.setItem(e,t)}catch(e){}},this.removeCookie=function(e){t.setCookie(e,"",-1)},this.getTimeStamp=function(){return(new Date).getTime()},this.uuid=function(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}))},this.getDistinctId=function(){var e=t.getCookie("distinctId");return e||(e=t.uuid(),t.setCookie("distinctId",e),e)},this.filterSensitiveData=function(e,n){if(void 0===n&&(n=["password","token","secret","key"]),!t.isObject(e))return e;var r={};return t.each(e,(function(e,i){n.some((function(e){return"string"==typeof i&&i.toLowerCase().includes(e.toLowerCase())}))?r[i]="***":t.isObject(e)?r[i]=t.filterSensitiveData(e,n):r[i]=e})),r},this.xssFilter=function(e){return e?"string"!=typeof e?e.toString():e.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""},this.getQueryValue=function(){for(var e=decodeURI(window.location.href).match(new RegExp("[?&][^?&]+=[^?&]+","g"))||[],t={},n=0;n<e.length;n++){var r=e[n].replace(/\?|\&/,"").split("=");t[r[0]]=r[1]}return Object.keys(t).length>0?t:null},this.ajax=function(n){function r(t){if(!t)return{};if("string"==typeof t)try{return JSON.parse(t)}catch(e){return{}}return"object"===e(t)?t:{}}n.timeout=n.timeout||3e4,n.credentials=void 0===n.credentials||n.credentials;var i=t.xhr(n.cors);if(!i)return!1;n.type||(n.type=n.data?"POST":"GET");var a,o=n.success,s=n.error;n.success=function(e){o&&o(e),a&&(clearTimeout(a),a=null)},n.error=function(e,t){s&&s(e,t),a&&(clearTimeout(a),a=null)},a=window.setTimeout((function(){!function(){try{t.isObject(i)&&i.abort&&i.abort()}catch(e){t.printLog(e)}a&&(clearTimeout(a),a=null,n.error&&n.error(),i.onreadystatechange=null,i.onload=null,i.onerror=null)}()}),n.timeout),i.onreadystatechange=function(){try{4==i.readyState&&(i.status>=200&&i.status<300||304==i.status?n.success&&n.success(r(i.responseText)):n.error&&n.error(r(i.responseText),i.status),i.onreadystatechange=null,i.onload=null)}catch(e){i.onreadystatechange=null,i.onload=null}},i.open(n.type||"GET",n.url,!0);try{n.credentials&&(i.withCredentials=!0),t.isObject(n.header)&&t.each(n.header,(function(e,t){i.setRequestHeader&&i.setRequestHeader(t,e)})),n.data&&(n.cors||i.setRequestHeader&&i.setRequestHeader("X-Requested-With","XMLHttpRequest"),"application/json"===n.contentType?i.setRequestHeader&&i.setRequestHeader("Content-type","application/json; charset=UTF-8"):i.setRequestHeader&&i.setRequestHeader("Content-type","application/x-www-form-urlencoded"))}catch(e){t.printLog(e)}i.send(n.data||null)},this.xhr=function(e){return e?void 0!==window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest?new XMLHttpRequest:null:void 0!==window.XMLHttpRequest?new XMLHttpRequest:null},this.getUA=function(){var e,t={},n=navigator.userAgent.toLowerCase();return(e=n.match(/opera.([\d.]+)/))?t.opera=Number(e[1].split(".")[0]):(e=n.match(/msie ([\d.]+)/))?t.ie=Number(e[1].split(".")[0]):(e=n.match(/edge.([\d.]+)/))?t.edge=Number(e[1].split(".")[0]):(e=n.match(/firefox\/([\d.]+)/))?t.firefox=Number(e[1].split(".")[0]):(e=n.match(/chrome\/([\d.]+)/))?t.chrome=Number(e[1].split(".")[0]):(e=n.match(/version\/([\d.]+).*safari/))?t.safari=Number(e[1].match(/^\d*.\d*/)):(e=n.match(/trident\/([\d.]+)/))&&(t.ie=11),t},this.isSupportBeaconSend=function(){var n=!1;if("object"!==("undefined"==typeof navigator?"undefined":e(navigator))||"function"!=typeof navigator.sendBeacon)return n;var r=t.getUA(),i=navigator.userAgent.toLowerCase();if(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)){var a=(i.match(/os [\d._]*/gi)+"").replace(/[^0-9|_.]/gi,"").replace(/_/gi,".").split(".");void 0===r.safari&&(r.safari=Number(a[0])),a[0]&&+a[0]<13?(r.chrome>41||r.firefox>30||r.opera>25||r.safari>12)&&(n=!0):(r.chrome>41||r.firefox>30||r.opera>25||r.safari>11.3)&&(n=!0)}else(r.chrome>38||r.edge>13||r.firefox>30||r.opera>25||r.safari>11)&&(n=!0);return n},this.throttle=function(e,t){var n=null,r=0;return function(){for(var i=[],a=0;a<arguments.length;a++)i[a]=arguments[a];var o=Date.now(),s=t-(o-r);s<=0||s>t?(n&&(clearTimeout(n),n=null),r=o,e.apply(void 0,i)):n||(n=window.setTimeout((function(){r=Date.now(),n=null,e.apply(void 0,i)}),s))}},this.debounce=function(e,t){var n=null;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];n&&clearTimeout(n),n=window.setTimeout((function(){e.apply(void 0,r)}),t)}},this.sendBeacon=function(e){if(!0===t.isSupportBeaconSend()){var n={type:e.contentType},r=new Blob([JSON.stringify(e.data)],n);return navigator.sendBeacon(e.url,r)?Promise.resolve({success:!0,message:"发送成功"}):Promise.reject({success:!1,message:"sendBeacon返回false"})}return Promise.reject({success:!1,message:"不支持sendBeacon,发送失败!"})},this.getDeviceId=function(){var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return e;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),r},this.collectFingerprint=function(){var e={};return e.userAgent=navigator.userAgent,e.screenWidth=screen.width,e.screenHeight=screen.height,e.colorDepth=screen.colorDepth,e.pixelDepth=screen.pixelDepth,e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone,e.timezoneOffset=(new Date).getTimezoneOffset(),e.language=navigator.language,e.languages=Array.from(navigator.languages),e.platform=navigator.platform,e.webgl=t.getWebGLFingerprint(),e.canvas=t.getCanvasFingerprint(),e.audio=t.getAudioFingerprint(),e.fonts=t.getFontFingerprint(),e.plugins=t.getPluginsFingerprint(),e.localStorage=t.hasLocalStorage(),e.sessionStorage=t.hasSessionStorage(),e.indexedDB=t.hasIndexedDB(),e.hardwareConcurrency=navigator.hardwareConcurrency,e.deviceMemory=navigator.deviceMemory,e.maxTouchPoints=navigator.maxTouchPoints,e.connection=t.getConnectionFingerprint(),e},this.getWebGLFingerprint=function(){try{var e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!t)return"not-supported";var n=t.getExtension("WEBGL_debug_renderer_info");return(n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):"unknown")+"|"+(n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):"unknown")}catch(e){return"error"}},this.getCanvasFingerprint=function(){try{var e=document.createElement("canvas");e.width=200,e.height=50;var t=e.getContext("2d");return t?(t.textBaseline="top",t.font="14px Arial",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText("Canvas fingerprint",2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText("Canvas fingerprint",4,17),e.toDataURL().slice(-50)):"not-supported"}catch(e){return"error"}},this.getAudioFingerprint=function(){try{var e=window.AudioContext||window.webkitAudioContext;if(!e)return"not-supported";var t=new e,n=String(t.sampleRate||0);return t.close(),n}catch(e){return"error"}},this.getFontFingerprint=function(){try{var e=["monospace","sans-serif","serif"],t="mmmmmmmmmmlli",n=document.createElement("canvas").getContext("2d");if(!n)return"not-supported";var r=[],i={};return e.forEach((function(e){n.font="72px "+e,i[e]=n.measureText(t).width})),["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Helvetica","Impact","Times New Roman","Trebuchet MS","Verdana"].forEach((function(a){var o=!1;e.forEach((function(e){n.font="72px '"+a+"', "+e,n.measureText(t).width!==i[e]&&(o=!0)})),o&&r.push(a)})),r.join(",")}catch(e){return"error"}},this.getPluginsFingerprint=function(){try{var e=[];if(navigator.plugins)for(var t=0;t<navigator.plugins.length;t++){var n=navigator.plugins[t];n&&e.push(n.name+"|"+n.description+"|"+n.filename)}return e.join(";")}catch(e){return"error"}},this.hasLocalStorage=function(){try{var e="__test__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}},this.hasSessionStorage=function(){try{var e="__test__";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(e){return!1}},this.hasIndexedDB=function(){return"indexedDB"in window&&null!==indexedDB},this.getConnectionFingerprint=function(){try{var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?e.effectiveType||"unknown":"not-supported"}catch(e){return"error"}},this.hashFingerprint=function(e){for(var t=JSON.stringify(e,Object.keys(e).sort()),n=5381,r=52711,i=0;i<t.length;i++){var a=t.charCodeAt(i);n=(n<<5)+n+a,r=(r<<5)+r+a}return"fp_"+(n>>>0).toString(16).padStart(8,"0")+(r>>>0).toString(16).padStart(8,"0")}}return t.prototype.printLog=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];if(this.isObject(t[0])&&(t[0]=this.formatJsonString(t[0])),"object"===("undefined"==typeof console?"undefined":e(console))&&console.log)try{return console.log.apply(console,t)}catch(e){console.log(t[0])}},t.prototype.isObject=function(e){return null!=e&&"[object Object]"==toString.call(e)},t.prototype.isUndefined=function(e){return void 0===e},t.prototype.isString=function(e){return"[object String]"==toString.call(e)},t.prototype.isDate=function(e){return"[object Date]"==toString.call(e)},t.prototype.isBoolean=function(e){return"[object Boolean]"==toString.call(e)},t.prototype.isNumber=function(e){return"[object Number]"==toString.call(e)&&/[\d\.]+/.test(String(e))},t.prototype.isElement=function(e){return!(!e||1!==e.nodeType)},t.prototype.isFunction=function(e){if(!e)return!1;var t=toString.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t},t.prototype.isJSONString=function(e){if(!this.isString(e))return!1;try{JSON.parse(e)}catch(e){return!1}return!0},t.prototype._decodeURIComponent=function(e){var t=e;try{t=decodeURIComponent(e)}catch(n){t=e}return t},t.prototype.getMainHost=function(){var e="mh_"+Math.random(),t=new RegExp("(^|;)\\s*"+e+"=12345"),n=new Date(0),r=document.domain,i=r.split("."),a=[];for(a.unshift(i.pop());i.length;){a.unshift(i.pop());var o=a.join("."),s=e+"=12345;domain=."+o;if(document.cookie=s,t.test(document.cookie))return document.cookie=s+";expires="+n,o}return r},t}()));export default i;
1
+ function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,n)};var n=function(){return(n=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)};function r(e,t){for(var n=0,r=t.length,i=e.length;n<r;n++,i++)e[i]=t[n];return e}var i=new(function(i){function o(){var t=i.call(this)||this;return t.batchTimer=null,t.BATCH_QUEUE_STORAGE_KEY="web_tracking_batch_queue",t.useCustomPageKey=!1,t.isUnloadListenerSetup=!1,t.pageDurationTimer=null,t.PENDING_REQUESTS_STORAGE_KEY="web_tracking_pending_requests",t.DEFAULT_PENDING_REQUESTS_MAX_SIZE=50,t.MAX_STORAGE_SIZE=4194304,t.exposureObserver=null,t.exposureElementsMap=new Map,t.userInfo=null,t.currentUrl="",t.pageKey="",t.deviceId="",t.eventDescMap={PageView:"Web 浏览页面",WebClick:"Web 元素点击",PageRetained:"Web 页面浏览时长",CustomTrack:"Web 自定义代码上报",WebExposure:"Web 元素曝光"},t.init=function(e){t.preset(e);var n=window.location.pathname;t.currentUrl=window.location.href,e.pageKey?(t.pageKey=e.pageKey,t.useCustomPageKey=!0):(t.pageKey=n.replace(/\//g,"_").substring(1),t.useCustomPageKey=!1),t.systemsInfo=t.getSystemsInfo(e.platform),t.deviceId=t.getDeviceId(),e.userInfo&&t.isObject(e.userInfo)&&(t.userInfo=e.userInfo),t.setCookie("retainedStartTime",t.getTimeStamp()),t.initConfig.batchSend&&t.restoreBatchQueueFromStorage(),t.restorePendingRequestsFromStorage(),t.setupBeforeUnloadListener(),t.initConfig.autoTrackPageDurationInterval&&t.startPageDurationTimer(),t.initConfig.autoTrackExposure&&t.initExposureObserver()},t.preset=function(e){if(e instanceof Object){if(void 0!==e.pageKey)if(null===e.pageKey||""===e.pageKey){t.useCustomPageKey=!1;var n=window.location.pathname;t.pageKey=n.replace(/\//g,"_").substring(1)}else t.pageKey=e.pageKey,t.useCustomPageKey=!0;t.each(e,(function(e,n){if("pageKey"!==n&&t.initConfig.hasOwnProperty(n)){var r=t.validateConfigParam(String(n),e);r.valid?t.initConfig[n]=e:t.printLog("配置参数验证失败: "+String(n)+" = "+e+", 原因: "+r.message)}}))}/^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-\(\)]*[\w@?^=%&/~+#-\(\)])?$/.test(t.initConfig.serverUrl)||(t.printLog("当前 server_url 为空或不正确,只在控制台打印日志,network 中不会发数据,请配置正确的 server_url!"),t.initConfig.showLog=!0),t.initConfig.autoTrack||t.initConfig.trackPartKeyClick?t.listener():t.unlistener(),t.initConfig.autoTrackPageDurationInterval?t.startPageDurationTimer():t.stopPageDurationTimer(),t.initConfig.autoTrackExposure?t.initExposureObserver():t.stopExposureObserver()},t.validateConfigParam=function(t,n){switch(t){case"sampleRate":if("number"!=typeof n||n<0||n>1)return{valid:!1,message:"sampleRate 必须是 0-1 之间的数字"};break;case"sendTimeout":if("number"!=typeof n||n<=0)return{valid:!1,message:"sendTimeout 必须是大于 0 的数字"};break;case"batchInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"batchInterval 必须是大于 0 的数字"};break;case"batchMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"batchMaxSize 必须是大于 0 的整数"};break;case"pendingRequestsMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"pendingRequestsMaxSize 必须是大于 0 的整数"};break;case"pageDurationInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"pageDurationInterval 必须是大于 0 的数字"};break;case"sendMethod":if("string"!=typeof n||!["auto","xhr","beacon"].includes(n))return{valid:!1,message:"sendMethod 必须是 auto、xhr 或 beacon"};break;case"exposureThreshold":if("number"!=typeof n||n<0||n>1)return{valid:!1,message:"exposureThreshold 必须是 0-1 之间的数字"};break;case"exposureTime":if("number"!=typeof n||n<=0)return{valid:!1,message:"exposureTime 必须是大于 0 的数字"};break;case"exposureNum":if(void 0!==n&&("number"!=typeof n||n<=0||!Number.isInteger(n)))return{valid:!1,message:"exposureNum 必须是大于 0 的整数或不限制"};break;case"showLog":case"autoTrack":case"isTrackSinglePage":case"batchSend":case"trackPartKeyClick":case"autoTrackPageDurationInterval":if("boolean"!=typeof n)return{valid:!1,message:t+" 必须是布尔值"};break;case"business":case"header":if(null!==n&&"object"!==e(n))return{valid:!1,message:t+" 必须是对象或 null"};break;case"contentType":if("application/json"!==n&&"application/x-www-form-urlencoded"!==n)return{valid:!1,message:"contentType 必须是 application/json 或 application/x-www-form-urlencoded"};break;case"platform":if("string"!=typeof n)return{valid:!1,message:"platform 必须是字符串"}}return{valid:!0}},t.login=function(e){t.isObject(e)&&(t.userInfo=e)},t.getDeviceId=function(){if(t.deviceId)return t.deviceId;var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return t.deviceId=e,t.deviceId;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),t.deviceId=r,t.deviceId},t.resetDeviceId=function(){return document.cookie="device_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;",localStorage.removeItem("device_id"),t.deviceId="",t.getDeviceId()},t.track=function(e){var n=e.desc,r=e.pageKey,i=e.partkey,o=e.business,a=e.header,s=t.getParams({desc:n,event:"CustomTrack",itemKey:t.getItemKey(i,r),privateParamMap:{business:o}});return t.sendData(s,a)},t.listener=function(){t.unlistener(),t.initConfig.autoTrack&&(t.initConfig.isTrackSinglePage&&(t.rewriteHistory(),t.addSinglePageEvent(t.onPageViewCallback)),t.each(["load","beforeunload"],(function(e){t.addEventListener(window,e,t.onPageViewCallback)}))),(t.initConfig.autoTrack||t.initConfig.trackPartKeyClick)&&t.addEventListener(window,"click",t.onClickCallback)},t.unlistener=function(){if(t.initConfig.isTrackSinglePage){var e=window.history.pushState?"popstate":"hashchange";t.each(["pushState","replaceState",e],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)}))}t.each(["load","beforeunload"],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)})),t.removeEventListener(window,"click",t.onClickCallback),t.clearBatchTimer(),t.stopPageDurationTimer()},t.clearBatchTimer=function(){null!==t.batchTimer&&(clearTimeout(t.batchTimer),t.batchTimer=null)},t.clearBatchQueue=function(){t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("批量队列已清空")},t.getBatchQueueFromStorage=function(){try{var e=t.getLocalStorage(t.BATCH_QUEUE_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取批量队列失败: "+e),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]")}return[]},t.saveBatchQueueToStorage=function(e){try{var n=JSON.stringify(e);if(n.length>t.MAX_STORAGE_SIZE){var r=Math.floor(.8*e.length),i=e.slice(-r);t.printLog("队列过大,已截断保留最新 "+r+" 条数据(限制: "+t.MAX_STORAGE_SIZE/1024/1024+"MB)"),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(i))}else t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,n)}catch(e){t.printLog("保存批量队列到 LocalStorage 失败: "+e)}},t.getPendingRequestsFromStorage=function(){try{var e=t.getLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取待发送请求失败: "+e),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]")}return[]},t.savePendingRequestsToStorage=function(e){try{t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}},t.setPageKey=function(e,n){if(void 0===n&&(n=!1),null===e||""===e){t.useCustomPageKey=!1;var r=window.location.pathname;t.pageKey=r.replace(/\//g,"_").substring(1),t.initConfig.showLog&&t.printLog("页面标识已恢复自动生成: "+t.pageKey)}else t.pageKey=e,t.useCustomPageKey=!n,t.initConfig.showLog&&t.printLog("页面标识已设置为: "+e+", 自动更新: "+n)},t.getPageKey=function(){return t.pageKey},t.onClickCallback=function(e){var n,r=e.target;if(null===(n=null==r?void 0:r.dataset)||void 0===n?void 0:n.partKey){var i=[e.pageX,e.pageY],o=r.id,a=r.className,s={id:o,nodeName:r.nodeName,className:a,position:i},u=t.getParams({event:"WebClick",desc:t.eventDescMap.WebClick,itemKey:t.getItemKey(r.dataset.partKey),privateParamMap:{targetEle:s,pointerType:e.pointerType,currentUrl:t.currentUrl,elementSelector:t.getDomSelector(r)||""}});t.sendData(u)}},t.onPageViewCallback=function(e){var n,r,i=t.getPendingRequestsFromStorage(),o=t.initConfig.batchSend?t.getBatchQueueFromStorage():[];(i.length>0||o.length>0)&&t.flushPendingData();var a=window.location.origin,s=t.getParams({event:"PageView",desc:t.eventDescMap.PageView,privateParamMap:{currentUrl:t.currentUrl,targetUrl:(null===(n=e.arguments)||void 0===n?void 0:n[2])?a+(null===(r=e.arguments)||void 0===r?void 0:r[2]):null}});t.currentUrl=window.location.href,t.useCustomPageKey||(t.pageKey=window.location.pathname.replace(/\//g,"_").substring(1)),t.initConfig.autoTrackPageDurationInterval&&(t.stopPageDurationTimer(),t.startPageDurationTimer()),t.sendRetained(e.type),t.sendData(s)},t.getParams=function(e){var n=e.event,r=e.desc,i=e.privateParamMap,o=void 0===i?{}:i,a=e.itemKey,s=t.initConfig.business,u=window.innerWidth,c=window.innerHeight,g=window.screen.width,l=window.screen.height,p=t.filterSensitiveData(s||{}),d=t.filterSensitiveData(t.userInfo||{}),f=t.filterSensitiveData(o||{}),h=t.filterSensitiveData(t.getQueryValue()||{}),m={currentUrl:f.currentUrl||t.currentUrl,business:Object.assign({},p,f.business||{}),pageWidth:u,pageHeight:c,screenWidth:g,screenHeight:l,sdkVersion:t.sdkVersion,systemsInfo:t.systemsInfo,urlParams:h,userInfo:d,deviceId:t.deviceId};return f.targetEle&&(m.targetEle=f.targetEle),f.targetUrl&&(m.targetUrl=f.targetUrl),f.pointerType&&(m.pointerType=f.pointerType),f.elementSelector&&(m.elementSelector=f.elementSelector),f.retainedDuration&&(m.retainedDuration=f.retainedDuration),{event:n,desc:r,itemKey:a||t.getItemKey(),requestTime:t.getTimeStamp(),privateParamMap:m}},t.shouldSample=function(){var e=t.initConfig.sampleRate;return e>=1||!(e<=0)&&Math.random()<e},t.flushBatchQueue=function(){var e=t.getBatchQueueFromStorage();if(0!==e.length){var n=t.getTimeStamp(),r=e.filter((function(e){return!e._nextRetryTime||e._nextRetryTime<=n}));if(0!==r.length){var i=e.filter((function(e){return!!e._nextRetryTime&&e._nextRetryTime>n}));t.saveBatchQueueToStorage(i),t.sendBatchData(r)}else t.initConfig.showLog&&t.printLog("批量队列中有 "+e.length+" 条数据等待重试")}},t.sendBatchData=function(e){var n=t.initConfig,r=n.serverUrl,i=n.contentType,o=n.showLog,a=n.sendMethod,s=n.header;if(o&&(t.printLog("批量发送 "+e.length+" 条数据"),e.forEach((function(e){return t.printLog(e)}))),t.shouldUseBeacon(a,void 0,s))try{var u=new Blob([JSON.stringify(e)],{type:i||"application/json"});navigator.sendBeacon(r,u)?(t.saveBatchQueueToStorage([]),o&&t.printLog("批量发送成功: "+e.length+" 条数据")):(t.printLog("批量发送失败: sendBeacon 返回 false,数据已重新加入队列"),t.retryBatchData(e))}catch(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}else t.ajax({url:r,type:"POST",data:JSON.stringify({events:e}),contentType:i,credentials:!1,timeout:t.initConfig.sendTimeout,cors:!0,success:function(){t.saveBatchQueueToStorage([]),t.initConfig.showLog&&t.printLog("批量发送成功: "+e.length+" 条数据")},error:function(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}})},t.retryBatchData=function(e){var n=t.getBatchQueueFromStorage(),i=function(e){return e.event+"_"+e.itemKey+"_"+e.requestTime},o=new Set(n.map(i)),a=t.getTimeStamp(),s=e.filter((function(e){var n=i(e);if(o.has(n))return!1;var r=(e._retryCount||0)+1;return r>3?(t.initConfig.showLog&&t.printLog("数据已达到最大重试次数,放弃重试: "+n),!1):(e._retryCount=r,e._nextRetryTime=a+1e3*Math.pow(2,r),o.add(n),!0)})),u=r(r([],s),n),c=2*t.initConfig.batchMaxSize,g=u.length>c?u.slice(0,c):u;t.saveBatchQueueToStorage(g),t.initConfig.showLog&&t.printLog("已将 "+s.length+" 条数据加入重试队列")},t.addToBatchQueue=function(e){var n=t.initConfig,r=n.batchInterval,i=n.batchMaxSize;if(t.shouldSample()){var o=t.getBatchQueueFromStorage();o.push(e),t.saveBatchQueueToStorage(o),o.length>=i?t.flushBatchQueue():t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}else t.initConfig.showLog&&t.printLog("数据已采样跳过(批量模式)")},t.restoreBatchQueueFromStorage=function(){var e=t.getBatchQueueFromStorage();if(e.length>0){t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送数据");var n=t.initConfig.batchMaxSize;if(e.length>=n)t.flushBatchQueue();else{var r=t.initConfig.batchInterval;t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}}},t.addToPendingRequests=function(e){var n=t.getPendingRequestsFromStorage();n.push(e);var r=t.initConfig.pendingRequestsMaxSize||t.DEFAULT_PENDING_REQUESTS_MAX_SIZE;if(n.length>r){var i=n.slice(-r);t.initConfig.showLog&&t.printLog("待发送请求队列已满,已移除最旧的数据(最大限制: "+r+")"),t.savePendingRequestsToStorage(i)}else t.savePendingRequestsToStorage(n)},t.restorePendingRequestsFromStorage=function(){var e=t.getPendingRequestsFromStorage();e.length>0&&t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送请求")},t.isPageUnloading=function(){return"hidden"===document.visibilityState},t.sendWithBeacon=function(e,n,r){try{var i=new Blob([JSON.stringify(e)],{type:r||"application/json"});return navigator.sendBeacon(n,i)}catch(e){return t.initConfig.showLog&&t.printLog("sendBeacon 发送失败: "+e),!1}},t.flushPendingRequests=function(){var e=t.getPendingRequestsFromStorage();if(0!==e.length){t.savePendingRequestsToStorage([]);var n=t.initConfig,r=n.serverUrl,i=n.sendTimeout,o=n.contentType,a=n.showLog,s=n.header;e.forEach((function(e){t.shouldSample()?(a&&t.printLog(e),t.ajax({header:s,url:r,type:"POST",data:JSON.stringify(e),contentType:o,credentials:!1,timeout:i,cors:!0,success:function(){a&&t.printLog("待发送请求发送成功")},error:function(e){a&&t.printLog("待发送请求发送失败(不再重试): "+e)}})):a&&t.printLog("待发送请求已采样跳过")}))}},t.setupBeforeUnloadListener=function(){t.isUnloadListenerSetup||(t.isUnloadListenerSetup=!0,document.addEventListener("visibilitychange",(function(){t.isPageUnloading()&&t.flushPendingData()})),window.addEventListener("beforeunload",(function(){t.flushPendingData()})),window.addEventListener("pagehide",(function(){t.flushPendingData()})))},t.isFlushingPendingData=!1,t.flushPendingData=function(){if(!t.isFlushingPendingData){t.stopPageDurationTimer();var e=[],n=t.getBatchQueueFromStorage();n.length>0&&e.push.apply(e,n);var r=t.getPendingRequestsFromStorage();if(r.length>0&&e.push.apply(e,r),0!==e.length){t.isFlushingPendingData=!0;try{t.initConfig.batchSend?t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(e)):t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.initConfig.showLog&&t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}if(navigator.sendBeacon&&t.initConfig.serverUrl)try{var i=1===e.length?e[0]:e,o=new Blob([JSON.stringify(i)],{type:t.initConfig.contentType||"application/json"});navigator.sendBeacon(t.initConfig.serverUrl,o)?(t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("页面卸载时成功发送 "+e.length+" 条数据")):t.initConfig.showLog&&t.printLog("sendBeacon 返回 false,数据已保存到 LocalStorage 等待下次恢复")}catch(e){t.initConfig.showLog&&t.printLog("页面卸载时发送数据失败: "+e+",数据已保存到 LocalStorage")}finally{t.isFlushingPendingData=!1}else t.initConfig.showLog&&t.printLog("不支持 sendBeacon,数据已保存到 LocalStorage 等待下次恢复"),t.isFlushingPendingData=!1}}},t.sendData=function(e,n){if(!t.shouldSample())return Promise.resolve({success:!0,message:"数据已采样跳过"});var r=t.initConfig,i=r.serverUrl,o=r.sendTimeout,a=r.contentType,s=r.showLog,u=r.header,c=r.batchSend,g=r.sendMethod;return s&&t.printLog(e),c?(t.addToBatchQueue(e),Promise.resolve({success:!0,message:"已添加到批量队列"})):t.shouldUseBeacon(g,n,u)?t.isPageUnloading()?t.sendWithBeacon(e,i,a)?Promise.resolve({success:!0,message:"页面卸载时发送成功"}):(t.addToPendingRequests(e),Promise.resolve({success:!0,message:"已添加到待发送队列"})):t.sendBeacon({contentType:a,url:i,data:e}).catch((function(n){return t.addToPendingRequests(e),Promise.resolve({success:!0,message:"sendBeacon 失败,已添加到待发送队列"})})):new Promise((function(r,s){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!u&&t.sendWithBeacon(e,i,a))return void r({success:!0,message:"页面卸载时使用 sendBeacon 发送成功"});t.ajax({header:n||u,url:i,type:"POST",data:JSON.stringify(e),contentType:a,credentials:!1,timeout:o,cors:!0,success:function(e){return r({success:!0,data:e})},error:function(o,c){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!u&&t.sendWithBeacon(e,i,a))return void r({success:!0,message:"XMLHttpRequest 失败,已使用 sendBeacon 发送"});s({success:!1,message:String(o),code:c})}})}))},t.shouldUseBeacon=function(e,n,r){return"xhr"!==e&&("beacon"===e?!0===t.isSupportBeaconSend():!0===t.isSupportBeaconSend()&&!n&&!r)},t.sendRetained=function(e){var r=t.getParams({event:"PageRetained",desc:t.eventDescMap.PageRetained});if(["beforeunload","pushState","replaceState","hashchange","popstate"].indexOf(e)>=0){var i=t.getCookie("retainedStartTime"),o=i?+i:t.getTimeStamp(),a=n(n({},r),{privateParamMap:n(n({},r.privateParamMap),{retainedDuration:Math.max(r.requestTime-o,0)})});t.sendData(a),t.setCookie("retainedStartTime",t.getTimeStamp())}},t.trackPageDuration=function(e,n,r){var i;if(void 0===r&&(r=!0),null!=e)i=Math.max(e,0);else{var o=t.getCookie("retainedStartTime"),a=o?+o:t.getTimeStamp(),s=t.getTimeStamp();i=Math.max(s-a,0)}var u=(null==n?void 0:n.desc)||t.eventDescMap.PageRetained,c=(null==n?void 0:n.pageKey)||t.pageKey,g=(null==n?void 0:n.business)||{},l=null==n?void 0:n.header,p=t.getParams({event:"PageRetained",desc:u,itemKey:t.getItemKey(void 0,c),privateParamMap:{business:g,retainedDuration:i}}),d=t.sendData(p,l);return r&&t.setCookie("retainedStartTime",t.getTimeStamp()),d},t.startPageDurationTimer=function(){t.stopPageDurationTimer();var e=t.initConfig.pageDurationInterval||3e4;e<=0?t.initConfig.showLog&&t.printLog("定时上报间隔时间无效,已禁用定时上报"):(t.pageDurationTimer=window.setInterval((function(){"visible"===document.visibilityState&&t.trackPageDuration(e,{desc:"定时上报页面停留时长",business:{reportType:"interval",interval:e}},!0).catch((function(e){t.initConfig.showLog&&t.printLog("定时上报页面停留时长失败: "+e)}))}),e),t.initConfig.showLog&&t.printLog("定时上报页面停留时长已启动,间隔: "+e+"ms"))},t.stopPageDurationTimer=function(){null!==t.pageDurationTimer&&(clearInterval(t.pageDurationTimer),t.pageDurationTimer=null,t.initConfig.showLog&&t.printLog("定时上报页面停留时长已停止"))},t.getItemKey=function(e,n){return[t.initConfig.appKey,(n||t.pageKey).toString(),e?e.toString():void 0].filter((function(e){return!!e})).reduce((function(e,t){return e+(e.length?".":"")+t}),"")},t.extractDataAttributes=function(e){for(var t={},n=e;n;){for(var r=n.attributes,i=0;i<r.length;i++){var o=r[i],a=o.name;if(a.startsWith("data-")&&"data-exposure"!==a&&"data-part-key"!==a&&"data-desc"!==a){var s=o.value;if(s)t[a.replace(/^data-/,"").split("-").map((function(e,t){return 0===t?e:e.charAt(0).toUpperCase()+e.slice(1)})).join("")]=s}}if((n=n.parentElement)&&"BODY"===n.tagName)break}return t},t.initExposureObserver=function(){if(t.initConfig.autoTrackExposure)if("IntersectionObserver"in window){var e=t.initConfig.exposureThreshold||.5;t.exposureObserver=new IntersectionObserver((function(e){e.forEach((function(e){var n=e.target,r=t.exposureElementsMap.get(n);if(r){var i=t.initConfig.exposureTime||500;e.isIntersecting?(r.isVisible=!0,r.visibleStartTime=t.getTimeStamp(),r.exposureTimer&&clearTimeout(r.exposureTimer),r.exposureTimer=window.setTimeout((function(){r.isVisible&&t.reportExposure(n)}),i)):(r.isVisible=!1,r.exposureTimer&&(clearTimeout(r.exposureTimer),r.exposureTimer=null))}}))}),{threshold:e}),t.observeExposureElements()}else t.initConfig.showLog&&t.printLog("当前浏览器不支持 IntersectionObserver,无法启用曝光埋点")},t.observeExposureElements=function(){if(t.exposureObserver){var e=document.querySelectorAll('[data-exposure="true"]');e.forEach((function(e){if(!t.exposureElementsMap.has(e)){var n=e;t.exposureElementsMap.set(n,{element:n,visibleStartTime:0,exposureCount:0,isVisible:!1,exposureTimer:null}),t.exposureObserver.observe(n)}})),t.initConfig.showLog&&e.length>0&&t.printLog("已监听 "+e.length+" 个曝光元素")}},t.reportExposure=function(e){var n=t.exposureElementsMap.get(e);if(n){var r=t.initConfig.exposureNum;if(void 0!==r&&n.exposureCount>=r)t.initConfig.showLog&&t.printLog("元素已达到最大曝光次数限制: "+r);else{var i=t.extractDataAttributes(e),o=e.getAttribute("data-desc")||t.eventDescMap.WebExposure,a=e.getAttribute("data-part-key")||"exposure",s=t.getParams({event:"WebExposure",desc:o,itemKey:t.getItemKey(a),privateParamMap:{business:i}});t.sendData(s).then((function(){n.exposureCount++,n.exposureTimer&&(clearTimeout(n.exposureTimer),n.exposureTimer=null),t.initConfig.showLog&&t.printLog("曝光上报成功,当前曝光次数: "+n.exposureCount)})).catch((function(e){t.initConfig.showLog&&t.printLog("曝光上报失败: "+e)}))}}},t.stopExposureObserver=function(){t.exposureObserver&&(t.exposureObserver.disconnect(),t.exposureObserver=null,t.exposureElementsMap.forEach((function(e){e.exposureTimer&&clearTimeout(e.exposureTimer)})),t.exposureElementsMap.clear(),t.initConfig.showLog&&t.printLog("曝光监听已停止"))},t.sdkVersion="1.2.4",t.initConfig={appKey:"",platform:void 0,showLog:!1,serverUrl:"",autoTrack:!1,sendTimeout:3e3,isTrackSinglePage:!1,contentType:"application/json",business:{},header:void 0,sampleRate:1,batchSend:!1,batchInterval:5e3,batchMaxSize:10,trackPartKeyClick:!1,pendingRequestsMaxSize:50,autoTrackPageDurationInterval:!1,pageDurationInterval:3e4,sendMethod:"auto",autoTrackExposure:!1,exposureThreshold:.5,exposureTime:500,exposureNum:void 0},t.systemsInfo={},t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(o,i),o.prototype.addSinglePageEvent=function(e){var t=this,n=window.history.pushState?"popstate":"hashchange";this.each(["pushState","replaceState",n],(function(n){t.addEventListener(window,n,e)}))},o}(function(){function t(){var t=this;this.getSystemsInfo=function(e){var t=navigator.userAgent,n="other",r=[],i={language:navigator.language},o=t.match(/MicroMessenger\/([\d\.]+)/i),a=o&&o[1]?o[1]:null,s=t.match(/(ipod).*\s([\d_]+)/i),u=t.match(/(ipad).*\s([\d_]+)/i),c=t.match(/(iphone)\sos\s([\d_]+)/i),g=t.match(/(android)\s([\d\.]+)/i),l=t.match(/(Windows NT)\s([\d\.]+)/i),p=t.match(/(Mac OS X)\s([\d_]+)/i);r=[],g?(r.push("Android "+g[2]),n="h5"):c?(r.push("iPhone, iOS "+c[2].replace(/_/g,".")),n="h5"):u?(r.push("iPad, iOS "+u[2].replace(/_/g,".")),n="ipad"):s?(r.push("iPod, iOS "+s[2].replace(/_/g,".")),n="h5"):l?(r.push("Windows "+l[2].replace(/_/g,".")),n="pc"):p&&(r.push("Mac, MacOS "+p[2].replace(/_/g,".")),n="pc"),a&&r.push("WeChat "+a),i.client=r.length?r.join(", "):"Unknown",i.platform=e||n;var d=t.toLowerCase().match(/ nettype\/([^ ]+)/g);return d&&d[0]&&(r=[(d=d[0].split("/"))[1]],i.network=r.length?r.join(", "):"Unknown"),i.ua=t,i},this.addEventListener=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,(function(t){return n.call(e,t)}),!1)},this.removeEventListener=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n):e.detachEvent&&e.detachEvent("on"+t,(function(t){return n.call(e,t)}),!0)},this.rewriteHistory=function(){var e=window.history,t=function(e){var t=window.history,n=t[e],r=new Event(e);return function(){var e=n.apply(t,arguments);return r.arguments=arguments,window.dispatchEvent(r),e}};window.history.pushState&&(e.pushState=t("pushState"),e.replaceState=t("replaceState"))},this.isArray=Array.isArray||function(e){return"[object Array]"===toString.call(e)},this.formatJsonString=function(e){try{return JSON.stringify(e,null," ")}catch(t){return JSON.stringify(e)}},this.nativeForEach=Array.prototype.forEach,this.slice=Array.prototype.slice,this.hasOwnProperty=Object.prototype.hasOwnProperty,this.breaker={},this.each=function(e,n,r){if(null==e)return!1;if(t.nativeForEach&&e.forEach===t.nativeForEach)e.forEach(n,r);else if(t.isArray(e)&&e.length===+e.length){for(var i=0,o=e.length;i<o;i++)if(i in e&&n.call(r,e[i],i,e)===t.breaker)return!1}else for(var a in e)if(t.hasOwnProperty.call(e,a)&&n.call(r,e[a],a,e)===t.breaker)return!1;return!0},this.getDomIndex=function(e){if(!e.parentNode)return-1;for(var t=0,n=e.tagName,r=e.parentNode.children,i=0;i<r.length;i++)if(r[i].tagName===n){if(e===r[i])return t;t++}return-1},this.selector=function(e){var n=e.parentNode&&9==e.parentNode.nodeType?-1:t.getDomIndex(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~n?":nth-of-type("+(n+1)+")":"")},this.getDomSelector=function(e,n){if(!e||!e.parentNode||!e.parentNode.children)return!1;n=n&&n.join?n:[];var r=e.nodeName.toLowerCase();return e&&"body"!==r&&1==e.nodeType?(n.unshift(t.selector(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?n.join(" > "):t.getDomSelector(e.parentNode,n)):(n.unshift("body"),n.join(" > "))},this.getCookie=function(e){for(var t=e+"=",n=document.cookie.split(";"),r=0;r<n.length;r++){for(var i=n[r];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(t))return this._decodeURIComponent(i.substring(t.length,i.length))}return null},this.setCookie=function(e,t,n){var r,i="";n=null==n?73e3:n;var o=this.getMainHost();if(r=o?"; domain="+o:"",0!==n){var a=new Date;"s"===String(n).slice(-1)?a.setTime(a.getTime()+1e3*Number(String(n).slice(0,-1))):a.setTime(a.getTime()+24*n*60*60*1e3),i="; expires="+a.toUTCString()}function s(e){return e||!1}var u="",c="",g="";e&&(u=s(e)),t&&(c=s(t)),r&&(g=s(r)),u&&c&&(document.cookie=u+"="+encodeURIComponent(c)+i+"; path=/"+g)},this.getLocalStorage=function(e){try{return localStorage.getItem(e)}catch(e){return null}},this.setLocalStorage=function(e,t){try{localStorage.setItem(e,t)}catch(e){}},this.removeCookie=function(e){t.setCookie(e,"",-1)},this.getTimeStamp=function(){return(new Date).getTime()},this.uuid=function(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}))},this.getDistinctId=function(){var e=t.getCookie("distinctId");return e||(e=t.uuid(),t.setCookie("distinctId",e),e)},this.filterSensitiveData=function(e,n){if(void 0===n&&(n=["password","token","secret","key"]),!t.isObject(e))return e;var r={};return t.each(e,(function(e,i){n.some((function(e){return"string"==typeof i&&i.toLowerCase().includes(e.toLowerCase())}))?r[i]="***":t.isObject(e)?r[i]=t.filterSensitiveData(e,n):r[i]=e})),r},this.xssFilter=function(e){return e?"string"!=typeof e?e.toString():e.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""},this.getQueryValue=function(){for(var e=decodeURI(window.location.href).match(new RegExp("[?&][^?&]+=[^?&]+","g"))||[],t={},n=0;n<e.length;n++){var r=e[n].replace(/\?|\&/,"").split("=");t[r[0]]=r[1]}return Object.keys(t).length>0?t:null},this.ajax=function(n){function r(t){if(!t)return{};if("string"==typeof t)try{return JSON.parse(t)}catch(e){return{}}return"object"===e(t)?t:{}}n.timeout=n.timeout||3e4,n.credentials=void 0===n.credentials||n.credentials;var i=t.xhr(n.cors);if(!i)return!1;n.type||(n.type=n.data?"POST":"GET");var o,a=n.success,s=n.error;n.success=function(e){a&&a(e),o&&(clearTimeout(o),o=null)},n.error=function(e,t){s&&s(e,t),o&&(clearTimeout(o),o=null)},o=window.setTimeout((function(){!function(){try{t.isObject(i)&&i.abort&&i.abort()}catch(e){t.printLog(e)}o&&(clearTimeout(o),o=null,n.error&&n.error(),i.onreadystatechange=null,i.onload=null,i.onerror=null)}()}),n.timeout),i.onreadystatechange=function(){try{4==i.readyState&&(i.status>=200&&i.status<300||304==i.status?n.success&&n.success(r(i.responseText)):n.error&&n.error(r(i.responseText),i.status),i.onreadystatechange=null,i.onload=null)}catch(e){i.onreadystatechange=null,i.onload=null}},i.open(n.type||"GET",n.url,!0);try{n.credentials&&(i.withCredentials=!0),t.isObject(n.header)&&t.each(n.header,(function(e,t){i.setRequestHeader&&i.setRequestHeader(t,e)})),n.data&&(n.cors||i.setRequestHeader&&i.setRequestHeader("X-Requested-With","XMLHttpRequest"),"application/json"===n.contentType?i.setRequestHeader&&i.setRequestHeader("Content-type","application/json; charset=UTF-8"):i.setRequestHeader&&i.setRequestHeader("Content-type","application/x-www-form-urlencoded"))}catch(e){t.printLog(e)}i.send(n.data||null)},this.xhr=function(e){return e?void 0!==window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest?new XMLHttpRequest:null:void 0!==window.XMLHttpRequest?new XMLHttpRequest:null},this.getUA=function(){var e,t={},n=navigator.userAgent.toLowerCase();return(e=n.match(/opera.([\d.]+)/))?t.opera=Number(e[1].split(".")[0]):(e=n.match(/msie ([\d.]+)/))?t.ie=Number(e[1].split(".")[0]):(e=n.match(/edge.([\d.]+)/))?t.edge=Number(e[1].split(".")[0]):(e=n.match(/firefox\/([\d.]+)/))?t.firefox=Number(e[1].split(".")[0]):(e=n.match(/chrome\/([\d.]+)/))?t.chrome=Number(e[1].split(".")[0]):(e=n.match(/version\/([\d.]+).*safari/))?t.safari=Number(e[1].match(/^\d*.\d*/)):(e=n.match(/trident\/([\d.]+)/))&&(t.ie=11),t},this.isSupportBeaconSend=function(){var n=!1;if("object"!==("undefined"==typeof navigator?"undefined":e(navigator))||"function"!=typeof navigator.sendBeacon)return n;var r=t.getUA(),i=navigator.userAgent.toLowerCase();if(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)){var o=(i.match(/os [\d._]*/gi)+"").replace(/[^0-9|_.]/gi,"").replace(/_/gi,".").split(".");void 0===r.safari&&(r.safari=Number(o[0])),o[0]&&+o[0]<13?(r.chrome>41||r.firefox>30||r.opera>25||r.safari>12)&&(n=!0):(r.chrome>41||r.firefox>30||r.opera>25||r.safari>11.3)&&(n=!0)}else(r.chrome>38||r.edge>13||r.firefox>30||r.opera>25||r.safari>11)&&(n=!0);return n},this.throttle=function(e,t){var n=null,r=0;return function(){for(var i=[],o=0;o<arguments.length;o++)i[o]=arguments[o];var a=Date.now(),s=t-(a-r);s<=0||s>t?(n&&(clearTimeout(n),n=null),r=a,e.apply(void 0,i)):n||(n=window.setTimeout((function(){r=Date.now(),n=null,e.apply(void 0,i)}),s))}},this.debounce=function(e,t){var n=null;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];n&&clearTimeout(n),n=window.setTimeout((function(){e.apply(void 0,r)}),t)}},this.sendBeacon=function(e){if(!0===t.isSupportBeaconSend()){var n={type:e.contentType},r=new Blob([JSON.stringify(e.data)],n);return navigator.sendBeacon(e.url,r)?Promise.resolve({success:!0,message:"发送成功"}):Promise.reject({success:!1,message:"sendBeacon返回false"})}return Promise.reject({success:!1,message:"不支持sendBeacon,发送失败!"})},this.getDeviceId=function(){var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return e;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),r},this.collectFingerprint=function(){var e={};return e.userAgent=navigator.userAgent,e.screenWidth=screen.width,e.screenHeight=screen.height,e.colorDepth=screen.colorDepth,e.pixelDepth=screen.pixelDepth,e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone,e.timezoneOffset=(new Date).getTimezoneOffset(),e.language=navigator.language,e.languages=Array.from(navigator.languages),e.platform=navigator.platform,e.webgl=t.getWebGLFingerprint(),e.canvas=t.getCanvasFingerprint(),e.audio=t.getAudioFingerprint(),e.fonts=t.getFontFingerprint(),e.plugins=t.getPluginsFingerprint(),e.localStorage=t.hasLocalStorage(),e.sessionStorage=t.hasSessionStorage(),e.indexedDB=t.hasIndexedDB(),e.hardwareConcurrency=navigator.hardwareConcurrency,e.deviceMemory=navigator.deviceMemory,e.maxTouchPoints=navigator.maxTouchPoints,e.connection=t.getConnectionFingerprint(),e},this.getWebGLFingerprint=function(){try{var e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!t)return"not-supported";var n=t.getExtension("WEBGL_debug_renderer_info");return(n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):"unknown")+"|"+(n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):"unknown")}catch(e){return"error"}},this.getCanvasFingerprint=function(){try{var e=document.createElement("canvas");e.width=200,e.height=50;var t=e.getContext("2d");return t?(t.textBaseline="top",t.font="14px Arial",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText("Canvas fingerprint",2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText("Canvas fingerprint",4,17),e.toDataURL().slice(-50)):"not-supported"}catch(e){return"error"}},this.getAudioFingerprint=function(){try{var e=window.AudioContext||window.webkitAudioContext;if(!e)return"not-supported";var t=new e,n=String(t.sampleRate||0);return t.close(),n}catch(e){return"error"}},this.getFontFingerprint=function(){try{var e=["monospace","sans-serif","serif"],t="mmmmmmmmmmlli",n=document.createElement("canvas").getContext("2d");if(!n)return"not-supported";var r=[],i={};return e.forEach((function(e){n.font="72px "+e,i[e]=n.measureText(t).width})),["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Helvetica","Impact","Times New Roman","Trebuchet MS","Verdana"].forEach((function(o){var a=!1;e.forEach((function(e){n.font="72px '"+o+"', "+e,n.measureText(t).width!==i[e]&&(a=!0)})),a&&r.push(o)})),r.join(",")}catch(e){return"error"}},this.getPluginsFingerprint=function(){try{var e=[];if(navigator.plugins)for(var t=0;t<navigator.plugins.length;t++){var n=navigator.plugins[t];n&&e.push(n.name+"|"+n.description+"|"+n.filename)}return e.join(";")}catch(e){return"error"}},this.hasLocalStorage=function(){try{var e="__test__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}},this.hasSessionStorage=function(){try{var e="__test__";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(e){return!1}},this.hasIndexedDB=function(){return"indexedDB"in window&&null!==indexedDB},this.getConnectionFingerprint=function(){try{var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?e.effectiveType||"unknown":"not-supported"}catch(e){return"error"}},this.hashFingerprint=function(e){for(var t=JSON.stringify(e,Object.keys(e).sort()),n=5381,r=52711,i=0;i<t.length;i++){var o=t.charCodeAt(i);n=(n<<5)+n+o,r=(r<<5)+r+o}return"fp_"+(n>>>0).toString(16).padStart(8,"0")+(r>>>0).toString(16).padStart(8,"0")}}return t.prototype.printLog=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];if(this.isObject(t[0])&&(t[0]=this.formatJsonString(t[0])),"object"===("undefined"==typeof console?"undefined":e(console))&&console.log)try{return console.log.apply(console,t)}catch(e){console.log(t[0])}},t.prototype.isObject=function(e){return null!=e&&"[object Object]"==toString.call(e)},t.prototype.isUndefined=function(e){return void 0===e},t.prototype.isString=function(e){return"[object String]"==toString.call(e)},t.prototype.isDate=function(e){return"[object Date]"==toString.call(e)},t.prototype.isBoolean=function(e){return"[object Boolean]"==toString.call(e)},t.prototype.isNumber=function(e){return"[object Number]"==toString.call(e)&&/[\d\.]+/.test(String(e))},t.prototype.isElement=function(e){return!(!e||1!==e.nodeType)},t.prototype.isFunction=function(e){if(!e)return!1;var t=toString.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t},t.prototype.isJSONString=function(e){if(!this.isString(e))return!1;try{JSON.parse(e)}catch(e){return!1}return!0},t.prototype._decodeURIComponent=function(e){var t=e;try{t=decodeURIComponent(e)}catch(n){t=e}return t},t.prototype.getMainHost=function(){var e="mh_"+Math.random(),t=new RegExp("(^|;)\\s*"+e+"=12345"),n=new Date(0),r=document.domain,i=r.split("."),o=[];for(o.unshift(i.pop());i.length;){o.unshift(i.pop());var a=o.join("."),s=e+"=12345;domain=."+a;if(document.cookie=s,t.test(document.cookie))return document.cookie=s+";expires="+n,a}return r},t}()));export default i;
package/lib/index.js CHANGED
@@ -1259,7 +1259,11 @@
1259
1259
 
1260
1260
  _this.DEFAULT_PENDING_REQUESTS_MAX_SIZE = 50; // LocalStorage 最大大小限制(4MB)
1261
1261
 
1262
- _this.MAX_STORAGE_SIZE = 4 * 1024 * 1024; // 用户信息
1262
+ _this.MAX_STORAGE_SIZE = 4 * 1024 * 1024; // IntersectionObserver 实例
1263
+
1264
+ _this.exposureObserver = null; // 曝光元素映射
1265
+
1266
+ _this.exposureElementsMap = new Map(); // 用户信息
1263
1267
 
1264
1268
  _this.userInfo = null; // 当前路由
1265
1269
 
@@ -1273,7 +1277,8 @@
1273
1277
  PageView: "Web 浏览页面",
1274
1278
  WebClick: "Web 元素点击",
1275
1279
  PageRetained: "Web 页面浏览时长",
1276
- CustomTrack: "Web 自定义代码上报"
1280
+ CustomTrack: "Web 自定义代码上报",
1281
+ WebExposure: "Web 元素曝光"
1277
1282
  };
1278
1283
  /**
1279
1284
  * @description 初始化函数
@@ -1318,6 +1323,11 @@
1318
1323
 
1319
1324
  if (_this.initConfig.autoTrackPageDurationInterval) {
1320
1325
  _this.startPageDurationTimer();
1326
+ } // 如果启用了曝光监听,初始化曝光监听
1327
+
1328
+
1329
+ if (_this.initConfig.autoTrackExposure) {
1330
+ _this.initExposureObserver();
1321
1331
  }
1322
1332
  };
1323
1333
  /**
@@ -1378,6 +1388,13 @@
1378
1388
  _this.startPageDurationTimer();
1379
1389
  } else {
1380
1390
  _this.stopPageDurationTimer();
1391
+ } // 处理曝光监听配置
1392
+
1393
+
1394
+ if (_this.initConfig.autoTrackExposure) {
1395
+ _this.initExposureObserver();
1396
+ } else {
1397
+ _this.stopExposureObserver();
1381
1398
  }
1382
1399
  };
1383
1400
  /**
@@ -1460,6 +1477,36 @@
1460
1477
 
1461
1478
  break;
1462
1479
 
1480
+ case 'exposureThreshold':
1481
+ if (typeof value !== 'number' || value < 0 || value > 1) {
1482
+ return {
1483
+ valid: false,
1484
+ message: 'exposureThreshold 必须是 0-1 之间的数字'
1485
+ };
1486
+ }
1487
+
1488
+ break;
1489
+
1490
+ case 'exposureTime':
1491
+ if (typeof value !== 'number' || value <= 0) {
1492
+ return {
1493
+ valid: false,
1494
+ message: 'exposureTime 必须是大于 0 的数字'
1495
+ };
1496
+ }
1497
+
1498
+ break;
1499
+
1500
+ case 'exposureNum':
1501
+ if (value !== undefined && (typeof value !== 'number' || value <= 0 || !Number.isInteger(value))) {
1502
+ return {
1503
+ valid: false,
1504
+ message: 'exposureNum 必须是大于 0 的整数或不限制'
1505
+ };
1506
+ }
1507
+
1508
+ break;
1509
+
1463
1510
  case 'showLog':
1464
1511
  case 'autoTrack':
1465
1512
  case 'isTrackSinglePage':
@@ -2786,8 +2833,216 @@
2786
2833
  return str + ("" + (str.length ? "." : "")) + key;
2787
2834
  }, "");
2788
2835
  };
2836
+ /**
2837
+ * @description 从元素或其祖先节点提取 data-* 属性
2838
+ * @param element 目标元素
2839
+ * @returns 提取的业务参数对象
2840
+ */
2841
+
2842
+
2843
+ _this.extractDataAttributes = function (element) {
2844
+ var business = {};
2845
+ var currentElement = element;
2846
+
2847
+ while (currentElement) {
2848
+ var attributes = currentElement.attributes;
2849
+
2850
+ for (var i = 0; i < attributes.length; i++) {
2851
+ var attr = attributes[i];
2852
+ var name_1 = attr.name;
2853
+
2854
+ if (name_1.startsWith('data-') && name_1 !== 'data-exposure' && name_1 !== 'data-part-key' && name_1 !== 'data-desc') {
2855
+ var value = attr.value;
2856
+
2857
+ if (value) {
2858
+ var camelCaseKey = name_1.replace(/^data-/, '').split('-').map(function (part, index) {
2859
+ return index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1);
2860
+ }).join('');
2861
+ business[camelCaseKey] = value;
2862
+ }
2863
+ }
2864
+ }
2865
+
2866
+ currentElement = currentElement.parentElement;
2867
+
2868
+ if (currentElement && currentElement.tagName === 'BODY') {
2869
+ break;
2870
+ }
2871
+ }
2872
+
2873
+ return business;
2874
+ };
2875
+ /**
2876
+ * @description 初始化曝光监听
2877
+ */
2878
+
2879
+
2880
+ _this.initExposureObserver = function () {
2881
+ if (!_this.initConfig.autoTrackExposure) {
2882
+ return;
2883
+ }
2884
+
2885
+ if (!('IntersectionObserver' in window)) {
2886
+ if (_this.initConfig.showLog) {
2887
+ _this.printLog('当前浏览器不支持 IntersectionObserver,无法启用曝光埋点');
2888
+ }
2889
+
2890
+ return;
2891
+ }
2892
+
2893
+ var threshold = _this.initConfig.exposureThreshold || 0.5;
2894
+ _this.exposureObserver = new IntersectionObserver(function (entries) {
2895
+ entries.forEach(function (entry) {
2896
+ var element = entry.target;
2897
+
2898
+ var elementInfo = _this.exposureElementsMap.get(element);
2899
+
2900
+ if (!elementInfo) {
2901
+ return;
2902
+ }
2903
+
2904
+ var exposureTime = _this.initConfig.exposureTime || 500;
2905
+
2906
+ if (entry.isIntersecting) {
2907
+ elementInfo.isVisible = true;
2908
+ elementInfo.visibleStartTime = _this.getTimeStamp();
2909
+
2910
+ if (elementInfo.exposureTimer) {
2911
+ clearTimeout(elementInfo.exposureTimer);
2912
+ }
2913
+
2914
+ elementInfo.exposureTimer = window.setTimeout(function () {
2915
+ if (elementInfo.isVisible) {
2916
+ _this.reportExposure(element);
2917
+ }
2918
+ }, exposureTime);
2919
+ } else {
2920
+ elementInfo.isVisible = false;
2921
+
2922
+ if (elementInfo.exposureTimer) {
2923
+ clearTimeout(elementInfo.exposureTimer);
2924
+ elementInfo.exposureTimer = null;
2925
+ }
2926
+ }
2927
+ });
2928
+ }, {
2929
+ threshold: threshold
2930
+ });
2931
+
2932
+ _this.observeExposureElements();
2933
+ };
2934
+ /**
2935
+ * @description 监听页面上的曝光元素
2936
+ */
2937
+
2938
+
2939
+ _this.observeExposureElements = function () {
2940
+ if (!_this.exposureObserver) {
2941
+ return;
2942
+ }
2943
+
2944
+ var elements = document.querySelectorAll('[data-exposure="true"]');
2945
+ elements.forEach(function (element) {
2946
+ if (!_this.exposureElementsMap.has(element)) {
2947
+ var htmlElement = element;
2948
+
2949
+ _this.exposureElementsMap.set(htmlElement, {
2950
+ element: htmlElement,
2951
+ visibleStartTime: 0,
2952
+ exposureCount: 0,
2953
+ isVisible: false,
2954
+ exposureTimer: null
2955
+ });
2956
+
2957
+ _this.exposureObserver.observe(htmlElement);
2958
+ }
2959
+ });
2960
+
2961
+ if (_this.initConfig.showLog && elements.length > 0) {
2962
+ _this.printLog("\u5DF2\u76D1\u542C " + elements.length + " \u4E2A\u66DD\u5149\u5143\u7D20");
2963
+ }
2964
+ };
2965
+ /**
2966
+ * @description 上报曝光事件
2967
+ * @param element 曝光元素
2968
+ */
2969
+
2970
+
2971
+ _this.reportExposure = function (element) {
2972
+ var elementInfo = _this.exposureElementsMap.get(element);
2973
+
2974
+ if (!elementInfo) {
2975
+ return;
2976
+ }
2977
+
2978
+ var exposureNum = _this.initConfig.exposureNum;
2979
+
2980
+ if (exposureNum !== undefined && elementInfo.exposureCount >= exposureNum) {
2981
+ if (_this.initConfig.showLog) {
2982
+ _this.printLog("\u5143\u7D20\u5DF2\u8FBE\u5230\u6700\u5927\u66DD\u5149\u6B21\u6570\u9650\u5236: " + exposureNum);
2983
+ }
2984
+
2985
+ return;
2986
+ }
2987
+
2988
+ var business = _this.extractDataAttributes(element);
2989
+
2990
+ var desc = element.getAttribute('data-desc') || _this.eventDescMap['WebExposure'];
2991
+
2992
+ var partkey = element.getAttribute('data-part-key') || 'exposure';
2993
+
2994
+ var params = _this.getParams({
2995
+ event: 'WebExposure',
2996
+ desc: desc,
2997
+ itemKey: _this.getItemKey(partkey),
2998
+ privateParamMap: {
2999
+ business: business
3000
+ }
3001
+ });
3002
+
3003
+ _this.sendData(params).then(function () {
3004
+ elementInfo.exposureCount++;
3005
+
3006
+ if (elementInfo.exposureTimer) {
3007
+ clearTimeout(elementInfo.exposureTimer);
3008
+ elementInfo.exposureTimer = null;
3009
+ }
3010
+
3011
+ if (_this.initConfig.showLog) {
3012
+ _this.printLog("\u66DD\u5149\u4E0A\u62A5\u6210\u529F\uFF0C\u5F53\u524D\u66DD\u5149\u6B21\u6570: " + elementInfo.exposureCount);
3013
+ }
3014
+ }).catch(function (err) {
3015
+ if (_this.initConfig.showLog) {
3016
+ _this.printLog("\u66DD\u5149\u4E0A\u62A5\u5931\u8D25: " + err);
3017
+ }
3018
+ });
3019
+ };
3020
+ /**
3021
+ * @description 停止曝光监听
3022
+ */
3023
+
3024
+
3025
+ _this.stopExposureObserver = function () {
3026
+ if (_this.exposureObserver) {
3027
+ _this.exposureObserver.disconnect();
3028
+
3029
+ _this.exposureObserver = null;
3030
+
3031
+ _this.exposureElementsMap.forEach(function (elementInfo) {
3032
+ if (elementInfo.exposureTimer) {
3033
+ clearTimeout(elementInfo.exposureTimer);
3034
+ }
3035
+ });
3036
+
3037
+ _this.exposureElementsMap.clear();
3038
+
3039
+ if (_this.initConfig.showLog) {
3040
+ _this.printLog('曝光监听已停止');
3041
+ }
3042
+ }
3043
+ };
2789
3044
 
2790
- _this.sdkVersion = "1.2.3"; // sdk版本
3045
+ _this.sdkVersion = "1.2.4"; // sdk版本
2791
3046
 
2792
3047
  _this.initConfig = {
2793
3048
  appKey: "",
@@ -2808,7 +3063,11 @@
2808
3063
  pendingRequestsMaxSize: 50,
2809
3064
  autoTrackPageDurationInterval: false,
2810
3065
  pageDurationInterval: 30000,
2811
- sendMethod: "auto" // 数据发送方式:auto(自动选择)、xhr(XMLHttpRequest)、beacon(sendBeacon)
3066
+ sendMethod: "auto",
3067
+ autoTrackExposure: false,
3068
+ exposureThreshold: 0.5,
3069
+ exposureTime: 500,
3070
+ exposureNum: undefined // 同一元素允许上报的最大曝光次数,不限制
2812
3071
 
2813
3072
  }; // 系统信息
2814
3073
 
package/lib/index.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).WebTracking=t()}(this,(function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,n)};var n=function(){return(n=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)};function r(e,t){for(var n=0,r=t.length,i=e.length;n<r;n++,i++)e[i]=t[n];return e}return new(function(i){function a(){var t=i.call(this)||this;return t.batchTimer=null,t.BATCH_QUEUE_STORAGE_KEY="web_tracking_batch_queue",t.useCustomPageKey=!1,t.isUnloadListenerSetup=!1,t.pageDurationTimer=null,t.PENDING_REQUESTS_STORAGE_KEY="web_tracking_pending_requests",t.DEFAULT_PENDING_REQUESTS_MAX_SIZE=50,t.MAX_STORAGE_SIZE=4194304,t.userInfo=null,t.currentUrl="",t.pageKey="",t.deviceId="",t.eventDescMap={PageView:"Web 浏览页面",WebClick:"Web 元素点击",PageRetained:"Web 页面浏览时长",CustomTrack:"Web 自定义代码上报"},t.init=function(e){t.preset(e);var n=window.location.pathname;t.currentUrl=window.location.href,e.pageKey?(t.pageKey=e.pageKey,t.useCustomPageKey=!0):(t.pageKey=n.replace(/\//g,"_").substring(1),t.useCustomPageKey=!1),t.systemsInfo=t.getSystemsInfo(e.platform),t.deviceId=t.getDeviceId(),e.userInfo&&t.isObject(e.userInfo)&&(t.userInfo=e.userInfo),t.setCookie("retainedStartTime",t.getTimeStamp()),t.initConfig.batchSend&&t.restoreBatchQueueFromStorage(),t.restorePendingRequestsFromStorage(),t.setupBeforeUnloadListener(),t.initConfig.autoTrackPageDurationInterval&&t.startPageDurationTimer()},t.preset=function(e){if(e instanceof Object){if(void 0!==e.pageKey)if(null===e.pageKey||""===e.pageKey){t.useCustomPageKey=!1;var n=window.location.pathname;t.pageKey=n.replace(/\//g,"_").substring(1)}else t.pageKey=e.pageKey,t.useCustomPageKey=!0;t.each(e,(function(e,n){if("pageKey"!==n&&t.initConfig.hasOwnProperty(n)){var r=t.validateConfigParam(String(n),e);r.valid?t.initConfig[n]=e:t.printLog("配置参数验证失败: "+String(n)+" = "+e+", 原因: "+r.message)}}))}/^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-\(\)]*[\w@?^=%&/~+#-\(\)])?$/.test(t.initConfig.serverUrl)||(t.printLog("当前 server_url 为空或不正确,只在控制台打印日志,network 中不会发数据,请配置正确的 server_url!"),t.initConfig.showLog=!0),t.initConfig.autoTrack||t.initConfig.trackPartKeyClick?t.listener():t.unlistener(),t.initConfig.autoTrackPageDurationInterval?t.startPageDurationTimer():t.stopPageDurationTimer()},t.validateConfigParam=function(t,n){switch(t){case"sampleRate":if("number"!=typeof n||n<0||n>1)return{valid:!1,message:"sampleRate 必须是 0-1 之间的数字"};break;case"sendTimeout":if("number"!=typeof n||n<=0)return{valid:!1,message:"sendTimeout 必须是大于 0 的数字"};break;case"batchInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"batchInterval 必须是大于 0 的数字"};break;case"batchMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"batchMaxSize 必须是大于 0 的整数"};break;case"pendingRequestsMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"pendingRequestsMaxSize 必须是大于 0 的整数"};break;case"pageDurationInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"pageDurationInterval 必须是大于 0 的数字"};break;case"sendMethod":if("string"!=typeof n||!["auto","xhr","beacon"].includes(n))return{valid:!1,message:"sendMethod 必须是 auto、xhr 或 beacon"};break;case"showLog":case"autoTrack":case"isTrackSinglePage":case"batchSend":case"trackPartKeyClick":case"autoTrackPageDurationInterval":if("boolean"!=typeof n)return{valid:!1,message:t+" 必须是布尔值"};break;case"business":case"header":if(null!==n&&"object"!==e(n))return{valid:!1,message:t+" 必须是对象或 null"};break;case"contentType":if("application/json"!==n&&"application/x-www-form-urlencoded"!==n)return{valid:!1,message:"contentType 必须是 application/json 或 application/x-www-form-urlencoded"};break;case"platform":if("string"!=typeof n)return{valid:!1,message:"platform 必须是字符串"}}return{valid:!0}},t.login=function(e){t.isObject(e)&&(t.userInfo=e)},t.getDeviceId=function(){if(t.deviceId)return t.deviceId;var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return t.deviceId=e,t.deviceId;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),t.deviceId=r,t.deviceId},t.resetDeviceId=function(){return document.cookie="device_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;",localStorage.removeItem("device_id"),t.deviceId="",t.getDeviceId()},t.track=function(e){var n=e.desc,r=e.pageKey,i=e.partkey,a=e.business,o=e.header,s=t.getParams({desc:n,event:"CustomTrack",itemKey:t.getItemKey(i,r),privateParamMap:{business:a}});return t.sendData(s,o)},t.listener=function(){t.unlistener(),t.initConfig.autoTrack&&(t.initConfig.isTrackSinglePage&&(t.rewriteHistory(),t.addSinglePageEvent(t.onPageViewCallback)),t.each(["load","beforeunload"],(function(e){t.addEventListener(window,e,t.onPageViewCallback)}))),(t.initConfig.autoTrack||t.initConfig.trackPartKeyClick)&&t.addEventListener(window,"click",t.onClickCallback)},t.unlistener=function(){if(t.initConfig.isTrackSinglePage){var e=window.history.pushState?"popstate":"hashchange";t.each(["pushState","replaceState",e],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)}))}t.each(["load","beforeunload"],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)})),t.removeEventListener(window,"click",t.onClickCallback),t.clearBatchTimer(),t.stopPageDurationTimer()},t.clearBatchTimer=function(){null!==t.batchTimer&&(clearTimeout(t.batchTimer),t.batchTimer=null)},t.clearBatchQueue=function(){t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("批量队列已清空")},t.getBatchQueueFromStorage=function(){try{var e=t.getLocalStorage(t.BATCH_QUEUE_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取批量队列失败: "+e),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]")}return[]},t.saveBatchQueueToStorage=function(e){try{var n=JSON.stringify(e);if(n.length>t.MAX_STORAGE_SIZE){var r=Math.floor(.8*e.length),i=e.slice(-r);t.printLog("队列过大,已截断保留最新 "+r+" 条数据(限制: "+t.MAX_STORAGE_SIZE/1024/1024+"MB)"),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(i))}else t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,n)}catch(e){t.printLog("保存批量队列到 LocalStorage 失败: "+e)}},t.getPendingRequestsFromStorage=function(){try{var e=t.getLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取待发送请求失败: "+e),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]")}return[]},t.savePendingRequestsToStorage=function(e){try{t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}},t.setPageKey=function(e,n){if(void 0===n&&(n=!1),null===e||""===e){t.useCustomPageKey=!1;var r=window.location.pathname;t.pageKey=r.replace(/\//g,"_").substring(1),t.initConfig.showLog&&t.printLog("页面标识已恢复自动生成: "+t.pageKey)}else t.pageKey=e,t.useCustomPageKey=!n,t.initConfig.showLog&&t.printLog("页面标识已设置为: "+e+", 自动更新: "+n)},t.getPageKey=function(){return t.pageKey},t.onClickCallback=function(e){var n,r=e.target;if(null===(n=null==r?void 0:r.dataset)||void 0===n?void 0:n.partKey){var i=[e.pageX,e.pageY],a=r.id,o=r.className,s={id:a,nodeName:r.nodeName,className:o,position:i},c=t.getParams({event:"WebClick",desc:t.eventDescMap.WebClick,itemKey:t.getItemKey(r.dataset.partKey),privateParamMap:{targetEle:s,pointerType:e.pointerType,currentUrl:t.currentUrl,elementSelector:t.getDomSelector(r)||""}});t.sendData(c)}},t.onPageViewCallback=function(e){var n,r,i=t.getPendingRequestsFromStorage(),a=t.initConfig.batchSend?t.getBatchQueueFromStorage():[];(i.length>0||a.length>0)&&t.flushPendingData();var o=window.location.origin,s=t.getParams({event:"PageView",desc:t.eventDescMap.PageView,privateParamMap:{currentUrl:t.currentUrl,targetUrl:(null===(n=e.arguments)||void 0===n?void 0:n[2])?o+(null===(r=e.arguments)||void 0===r?void 0:r[2]):null}});t.currentUrl=window.location.href,t.useCustomPageKey||(t.pageKey=window.location.pathname.replace(/\//g,"_").substring(1)),t.initConfig.autoTrackPageDurationInterval&&(t.stopPageDurationTimer(),t.startPageDurationTimer()),t.sendRetained(e.type),t.sendData(s)},t.getParams=function(e){var n=e.event,r=e.desc,i=e.privateParamMap,a=void 0===i?{}:i,o=e.itemKey,s=t.initConfig.business,c=window.innerWidth,u=window.innerHeight,g=window.screen.width,l=window.screen.height,d=t.filterSensitiveData(s||{}),p=t.filterSensitiveData(t.userInfo||{}),f=t.filterSensitiveData(a||{}),h=t.filterSensitiveData(t.getQueryValue()||{}),m={currentUrl:f.currentUrl||t.currentUrl,business:Object.assign({},d,f.business||{}),pageWidth:c,pageHeight:u,screenWidth:g,screenHeight:l,sdkVersion:t.sdkVersion,systemsInfo:t.systemsInfo,urlParams:h,userInfo:p,deviceId:t.deviceId};return f.targetEle&&(m.targetEle=f.targetEle),f.targetUrl&&(m.targetUrl=f.targetUrl),f.pointerType&&(m.pointerType=f.pointerType),f.elementSelector&&(m.elementSelector=f.elementSelector),f.retainedDuration&&(m.retainedDuration=f.retainedDuration),{event:n,desc:r,itemKey:o||t.getItemKey(),requestTime:t.getTimeStamp(),privateParamMap:m}},t.shouldSample=function(){var e=t.initConfig.sampleRate;return e>=1||!(e<=0)&&Math.random()<e},t.flushBatchQueue=function(){var e=t.getBatchQueueFromStorage();if(0!==e.length){var n=t.getTimeStamp(),r=e.filter((function(e){return!e._nextRetryTime||e._nextRetryTime<=n}));if(0!==r.length){var i=e.filter((function(e){return!!e._nextRetryTime&&e._nextRetryTime>n}));t.saveBatchQueueToStorage(i),t.sendBatchData(r)}else t.initConfig.showLog&&t.printLog("批量队列中有 "+e.length+" 条数据等待重试")}},t.sendBatchData=function(e){var n=t.initConfig,r=n.serverUrl,i=n.contentType,a=n.showLog,o=n.sendMethod,s=n.header;if(a&&(t.printLog("批量发送 "+e.length+" 条数据"),e.forEach((function(e){return t.printLog(e)}))),t.shouldUseBeacon(o,void 0,s))try{var c=new Blob([JSON.stringify(e)],{type:i||"application/json"});navigator.sendBeacon(r,c)?(t.saveBatchQueueToStorage([]),a&&t.printLog("批量发送成功: "+e.length+" 条数据")):(t.printLog("批量发送失败: sendBeacon 返回 false,数据已重新加入队列"),t.retryBatchData(e))}catch(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}else t.ajax({url:r,type:"POST",data:JSON.stringify({events:e}),contentType:i,credentials:!1,timeout:t.initConfig.sendTimeout,cors:!0,success:function(){t.saveBatchQueueToStorage([]),t.initConfig.showLog&&t.printLog("批量发送成功: "+e.length+" 条数据")},error:function(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}})},t.retryBatchData=function(e){var n=t.getBatchQueueFromStorage(),i=function(e){return e.event+"_"+e.itemKey+"_"+e.requestTime},a=new Set(n.map(i)),o=t.getTimeStamp(),s=e.filter((function(e){var n=i(e);if(a.has(n))return!1;var r=(e._retryCount||0)+1;return r>3?(t.initConfig.showLog&&t.printLog("数据已达到最大重试次数,放弃重试: "+n),!1):(e._retryCount=r,e._nextRetryTime=o+1e3*Math.pow(2,r),a.add(n),!0)})),c=r(r([],s),n),u=2*t.initConfig.batchMaxSize,g=c.length>u?c.slice(0,u):c;t.saveBatchQueueToStorage(g),t.initConfig.showLog&&t.printLog("已将 "+s.length+" 条数据加入重试队列")},t.addToBatchQueue=function(e){var n=t.initConfig,r=n.batchInterval,i=n.batchMaxSize;if(t.shouldSample()){var a=t.getBatchQueueFromStorage();a.push(e),t.saveBatchQueueToStorage(a),a.length>=i?t.flushBatchQueue():t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}else t.initConfig.showLog&&t.printLog("数据已采样跳过(批量模式)")},t.restoreBatchQueueFromStorage=function(){var e=t.getBatchQueueFromStorage();if(e.length>0){t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送数据");var n=t.initConfig.batchMaxSize;if(e.length>=n)t.flushBatchQueue();else{var r=t.initConfig.batchInterval;t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}}},t.addToPendingRequests=function(e){var n=t.getPendingRequestsFromStorage();n.push(e);var r=t.initConfig.pendingRequestsMaxSize||t.DEFAULT_PENDING_REQUESTS_MAX_SIZE;if(n.length>r){var i=n.slice(-r);t.initConfig.showLog&&t.printLog("待发送请求队列已满,已移除最旧的数据(最大限制: "+r+")"),t.savePendingRequestsToStorage(i)}else t.savePendingRequestsToStorage(n)},t.restorePendingRequestsFromStorage=function(){var e=t.getPendingRequestsFromStorage();e.length>0&&t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送请求")},t.isPageUnloading=function(){return"hidden"===document.visibilityState},t.sendWithBeacon=function(e,n,r){try{var i=new Blob([JSON.stringify(e)],{type:r||"application/json"});return navigator.sendBeacon(n,i)}catch(e){return t.initConfig.showLog&&t.printLog("sendBeacon 发送失败: "+e),!1}},t.flushPendingRequests=function(){var e=t.getPendingRequestsFromStorage();if(0!==e.length){t.savePendingRequestsToStorage([]);var n=t.initConfig,r=n.serverUrl,i=n.sendTimeout,a=n.contentType,o=n.showLog,s=n.header;e.forEach((function(e){t.shouldSample()?(o&&t.printLog(e),t.ajax({header:s,url:r,type:"POST",data:JSON.stringify(e),contentType:a,credentials:!1,timeout:i,cors:!0,success:function(){o&&t.printLog("待发送请求发送成功")},error:function(e){o&&t.printLog("待发送请求发送失败(不再重试): "+e)}})):o&&t.printLog("待发送请求已采样跳过")}))}},t.setupBeforeUnloadListener=function(){t.isUnloadListenerSetup||(t.isUnloadListenerSetup=!0,document.addEventListener("visibilitychange",(function(){t.isPageUnloading()&&t.flushPendingData()})),window.addEventListener("beforeunload",(function(){t.flushPendingData()})),window.addEventListener("pagehide",(function(){t.flushPendingData()})))},t.isFlushingPendingData=!1,t.flushPendingData=function(){if(!t.isFlushingPendingData){t.stopPageDurationTimer();var e=[],n=t.getBatchQueueFromStorage();n.length>0&&e.push.apply(e,n);var r=t.getPendingRequestsFromStorage();if(r.length>0&&e.push.apply(e,r),0!==e.length){t.isFlushingPendingData=!0;try{t.initConfig.batchSend?t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(e)):t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.initConfig.showLog&&t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}if(navigator.sendBeacon&&t.initConfig.serverUrl)try{var i=1===e.length?e[0]:e,a=new Blob([JSON.stringify(i)],{type:t.initConfig.contentType||"application/json"});navigator.sendBeacon(t.initConfig.serverUrl,a)?(t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("页面卸载时成功发送 "+e.length+" 条数据")):t.initConfig.showLog&&t.printLog("sendBeacon 返回 false,数据已保存到 LocalStorage 等待下次恢复")}catch(e){t.initConfig.showLog&&t.printLog("页面卸载时发送数据失败: "+e+",数据已保存到 LocalStorage")}finally{t.isFlushingPendingData=!1}else t.initConfig.showLog&&t.printLog("不支持 sendBeacon,数据已保存到 LocalStorage 等待下次恢复"),t.isFlushingPendingData=!1}}},t.sendData=function(e,n){if(!t.shouldSample())return Promise.resolve({success:!0,message:"数据已采样跳过"});var r=t.initConfig,i=r.serverUrl,a=r.sendTimeout,o=r.contentType,s=r.showLog,c=r.header,u=r.batchSend,g=r.sendMethod;return s&&t.printLog(e),u?(t.addToBatchQueue(e),Promise.resolve({success:!0,message:"已添加到批量队列"})):t.shouldUseBeacon(g,n,c)?t.isPageUnloading()?t.sendWithBeacon(e,i,o)?Promise.resolve({success:!0,message:"页面卸载时发送成功"}):(t.addToPendingRequests(e),Promise.resolve({success:!0,message:"已添加到待发送队列"})):t.sendBeacon({contentType:o,url:i,data:e}).catch((function(n){return t.addToPendingRequests(e),Promise.resolve({success:!0,message:"sendBeacon 失败,已添加到待发送队列"})})):new Promise((function(r,s){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!c&&t.sendWithBeacon(e,i,o))return void r({success:!0,message:"页面卸载时使用 sendBeacon 发送成功"});t.ajax({header:n||c,url:i,type:"POST",data:JSON.stringify(e),contentType:o,credentials:!1,timeout:a,cors:!0,success:function(e){return r({success:!0,data:e})},error:function(a,u){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!c&&t.sendWithBeacon(e,i,o))return void r({success:!0,message:"XMLHttpRequest 失败,已使用 sendBeacon 发送"});s({success:!1,message:String(a),code:u})}})}))},t.shouldUseBeacon=function(e,n,r){return"xhr"!==e&&("beacon"===e?!0===t.isSupportBeaconSend():!0===t.isSupportBeaconSend()&&!n&&!r)},t.sendRetained=function(e){var r=t.getParams({event:"PageRetained",desc:t.eventDescMap.PageRetained});if(["beforeunload","pushState","replaceState","hashchange","popstate"].indexOf(e)>=0){var i=t.getCookie("retainedStartTime"),a=i?+i:t.getTimeStamp(),o=n(n({},r),{privateParamMap:n(n({},r.privateParamMap),{retainedDuration:Math.max(r.requestTime-a,0)})});t.sendData(o),t.setCookie("retainedStartTime",t.getTimeStamp())}},t.trackPageDuration=function(e,n,r){var i;if(void 0===r&&(r=!0),null!=e)i=Math.max(e,0);else{var a=t.getCookie("retainedStartTime"),o=a?+a:t.getTimeStamp(),s=t.getTimeStamp();i=Math.max(s-o,0)}var c=(null==n?void 0:n.desc)||t.eventDescMap.PageRetained,u=(null==n?void 0:n.pageKey)||t.pageKey,g=(null==n?void 0:n.business)||{},l=null==n?void 0:n.header,d=t.getParams({event:"PageRetained",desc:c,itemKey:t.getItemKey(void 0,u),privateParamMap:{business:g,retainedDuration:i}}),p=t.sendData(d,l);return r&&t.setCookie("retainedStartTime",t.getTimeStamp()),p},t.startPageDurationTimer=function(){t.stopPageDurationTimer();var e=t.initConfig.pageDurationInterval||3e4;e<=0?t.initConfig.showLog&&t.printLog("定时上报间隔时间无效,已禁用定时上报"):(t.pageDurationTimer=window.setInterval((function(){"visible"===document.visibilityState&&t.trackPageDuration(e,{desc:"定时上报页面停留时长",business:{reportType:"interval",interval:e}},!0).catch((function(e){t.initConfig.showLog&&t.printLog("定时上报页面停留时长失败: "+e)}))}),e),t.initConfig.showLog&&t.printLog("定时上报页面停留时长已启动,间隔: "+e+"ms"))},t.stopPageDurationTimer=function(){null!==t.pageDurationTimer&&(clearInterval(t.pageDurationTimer),t.pageDurationTimer=null,t.initConfig.showLog&&t.printLog("定时上报页面停留时长已停止"))},t.getItemKey=function(e,n){return[t.initConfig.appKey,(n||t.pageKey).toString(),e?e.toString():void 0].filter((function(e){return!!e})).reduce((function(e,t){return e+(e.length?".":"")+t}),"")},t.sdkVersion="1.2.3",t.initConfig={appKey:"",platform:void 0,showLog:!1,serverUrl:"",autoTrack:!1,sendTimeout:3e3,isTrackSinglePage:!1,contentType:"application/json",business:{},header:void 0,sampleRate:1,batchSend:!1,batchInterval:5e3,batchMaxSize:10,trackPartKeyClick:!1,pendingRequestsMaxSize:50,autoTrackPageDurationInterval:!1,pageDurationInterval:3e4,sendMethod:"auto"},t.systemsInfo={},t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(a,i),a.prototype.addSinglePageEvent=function(e){var t=this,n=window.history.pushState?"popstate":"hashchange";this.each(["pushState","replaceState",n],(function(n){t.addEventListener(window,n,e)}))},a}(function(){function t(){var t=this;this.getSystemsInfo=function(e){var t=navigator.userAgent,n="other",r=[],i={language:navigator.language},a=t.match(/MicroMessenger\/([\d\.]+)/i),o=a&&a[1]?a[1]:null,s=t.match(/(ipod).*\s([\d_]+)/i),c=t.match(/(ipad).*\s([\d_]+)/i),u=t.match(/(iphone)\sos\s([\d_]+)/i),g=t.match(/(android)\s([\d\.]+)/i),l=t.match(/(Windows NT)\s([\d\.]+)/i),d=t.match(/(Mac OS X)\s([\d_]+)/i);r=[],g?(r.push("Android "+g[2]),n="h5"):u?(r.push("iPhone, iOS "+u[2].replace(/_/g,".")),n="h5"):c?(r.push("iPad, iOS "+c[2].replace(/_/g,".")),n="ipad"):s?(r.push("iPod, iOS "+s[2].replace(/_/g,".")),n="h5"):l?(r.push("Windows "+l[2].replace(/_/g,".")),n="pc"):d&&(r.push("Mac, MacOS "+d[2].replace(/_/g,".")),n="pc"),o&&r.push("WeChat "+o),i.client=r.length?r.join(", "):"Unknown",i.platform=e||n;var p=t.toLowerCase().match(/ nettype\/([^ ]+)/g);return p&&p[0]&&(r=[(p=p[0].split("/"))[1]],i.network=r.length?r.join(", "):"Unknown"),i.ua=t,i},this.addEventListener=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,(function(t){return n.call(e,t)}),!1)},this.removeEventListener=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n):e.detachEvent&&e.detachEvent("on"+t,(function(t){return n.call(e,t)}),!0)},this.rewriteHistory=function(){var e=window.history,t=function(e){var t=window.history,n=t[e],r=new Event(e);return function(){var e=n.apply(t,arguments);return r.arguments=arguments,window.dispatchEvent(r),e}};window.history.pushState&&(e.pushState=t("pushState"),e.replaceState=t("replaceState"))},this.isArray=Array.isArray||function(e){return"[object Array]"===toString.call(e)},this.formatJsonString=function(e){try{return JSON.stringify(e,null," ")}catch(t){return JSON.stringify(e)}},this.nativeForEach=Array.prototype.forEach,this.slice=Array.prototype.slice,this.hasOwnProperty=Object.prototype.hasOwnProperty,this.breaker={},this.each=function(e,n,r){if(null==e)return!1;if(t.nativeForEach&&e.forEach===t.nativeForEach)e.forEach(n,r);else if(t.isArray(e)&&e.length===+e.length){for(var i=0,a=e.length;i<a;i++)if(i in e&&n.call(r,e[i],i,e)===t.breaker)return!1}else for(var o in e)if(t.hasOwnProperty.call(e,o)&&n.call(r,e[o],o,e)===t.breaker)return!1;return!0},this.getDomIndex=function(e){if(!e.parentNode)return-1;for(var t=0,n=e.tagName,r=e.parentNode.children,i=0;i<r.length;i++)if(r[i].tagName===n){if(e===r[i])return t;t++}return-1},this.selector=function(e){var n=e.parentNode&&9==e.parentNode.nodeType?-1:t.getDomIndex(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~n?":nth-of-type("+(n+1)+")":"")},this.getDomSelector=function(e,n){if(!e||!e.parentNode||!e.parentNode.children)return!1;n=n&&n.join?n:[];var r=e.nodeName.toLowerCase();return e&&"body"!==r&&1==e.nodeType?(n.unshift(t.selector(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?n.join(" > "):t.getDomSelector(e.parentNode,n)):(n.unshift("body"),n.join(" > "))},this.getCookie=function(e){for(var t=e+"=",n=document.cookie.split(";"),r=0;r<n.length;r++){for(var i=n[r];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(t))return this._decodeURIComponent(i.substring(t.length,i.length))}return null},this.setCookie=function(e,t,n){var r,i="";n=null==n?73e3:n;var a=this.getMainHost();if(r=a?"; domain="+a:"",0!==n){var o=new Date;"s"===String(n).slice(-1)?o.setTime(o.getTime()+1e3*Number(String(n).slice(0,-1))):o.setTime(o.getTime()+24*n*60*60*1e3),i="; expires="+o.toUTCString()}function s(e){return e||!1}var c="",u="",g="";e&&(c=s(e)),t&&(u=s(t)),r&&(g=s(r)),c&&u&&(document.cookie=c+"="+encodeURIComponent(u)+i+"; path=/"+g)},this.getLocalStorage=function(e){try{return localStorage.getItem(e)}catch(e){return null}},this.setLocalStorage=function(e,t){try{localStorage.setItem(e,t)}catch(e){}},this.removeCookie=function(e){t.setCookie(e,"",-1)},this.getTimeStamp=function(){return(new Date).getTime()},this.uuid=function(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}))},this.getDistinctId=function(){var e=t.getCookie("distinctId");return e||(e=t.uuid(),t.setCookie("distinctId",e),e)},this.filterSensitiveData=function(e,n){if(void 0===n&&(n=["password","token","secret","key"]),!t.isObject(e))return e;var r={};return t.each(e,(function(e,i){n.some((function(e){return"string"==typeof i&&i.toLowerCase().includes(e.toLowerCase())}))?r[i]="***":t.isObject(e)?r[i]=t.filterSensitiveData(e,n):r[i]=e})),r},this.xssFilter=function(e){return e?"string"!=typeof e?e.toString():e.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""},this.getQueryValue=function(){for(var e=decodeURI(window.location.href).match(new RegExp("[?&][^?&]+=[^?&]+","g"))||[],t={},n=0;n<e.length;n++){var r=e[n].replace(/\?|\&/,"").split("=");t[r[0]]=r[1]}return Object.keys(t).length>0?t:null},this.ajax=function(n){function r(t){if(!t)return{};if("string"==typeof t)try{return JSON.parse(t)}catch(e){return{}}return"object"===e(t)?t:{}}n.timeout=n.timeout||3e4,n.credentials=void 0===n.credentials||n.credentials;var i=t.xhr(n.cors);if(!i)return!1;n.type||(n.type=n.data?"POST":"GET");var a,o=n.success,s=n.error;n.success=function(e){o&&o(e),a&&(clearTimeout(a),a=null)},n.error=function(e,t){s&&s(e,t),a&&(clearTimeout(a),a=null)},a=window.setTimeout((function(){!function(){try{t.isObject(i)&&i.abort&&i.abort()}catch(e){t.printLog(e)}a&&(clearTimeout(a),a=null,n.error&&n.error(),i.onreadystatechange=null,i.onload=null,i.onerror=null)}()}),n.timeout),i.onreadystatechange=function(){try{4==i.readyState&&(i.status>=200&&i.status<300||304==i.status?n.success&&n.success(r(i.responseText)):n.error&&n.error(r(i.responseText),i.status),i.onreadystatechange=null,i.onload=null)}catch(e){i.onreadystatechange=null,i.onload=null}},i.open(n.type||"GET",n.url,!0);try{n.credentials&&(i.withCredentials=!0),t.isObject(n.header)&&t.each(n.header,(function(e,t){i.setRequestHeader&&i.setRequestHeader(t,e)})),n.data&&(n.cors||i.setRequestHeader&&i.setRequestHeader("X-Requested-With","XMLHttpRequest"),"application/json"===n.contentType?i.setRequestHeader&&i.setRequestHeader("Content-type","application/json; charset=UTF-8"):i.setRequestHeader&&i.setRequestHeader("Content-type","application/x-www-form-urlencoded"))}catch(e){t.printLog(e)}i.send(n.data||null)},this.xhr=function(e){return e?void 0!==window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest?new XMLHttpRequest:null:void 0!==window.XMLHttpRequest?new XMLHttpRequest:null},this.getUA=function(){var e,t={},n=navigator.userAgent.toLowerCase();return(e=n.match(/opera.([\d.]+)/))?t.opera=Number(e[1].split(".")[0]):(e=n.match(/msie ([\d.]+)/))?t.ie=Number(e[1].split(".")[0]):(e=n.match(/edge.([\d.]+)/))?t.edge=Number(e[1].split(".")[0]):(e=n.match(/firefox\/([\d.]+)/))?t.firefox=Number(e[1].split(".")[0]):(e=n.match(/chrome\/([\d.]+)/))?t.chrome=Number(e[1].split(".")[0]):(e=n.match(/version\/([\d.]+).*safari/))?t.safari=Number(e[1].match(/^\d*.\d*/)):(e=n.match(/trident\/([\d.]+)/))&&(t.ie=11),t},this.isSupportBeaconSend=function(){var n=!1;if("object"!==("undefined"==typeof navigator?"undefined":e(navigator))||"function"!=typeof navigator.sendBeacon)return n;var r=t.getUA(),i=navigator.userAgent.toLowerCase();if(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)){var a=(i.match(/os [\d._]*/gi)+"").replace(/[^0-9|_.]/gi,"").replace(/_/gi,".").split(".");void 0===r.safari&&(r.safari=Number(a[0])),a[0]&&+a[0]<13?(r.chrome>41||r.firefox>30||r.opera>25||r.safari>12)&&(n=!0):(r.chrome>41||r.firefox>30||r.opera>25||r.safari>11.3)&&(n=!0)}else(r.chrome>38||r.edge>13||r.firefox>30||r.opera>25||r.safari>11)&&(n=!0);return n},this.throttle=function(e,t){var n=null,r=0;return function(){for(var i=[],a=0;a<arguments.length;a++)i[a]=arguments[a];var o=Date.now(),s=t-(o-r);s<=0||s>t?(n&&(clearTimeout(n),n=null),r=o,e.apply(void 0,i)):n||(n=window.setTimeout((function(){r=Date.now(),n=null,e.apply(void 0,i)}),s))}},this.debounce=function(e,t){var n=null;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];n&&clearTimeout(n),n=window.setTimeout((function(){e.apply(void 0,r)}),t)}},this.sendBeacon=function(e){if(!0===t.isSupportBeaconSend()){var n={type:e.contentType},r=new Blob([JSON.stringify(e.data)],n);return navigator.sendBeacon(e.url,r)?Promise.resolve({success:!0,message:"发送成功"}):Promise.reject({success:!1,message:"sendBeacon返回false"})}return Promise.reject({success:!1,message:"不支持sendBeacon,发送失败!"})},this.getDeviceId=function(){var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return e;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),r},this.collectFingerprint=function(){var e={};return e.userAgent=navigator.userAgent,e.screenWidth=screen.width,e.screenHeight=screen.height,e.colorDepth=screen.colorDepth,e.pixelDepth=screen.pixelDepth,e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone,e.timezoneOffset=(new Date).getTimezoneOffset(),e.language=navigator.language,e.languages=Array.from(navigator.languages),e.platform=navigator.platform,e.webgl=t.getWebGLFingerprint(),e.canvas=t.getCanvasFingerprint(),e.audio=t.getAudioFingerprint(),e.fonts=t.getFontFingerprint(),e.plugins=t.getPluginsFingerprint(),e.localStorage=t.hasLocalStorage(),e.sessionStorage=t.hasSessionStorage(),e.indexedDB=t.hasIndexedDB(),e.hardwareConcurrency=navigator.hardwareConcurrency,e.deviceMemory=navigator.deviceMemory,e.maxTouchPoints=navigator.maxTouchPoints,e.connection=t.getConnectionFingerprint(),e},this.getWebGLFingerprint=function(){try{var e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!t)return"not-supported";var n=t.getExtension("WEBGL_debug_renderer_info");return(n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):"unknown")+"|"+(n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):"unknown")}catch(e){return"error"}},this.getCanvasFingerprint=function(){try{var e=document.createElement("canvas");e.width=200,e.height=50;var t=e.getContext("2d");return t?(t.textBaseline="top",t.font="14px Arial",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText("Canvas fingerprint",2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText("Canvas fingerprint",4,17),e.toDataURL().slice(-50)):"not-supported"}catch(e){return"error"}},this.getAudioFingerprint=function(){try{var e=window.AudioContext||window.webkitAudioContext;if(!e)return"not-supported";var t=new e,n=String(t.sampleRate||0);return t.close(),n}catch(e){return"error"}},this.getFontFingerprint=function(){try{var e=["monospace","sans-serif","serif"],t="mmmmmmmmmmlli",n=document.createElement("canvas").getContext("2d");if(!n)return"not-supported";var r=[],i={};return e.forEach((function(e){n.font="72px "+e,i[e]=n.measureText(t).width})),["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Helvetica","Impact","Times New Roman","Trebuchet MS","Verdana"].forEach((function(a){var o=!1;e.forEach((function(e){n.font="72px '"+a+"', "+e,n.measureText(t).width!==i[e]&&(o=!0)})),o&&r.push(a)})),r.join(",")}catch(e){return"error"}},this.getPluginsFingerprint=function(){try{var e=[];if(navigator.plugins)for(var t=0;t<navigator.plugins.length;t++){var n=navigator.plugins[t];n&&e.push(n.name+"|"+n.description+"|"+n.filename)}return e.join(";")}catch(e){return"error"}},this.hasLocalStorage=function(){try{var e="__test__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}},this.hasSessionStorage=function(){try{var e="__test__";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(e){return!1}},this.hasIndexedDB=function(){return"indexedDB"in window&&null!==indexedDB},this.getConnectionFingerprint=function(){try{var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?e.effectiveType||"unknown":"not-supported"}catch(e){return"error"}},this.hashFingerprint=function(e){for(var t=JSON.stringify(e,Object.keys(e).sort()),n=5381,r=52711,i=0;i<t.length;i++){var a=t.charCodeAt(i);n=(n<<5)+n+a,r=(r<<5)+r+a}return"fp_"+(n>>>0).toString(16).padStart(8,"0")+(r>>>0).toString(16).padStart(8,"0")}}return t.prototype.printLog=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];if(this.isObject(t[0])&&(t[0]=this.formatJsonString(t[0])),"object"===("undefined"==typeof console?"undefined":e(console))&&console.log)try{return console.log.apply(console,t)}catch(e){console.log(t[0])}},t.prototype.isObject=function(e){return null!=e&&"[object Object]"==toString.call(e)},t.prototype.isUndefined=function(e){return void 0===e},t.prototype.isString=function(e){return"[object String]"==toString.call(e)},t.prototype.isDate=function(e){return"[object Date]"==toString.call(e)},t.prototype.isBoolean=function(e){return"[object Boolean]"==toString.call(e)},t.prototype.isNumber=function(e){return"[object Number]"==toString.call(e)&&/[\d\.]+/.test(String(e))},t.prototype.isElement=function(e){return!(!e||1!==e.nodeType)},t.prototype.isFunction=function(e){if(!e)return!1;var t=toString.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t},t.prototype.isJSONString=function(e){if(!this.isString(e))return!1;try{JSON.parse(e)}catch(e){return!1}return!0},t.prototype._decodeURIComponent=function(e){var t=e;try{t=decodeURIComponent(e)}catch(n){t=e}return t},t.prototype.getMainHost=function(){var e="mh_"+Math.random(),t=new RegExp("(^|;)\\s*"+e+"=12345"),n=new Date(0),r=document.domain,i=r.split("."),a=[];for(a.unshift(i.pop());i.length;){a.unshift(i.pop());var o=a.join("."),s=e+"=12345;domain=."+o;if(document.cookie=s,t.test(document.cookie))return document.cookie=s+";expires="+n,o}return r},t}()))}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).WebTracking=t()}(this,(function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,n)};var n=function(){return(n=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)};function r(e,t){for(var n=0,r=t.length,i=e.length;n<r;n++,i++)e[i]=t[n];return e}return new(function(i){function o(){var t=i.call(this)||this;return t.batchTimer=null,t.BATCH_QUEUE_STORAGE_KEY="web_tracking_batch_queue",t.useCustomPageKey=!1,t.isUnloadListenerSetup=!1,t.pageDurationTimer=null,t.PENDING_REQUESTS_STORAGE_KEY="web_tracking_pending_requests",t.DEFAULT_PENDING_REQUESTS_MAX_SIZE=50,t.MAX_STORAGE_SIZE=4194304,t.exposureObserver=null,t.exposureElementsMap=new Map,t.userInfo=null,t.currentUrl="",t.pageKey="",t.deviceId="",t.eventDescMap={PageView:"Web 浏览页面",WebClick:"Web 元素点击",PageRetained:"Web 页面浏览时长",CustomTrack:"Web 自定义代码上报",WebExposure:"Web 元素曝光"},t.init=function(e){t.preset(e);var n=window.location.pathname;t.currentUrl=window.location.href,e.pageKey?(t.pageKey=e.pageKey,t.useCustomPageKey=!0):(t.pageKey=n.replace(/\//g,"_").substring(1),t.useCustomPageKey=!1),t.systemsInfo=t.getSystemsInfo(e.platform),t.deviceId=t.getDeviceId(),e.userInfo&&t.isObject(e.userInfo)&&(t.userInfo=e.userInfo),t.setCookie("retainedStartTime",t.getTimeStamp()),t.initConfig.batchSend&&t.restoreBatchQueueFromStorage(),t.restorePendingRequestsFromStorage(),t.setupBeforeUnloadListener(),t.initConfig.autoTrackPageDurationInterval&&t.startPageDurationTimer(),t.initConfig.autoTrackExposure&&t.initExposureObserver()},t.preset=function(e){if(e instanceof Object){if(void 0!==e.pageKey)if(null===e.pageKey||""===e.pageKey){t.useCustomPageKey=!1;var n=window.location.pathname;t.pageKey=n.replace(/\//g,"_").substring(1)}else t.pageKey=e.pageKey,t.useCustomPageKey=!0;t.each(e,(function(e,n){if("pageKey"!==n&&t.initConfig.hasOwnProperty(n)){var r=t.validateConfigParam(String(n),e);r.valid?t.initConfig[n]=e:t.printLog("配置参数验证失败: "+String(n)+" = "+e+", 原因: "+r.message)}}))}/^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-\(\)]*[\w@?^=%&/~+#-\(\)])?$/.test(t.initConfig.serverUrl)||(t.printLog("当前 server_url 为空或不正确,只在控制台打印日志,network 中不会发数据,请配置正确的 server_url!"),t.initConfig.showLog=!0),t.initConfig.autoTrack||t.initConfig.trackPartKeyClick?t.listener():t.unlistener(),t.initConfig.autoTrackPageDurationInterval?t.startPageDurationTimer():t.stopPageDurationTimer(),t.initConfig.autoTrackExposure?t.initExposureObserver():t.stopExposureObserver()},t.validateConfigParam=function(t,n){switch(t){case"sampleRate":if("number"!=typeof n||n<0||n>1)return{valid:!1,message:"sampleRate 必须是 0-1 之间的数字"};break;case"sendTimeout":if("number"!=typeof n||n<=0)return{valid:!1,message:"sendTimeout 必须是大于 0 的数字"};break;case"batchInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"batchInterval 必须是大于 0 的数字"};break;case"batchMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"batchMaxSize 必须是大于 0 的整数"};break;case"pendingRequestsMaxSize":if("number"!=typeof n||n<=0||!Number.isInteger(n))return{valid:!1,message:"pendingRequestsMaxSize 必须是大于 0 的整数"};break;case"pageDurationInterval":if("number"!=typeof n||n<=0)return{valid:!1,message:"pageDurationInterval 必须是大于 0 的数字"};break;case"sendMethod":if("string"!=typeof n||!["auto","xhr","beacon"].includes(n))return{valid:!1,message:"sendMethod 必须是 auto、xhr 或 beacon"};break;case"exposureThreshold":if("number"!=typeof n||n<0||n>1)return{valid:!1,message:"exposureThreshold 必须是 0-1 之间的数字"};break;case"exposureTime":if("number"!=typeof n||n<=0)return{valid:!1,message:"exposureTime 必须是大于 0 的数字"};break;case"exposureNum":if(void 0!==n&&("number"!=typeof n||n<=0||!Number.isInteger(n)))return{valid:!1,message:"exposureNum 必须是大于 0 的整数或不限制"};break;case"showLog":case"autoTrack":case"isTrackSinglePage":case"batchSend":case"trackPartKeyClick":case"autoTrackPageDurationInterval":if("boolean"!=typeof n)return{valid:!1,message:t+" 必须是布尔值"};break;case"business":case"header":if(null!==n&&"object"!==e(n))return{valid:!1,message:t+" 必须是对象或 null"};break;case"contentType":if("application/json"!==n&&"application/x-www-form-urlencoded"!==n)return{valid:!1,message:"contentType 必须是 application/json 或 application/x-www-form-urlencoded"};break;case"platform":if("string"!=typeof n)return{valid:!1,message:"platform 必须是字符串"}}return{valid:!0}},t.login=function(e){t.isObject(e)&&(t.userInfo=e)},t.getDeviceId=function(){if(t.deviceId)return t.deviceId;var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return t.deviceId=e,t.deviceId;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),t.deviceId=r,t.deviceId},t.resetDeviceId=function(){return document.cookie="device_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;",localStorage.removeItem("device_id"),t.deviceId="",t.getDeviceId()},t.track=function(e){var n=e.desc,r=e.pageKey,i=e.partkey,o=e.business,a=e.header,s=t.getParams({desc:n,event:"CustomTrack",itemKey:t.getItemKey(i,r),privateParamMap:{business:o}});return t.sendData(s,a)},t.listener=function(){t.unlistener(),t.initConfig.autoTrack&&(t.initConfig.isTrackSinglePage&&(t.rewriteHistory(),t.addSinglePageEvent(t.onPageViewCallback)),t.each(["load","beforeunload"],(function(e){t.addEventListener(window,e,t.onPageViewCallback)}))),(t.initConfig.autoTrack||t.initConfig.trackPartKeyClick)&&t.addEventListener(window,"click",t.onClickCallback)},t.unlistener=function(){if(t.initConfig.isTrackSinglePage){var e=window.history.pushState?"popstate":"hashchange";t.each(["pushState","replaceState",e],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)}))}t.each(["load","beforeunload"],(function(e){t.removeEventListener(window,e,t.onPageViewCallback)})),t.removeEventListener(window,"click",t.onClickCallback),t.clearBatchTimer(),t.stopPageDurationTimer()},t.clearBatchTimer=function(){null!==t.batchTimer&&(clearTimeout(t.batchTimer),t.batchTimer=null)},t.clearBatchQueue=function(){t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("批量队列已清空")},t.getBatchQueueFromStorage=function(){try{var e=t.getLocalStorage(t.BATCH_QUEUE_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取批量队列失败: "+e),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]")}return[]},t.saveBatchQueueToStorage=function(e){try{var n=JSON.stringify(e);if(n.length>t.MAX_STORAGE_SIZE){var r=Math.floor(.8*e.length),i=e.slice(-r);t.printLog("队列过大,已截断保留最新 "+r+" 条数据(限制: "+t.MAX_STORAGE_SIZE/1024/1024+"MB)"),t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(i))}else t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,n)}catch(e){t.printLog("保存批量队列到 LocalStorage 失败: "+e)}},t.getPendingRequestsFromStorage=function(){try{var e=t.getLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY);if(e){var n=JSON.parse(e);if(Array.isArray(n))return n}}catch(e){t.printLog("读取待发送请求失败: "+e),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]")}return[]},t.savePendingRequestsToStorage=function(e){try{t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}},t.setPageKey=function(e,n){if(void 0===n&&(n=!1),null===e||""===e){t.useCustomPageKey=!1;var r=window.location.pathname;t.pageKey=r.replace(/\//g,"_").substring(1),t.initConfig.showLog&&t.printLog("页面标识已恢复自动生成: "+t.pageKey)}else t.pageKey=e,t.useCustomPageKey=!n,t.initConfig.showLog&&t.printLog("页面标识已设置为: "+e+", 自动更新: "+n)},t.getPageKey=function(){return t.pageKey},t.onClickCallback=function(e){var n,r=e.target;if(null===(n=null==r?void 0:r.dataset)||void 0===n?void 0:n.partKey){var i=[e.pageX,e.pageY],o=r.id,a=r.className,s={id:o,nodeName:r.nodeName,className:a,position:i},u=t.getParams({event:"WebClick",desc:t.eventDescMap.WebClick,itemKey:t.getItemKey(r.dataset.partKey),privateParamMap:{targetEle:s,pointerType:e.pointerType,currentUrl:t.currentUrl,elementSelector:t.getDomSelector(r)||""}});t.sendData(u)}},t.onPageViewCallback=function(e){var n,r,i=t.getPendingRequestsFromStorage(),o=t.initConfig.batchSend?t.getBatchQueueFromStorage():[];(i.length>0||o.length>0)&&t.flushPendingData();var a=window.location.origin,s=t.getParams({event:"PageView",desc:t.eventDescMap.PageView,privateParamMap:{currentUrl:t.currentUrl,targetUrl:(null===(n=e.arguments)||void 0===n?void 0:n[2])?a+(null===(r=e.arguments)||void 0===r?void 0:r[2]):null}});t.currentUrl=window.location.href,t.useCustomPageKey||(t.pageKey=window.location.pathname.replace(/\//g,"_").substring(1)),t.initConfig.autoTrackPageDurationInterval&&(t.stopPageDurationTimer(),t.startPageDurationTimer()),t.sendRetained(e.type),t.sendData(s)},t.getParams=function(e){var n=e.event,r=e.desc,i=e.privateParamMap,o=void 0===i?{}:i,a=e.itemKey,s=t.initConfig.business,u=window.innerWidth,c=window.innerHeight,g=window.screen.width,l=window.screen.height,p=t.filterSensitiveData(s||{}),d=t.filterSensitiveData(t.userInfo||{}),f=t.filterSensitiveData(o||{}),h=t.filterSensitiveData(t.getQueryValue()||{}),m={currentUrl:f.currentUrl||t.currentUrl,business:Object.assign({},p,f.business||{}),pageWidth:u,pageHeight:c,screenWidth:g,screenHeight:l,sdkVersion:t.sdkVersion,systemsInfo:t.systemsInfo,urlParams:h,userInfo:d,deviceId:t.deviceId};return f.targetEle&&(m.targetEle=f.targetEle),f.targetUrl&&(m.targetUrl=f.targetUrl),f.pointerType&&(m.pointerType=f.pointerType),f.elementSelector&&(m.elementSelector=f.elementSelector),f.retainedDuration&&(m.retainedDuration=f.retainedDuration),{event:n,desc:r,itemKey:a||t.getItemKey(),requestTime:t.getTimeStamp(),privateParamMap:m}},t.shouldSample=function(){var e=t.initConfig.sampleRate;return e>=1||!(e<=0)&&Math.random()<e},t.flushBatchQueue=function(){var e=t.getBatchQueueFromStorage();if(0!==e.length){var n=t.getTimeStamp(),r=e.filter((function(e){return!e._nextRetryTime||e._nextRetryTime<=n}));if(0!==r.length){var i=e.filter((function(e){return!!e._nextRetryTime&&e._nextRetryTime>n}));t.saveBatchQueueToStorage(i),t.sendBatchData(r)}else t.initConfig.showLog&&t.printLog("批量队列中有 "+e.length+" 条数据等待重试")}},t.sendBatchData=function(e){var n=t.initConfig,r=n.serverUrl,i=n.contentType,o=n.showLog,a=n.sendMethod,s=n.header;if(o&&(t.printLog("批量发送 "+e.length+" 条数据"),e.forEach((function(e){return t.printLog(e)}))),t.shouldUseBeacon(a,void 0,s))try{var u=new Blob([JSON.stringify(e)],{type:i||"application/json"});navigator.sendBeacon(r,u)?(t.saveBatchQueueToStorage([]),o&&t.printLog("批量发送成功: "+e.length+" 条数据")):(t.printLog("批量发送失败: sendBeacon 返回 false,数据已重新加入队列"),t.retryBatchData(e))}catch(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}else t.ajax({url:r,type:"POST",data:JSON.stringify({events:e}),contentType:i,credentials:!1,timeout:t.initConfig.sendTimeout,cors:!0,success:function(){t.saveBatchQueueToStorage([]),t.initConfig.showLog&&t.printLog("批量发送成功: "+e.length+" 条数据")},error:function(n){t.printLog("批量发送失败: "+n+",数据已重新加入队列"),t.retryBatchData(e)}})},t.retryBatchData=function(e){var n=t.getBatchQueueFromStorage(),i=function(e){return e.event+"_"+e.itemKey+"_"+e.requestTime},o=new Set(n.map(i)),a=t.getTimeStamp(),s=e.filter((function(e){var n=i(e);if(o.has(n))return!1;var r=(e._retryCount||0)+1;return r>3?(t.initConfig.showLog&&t.printLog("数据已达到最大重试次数,放弃重试: "+n),!1):(e._retryCount=r,e._nextRetryTime=a+1e3*Math.pow(2,r),o.add(n),!0)})),u=r(r([],s),n),c=2*t.initConfig.batchMaxSize,g=u.length>c?u.slice(0,c):u;t.saveBatchQueueToStorage(g),t.initConfig.showLog&&t.printLog("已将 "+s.length+" 条数据加入重试队列")},t.addToBatchQueue=function(e){var n=t.initConfig,r=n.batchInterval,i=n.batchMaxSize;if(t.shouldSample()){var o=t.getBatchQueueFromStorage();o.push(e),t.saveBatchQueueToStorage(o),o.length>=i?t.flushBatchQueue():t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}else t.initConfig.showLog&&t.printLog("数据已采样跳过(批量模式)")},t.restoreBatchQueueFromStorage=function(){var e=t.getBatchQueueFromStorage();if(e.length>0){t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送数据");var n=t.initConfig.batchMaxSize;if(e.length>=n)t.flushBatchQueue();else{var r=t.initConfig.batchInterval;t.batchTimer||(t.batchTimer=window.setTimeout((function(){t.flushBatchQueue(),t.batchTimer=null}),r))}}},t.addToPendingRequests=function(e){var n=t.getPendingRequestsFromStorage();n.push(e);var r=t.initConfig.pendingRequestsMaxSize||t.DEFAULT_PENDING_REQUESTS_MAX_SIZE;if(n.length>r){var i=n.slice(-r);t.initConfig.showLog&&t.printLog("待发送请求队列已满,已移除最旧的数据(最大限制: "+r+")"),t.savePendingRequestsToStorage(i)}else t.savePendingRequestsToStorage(n)},t.restorePendingRequestsFromStorage=function(){var e=t.getPendingRequestsFromStorage();e.length>0&&t.initConfig.showLog&&t.printLog("从 LocalStorage 恢复 "+e.length+" 条待发送请求")},t.isPageUnloading=function(){return"hidden"===document.visibilityState},t.sendWithBeacon=function(e,n,r){try{var i=new Blob([JSON.stringify(e)],{type:r||"application/json"});return navigator.sendBeacon(n,i)}catch(e){return t.initConfig.showLog&&t.printLog("sendBeacon 发送失败: "+e),!1}},t.flushPendingRequests=function(){var e=t.getPendingRequestsFromStorage();if(0!==e.length){t.savePendingRequestsToStorage([]);var n=t.initConfig,r=n.serverUrl,i=n.sendTimeout,o=n.contentType,a=n.showLog,s=n.header;e.forEach((function(e){t.shouldSample()?(a&&t.printLog(e),t.ajax({header:s,url:r,type:"POST",data:JSON.stringify(e),contentType:o,credentials:!1,timeout:i,cors:!0,success:function(){a&&t.printLog("待发送请求发送成功")},error:function(e){a&&t.printLog("待发送请求发送失败(不再重试): "+e)}})):a&&t.printLog("待发送请求已采样跳过")}))}},t.setupBeforeUnloadListener=function(){t.isUnloadListenerSetup||(t.isUnloadListenerSetup=!0,document.addEventListener("visibilitychange",(function(){t.isPageUnloading()&&t.flushPendingData()})),window.addEventListener("beforeunload",(function(){t.flushPendingData()})),window.addEventListener("pagehide",(function(){t.flushPendingData()})))},t.isFlushingPendingData=!1,t.flushPendingData=function(){if(!t.isFlushingPendingData){t.stopPageDurationTimer();var e=[],n=t.getBatchQueueFromStorage();n.length>0&&e.push.apply(e,n);var r=t.getPendingRequestsFromStorage();if(r.length>0&&e.push.apply(e,r),0!==e.length){t.isFlushingPendingData=!0;try{t.initConfig.batchSend?t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,JSON.stringify(e)):t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,JSON.stringify(e))}catch(e){t.initConfig.showLog&&t.printLog("保存待发送请求到 LocalStorage 失败: "+e)}if(navigator.sendBeacon&&t.initConfig.serverUrl)try{var i=1===e.length?e[0]:e,o=new Blob([JSON.stringify(i)],{type:t.initConfig.contentType||"application/json"});navigator.sendBeacon(t.initConfig.serverUrl,o)?(t.setLocalStorage(t.BATCH_QUEUE_STORAGE_KEY,"[]"),t.setLocalStorage(t.PENDING_REQUESTS_STORAGE_KEY,"[]"),t.initConfig.showLog&&t.printLog("页面卸载时成功发送 "+e.length+" 条数据")):t.initConfig.showLog&&t.printLog("sendBeacon 返回 false,数据已保存到 LocalStorage 等待下次恢复")}catch(e){t.initConfig.showLog&&t.printLog("页面卸载时发送数据失败: "+e+",数据已保存到 LocalStorage")}finally{t.isFlushingPendingData=!1}else t.initConfig.showLog&&t.printLog("不支持 sendBeacon,数据已保存到 LocalStorage 等待下次恢复"),t.isFlushingPendingData=!1}}},t.sendData=function(e,n){if(!t.shouldSample())return Promise.resolve({success:!0,message:"数据已采样跳过"});var r=t.initConfig,i=r.serverUrl,o=r.sendTimeout,a=r.contentType,s=r.showLog,u=r.header,c=r.batchSend,g=r.sendMethod;return s&&t.printLog(e),c?(t.addToBatchQueue(e),Promise.resolve({success:!0,message:"已添加到批量队列"})):t.shouldUseBeacon(g,n,u)?t.isPageUnloading()?t.sendWithBeacon(e,i,a)?Promise.resolve({success:!0,message:"页面卸载时发送成功"}):(t.addToPendingRequests(e),Promise.resolve({success:!0,message:"已添加到待发送队列"})):t.sendBeacon({contentType:a,url:i,data:e}).catch((function(n){return t.addToPendingRequests(e),Promise.resolve({success:!0,message:"sendBeacon 失败,已添加到待发送队列"})})):new Promise((function(r,s){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!u&&t.sendWithBeacon(e,i,a))return void r({success:!0,message:"页面卸载时使用 sendBeacon 发送成功"});t.ajax({header:n||u,url:i,type:"POST",data:JSON.stringify(e),contentType:a,credentials:!1,timeout:o,cors:!0,success:function(e){return r({success:!0,data:e})},error:function(o,c){if(t.isPageUnloading()&&"auto"===g&&t.isSupportBeaconSend()&&!n&&!u&&t.sendWithBeacon(e,i,a))return void r({success:!0,message:"XMLHttpRequest 失败,已使用 sendBeacon 发送"});s({success:!1,message:String(o),code:c})}})}))},t.shouldUseBeacon=function(e,n,r){return"xhr"!==e&&("beacon"===e?!0===t.isSupportBeaconSend():!0===t.isSupportBeaconSend()&&!n&&!r)},t.sendRetained=function(e){var r=t.getParams({event:"PageRetained",desc:t.eventDescMap.PageRetained});if(["beforeunload","pushState","replaceState","hashchange","popstate"].indexOf(e)>=0){var i=t.getCookie("retainedStartTime"),o=i?+i:t.getTimeStamp(),a=n(n({},r),{privateParamMap:n(n({},r.privateParamMap),{retainedDuration:Math.max(r.requestTime-o,0)})});t.sendData(a),t.setCookie("retainedStartTime",t.getTimeStamp())}},t.trackPageDuration=function(e,n,r){var i;if(void 0===r&&(r=!0),null!=e)i=Math.max(e,0);else{var o=t.getCookie("retainedStartTime"),a=o?+o:t.getTimeStamp(),s=t.getTimeStamp();i=Math.max(s-a,0)}var u=(null==n?void 0:n.desc)||t.eventDescMap.PageRetained,c=(null==n?void 0:n.pageKey)||t.pageKey,g=(null==n?void 0:n.business)||{},l=null==n?void 0:n.header,p=t.getParams({event:"PageRetained",desc:u,itemKey:t.getItemKey(void 0,c),privateParamMap:{business:g,retainedDuration:i}}),d=t.sendData(p,l);return r&&t.setCookie("retainedStartTime",t.getTimeStamp()),d},t.startPageDurationTimer=function(){t.stopPageDurationTimer();var e=t.initConfig.pageDurationInterval||3e4;e<=0?t.initConfig.showLog&&t.printLog("定时上报间隔时间无效,已禁用定时上报"):(t.pageDurationTimer=window.setInterval((function(){"visible"===document.visibilityState&&t.trackPageDuration(e,{desc:"定时上报页面停留时长",business:{reportType:"interval",interval:e}},!0).catch((function(e){t.initConfig.showLog&&t.printLog("定时上报页面停留时长失败: "+e)}))}),e),t.initConfig.showLog&&t.printLog("定时上报页面停留时长已启动,间隔: "+e+"ms"))},t.stopPageDurationTimer=function(){null!==t.pageDurationTimer&&(clearInterval(t.pageDurationTimer),t.pageDurationTimer=null,t.initConfig.showLog&&t.printLog("定时上报页面停留时长已停止"))},t.getItemKey=function(e,n){return[t.initConfig.appKey,(n||t.pageKey).toString(),e?e.toString():void 0].filter((function(e){return!!e})).reduce((function(e,t){return e+(e.length?".":"")+t}),"")},t.extractDataAttributes=function(e){for(var t={},n=e;n;){for(var r=n.attributes,i=0;i<r.length;i++){var o=r[i],a=o.name;if(a.startsWith("data-")&&"data-exposure"!==a&&"data-part-key"!==a&&"data-desc"!==a){var s=o.value;if(s)t[a.replace(/^data-/,"").split("-").map((function(e,t){return 0===t?e:e.charAt(0).toUpperCase()+e.slice(1)})).join("")]=s}}if((n=n.parentElement)&&"BODY"===n.tagName)break}return t},t.initExposureObserver=function(){if(t.initConfig.autoTrackExposure)if("IntersectionObserver"in window){var e=t.initConfig.exposureThreshold||.5;t.exposureObserver=new IntersectionObserver((function(e){e.forEach((function(e){var n=e.target,r=t.exposureElementsMap.get(n);if(r){var i=t.initConfig.exposureTime||500;e.isIntersecting?(r.isVisible=!0,r.visibleStartTime=t.getTimeStamp(),r.exposureTimer&&clearTimeout(r.exposureTimer),r.exposureTimer=window.setTimeout((function(){r.isVisible&&t.reportExposure(n)}),i)):(r.isVisible=!1,r.exposureTimer&&(clearTimeout(r.exposureTimer),r.exposureTimer=null))}}))}),{threshold:e}),t.observeExposureElements()}else t.initConfig.showLog&&t.printLog("当前浏览器不支持 IntersectionObserver,无法启用曝光埋点")},t.observeExposureElements=function(){if(t.exposureObserver){var e=document.querySelectorAll('[data-exposure="true"]');e.forEach((function(e){if(!t.exposureElementsMap.has(e)){var n=e;t.exposureElementsMap.set(n,{element:n,visibleStartTime:0,exposureCount:0,isVisible:!1,exposureTimer:null}),t.exposureObserver.observe(n)}})),t.initConfig.showLog&&e.length>0&&t.printLog("已监听 "+e.length+" 个曝光元素")}},t.reportExposure=function(e){var n=t.exposureElementsMap.get(e);if(n){var r=t.initConfig.exposureNum;if(void 0!==r&&n.exposureCount>=r)t.initConfig.showLog&&t.printLog("元素已达到最大曝光次数限制: "+r);else{var i=t.extractDataAttributes(e),o=e.getAttribute("data-desc")||t.eventDescMap.WebExposure,a=e.getAttribute("data-part-key")||"exposure",s=t.getParams({event:"WebExposure",desc:o,itemKey:t.getItemKey(a),privateParamMap:{business:i}});t.sendData(s).then((function(){n.exposureCount++,n.exposureTimer&&(clearTimeout(n.exposureTimer),n.exposureTimer=null),t.initConfig.showLog&&t.printLog("曝光上报成功,当前曝光次数: "+n.exposureCount)})).catch((function(e){t.initConfig.showLog&&t.printLog("曝光上报失败: "+e)}))}}},t.stopExposureObserver=function(){t.exposureObserver&&(t.exposureObserver.disconnect(),t.exposureObserver=null,t.exposureElementsMap.forEach((function(e){e.exposureTimer&&clearTimeout(e.exposureTimer)})),t.exposureElementsMap.clear(),t.initConfig.showLog&&t.printLog("曝光监听已停止"))},t.sdkVersion="1.2.4",t.initConfig={appKey:"",platform:void 0,showLog:!1,serverUrl:"",autoTrack:!1,sendTimeout:3e3,isTrackSinglePage:!1,contentType:"application/json",business:{},header:void 0,sampleRate:1,batchSend:!1,batchInterval:5e3,batchMaxSize:10,trackPartKeyClick:!1,pendingRequestsMaxSize:50,autoTrackPageDurationInterval:!1,pageDurationInterval:3e4,sendMethod:"auto",autoTrackExposure:!1,exposureThreshold:.5,exposureTime:500,exposureNum:void 0},t.systemsInfo={},t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(o,i),o.prototype.addSinglePageEvent=function(e){var t=this,n=window.history.pushState?"popstate":"hashchange";this.each(["pushState","replaceState",n],(function(n){t.addEventListener(window,n,e)}))},o}(function(){function t(){var t=this;this.getSystemsInfo=function(e){var t=navigator.userAgent,n="other",r=[],i={language:navigator.language},o=t.match(/MicroMessenger\/([\d\.]+)/i),a=o&&o[1]?o[1]:null,s=t.match(/(ipod).*\s([\d_]+)/i),u=t.match(/(ipad).*\s([\d_]+)/i),c=t.match(/(iphone)\sos\s([\d_]+)/i),g=t.match(/(android)\s([\d\.]+)/i),l=t.match(/(Windows NT)\s([\d\.]+)/i),p=t.match(/(Mac OS X)\s([\d_]+)/i);r=[],g?(r.push("Android "+g[2]),n="h5"):c?(r.push("iPhone, iOS "+c[2].replace(/_/g,".")),n="h5"):u?(r.push("iPad, iOS "+u[2].replace(/_/g,".")),n="ipad"):s?(r.push("iPod, iOS "+s[2].replace(/_/g,".")),n="h5"):l?(r.push("Windows "+l[2].replace(/_/g,".")),n="pc"):p&&(r.push("Mac, MacOS "+p[2].replace(/_/g,".")),n="pc"),a&&r.push("WeChat "+a),i.client=r.length?r.join(", "):"Unknown",i.platform=e||n;var d=t.toLowerCase().match(/ nettype\/([^ ]+)/g);return d&&d[0]&&(r=[(d=d[0].split("/"))[1]],i.network=r.length?r.join(", "):"Unknown"),i.ua=t,i},this.addEventListener=function(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,(function(t){return n.call(e,t)}),!1)},this.removeEventListener=function(e,t,n){e.removeEventListener?e.removeEventListener(t,n):e.detachEvent&&e.detachEvent("on"+t,(function(t){return n.call(e,t)}),!0)},this.rewriteHistory=function(){var e=window.history,t=function(e){var t=window.history,n=t[e],r=new Event(e);return function(){var e=n.apply(t,arguments);return r.arguments=arguments,window.dispatchEvent(r),e}};window.history.pushState&&(e.pushState=t("pushState"),e.replaceState=t("replaceState"))},this.isArray=Array.isArray||function(e){return"[object Array]"===toString.call(e)},this.formatJsonString=function(e){try{return JSON.stringify(e,null," ")}catch(t){return JSON.stringify(e)}},this.nativeForEach=Array.prototype.forEach,this.slice=Array.prototype.slice,this.hasOwnProperty=Object.prototype.hasOwnProperty,this.breaker={},this.each=function(e,n,r){if(null==e)return!1;if(t.nativeForEach&&e.forEach===t.nativeForEach)e.forEach(n,r);else if(t.isArray(e)&&e.length===+e.length){for(var i=0,o=e.length;i<o;i++)if(i in e&&n.call(r,e[i],i,e)===t.breaker)return!1}else for(var a in e)if(t.hasOwnProperty.call(e,a)&&n.call(r,e[a],a,e)===t.breaker)return!1;return!0},this.getDomIndex=function(e){if(!e.parentNode)return-1;for(var t=0,n=e.tagName,r=e.parentNode.children,i=0;i<r.length;i++)if(r[i].tagName===n){if(e===r[i])return t;t++}return-1},this.selector=function(e){var n=e.parentNode&&9==e.parentNode.nodeType?-1:t.getDomIndex(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~n?":nth-of-type("+(n+1)+")":"")},this.getDomSelector=function(e,n){if(!e||!e.parentNode||!e.parentNode.children)return!1;n=n&&n.join?n:[];var r=e.nodeName.toLowerCase();return e&&"body"!==r&&1==e.nodeType?(n.unshift(t.selector(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?n.join(" > "):t.getDomSelector(e.parentNode,n)):(n.unshift("body"),n.join(" > "))},this.getCookie=function(e){for(var t=e+"=",n=document.cookie.split(";"),r=0;r<n.length;r++){for(var i=n[r];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(t))return this._decodeURIComponent(i.substring(t.length,i.length))}return null},this.setCookie=function(e,t,n){var r,i="";n=null==n?73e3:n;var o=this.getMainHost();if(r=o?"; domain="+o:"",0!==n){var a=new Date;"s"===String(n).slice(-1)?a.setTime(a.getTime()+1e3*Number(String(n).slice(0,-1))):a.setTime(a.getTime()+24*n*60*60*1e3),i="; expires="+a.toUTCString()}function s(e){return e||!1}var u="",c="",g="";e&&(u=s(e)),t&&(c=s(t)),r&&(g=s(r)),u&&c&&(document.cookie=u+"="+encodeURIComponent(c)+i+"; path=/"+g)},this.getLocalStorage=function(e){try{return localStorage.getItem(e)}catch(e){return null}},this.setLocalStorage=function(e,t){try{localStorage.setItem(e,t)}catch(e){}},this.removeCookie=function(e){t.setCookie(e,"",-1)},this.getTimeStamp=function(){return(new Date).getTime()},this.uuid=function(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}))},this.getDistinctId=function(){var e=t.getCookie("distinctId");return e||(e=t.uuid(),t.setCookie("distinctId",e),e)},this.filterSensitiveData=function(e,n){if(void 0===n&&(n=["password","token","secret","key"]),!t.isObject(e))return e;var r={};return t.each(e,(function(e,i){n.some((function(e){return"string"==typeof i&&i.toLowerCase().includes(e.toLowerCase())}))?r[i]="***":t.isObject(e)?r[i]=t.filterSensitiveData(e,n):r[i]=e})),r},this.xssFilter=function(e){return e?"string"!=typeof e?e.toString():e.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""},this.getQueryValue=function(){for(var e=decodeURI(window.location.href).match(new RegExp("[?&][^?&]+=[^?&]+","g"))||[],t={},n=0;n<e.length;n++){var r=e[n].replace(/\?|\&/,"").split("=");t[r[0]]=r[1]}return Object.keys(t).length>0?t:null},this.ajax=function(n){function r(t){if(!t)return{};if("string"==typeof t)try{return JSON.parse(t)}catch(e){return{}}return"object"===e(t)?t:{}}n.timeout=n.timeout||3e4,n.credentials=void 0===n.credentials||n.credentials;var i=t.xhr(n.cors);if(!i)return!1;n.type||(n.type=n.data?"POST":"GET");var o,a=n.success,s=n.error;n.success=function(e){a&&a(e),o&&(clearTimeout(o),o=null)},n.error=function(e,t){s&&s(e,t),o&&(clearTimeout(o),o=null)},o=window.setTimeout((function(){!function(){try{t.isObject(i)&&i.abort&&i.abort()}catch(e){t.printLog(e)}o&&(clearTimeout(o),o=null,n.error&&n.error(),i.onreadystatechange=null,i.onload=null,i.onerror=null)}()}),n.timeout),i.onreadystatechange=function(){try{4==i.readyState&&(i.status>=200&&i.status<300||304==i.status?n.success&&n.success(r(i.responseText)):n.error&&n.error(r(i.responseText),i.status),i.onreadystatechange=null,i.onload=null)}catch(e){i.onreadystatechange=null,i.onload=null}},i.open(n.type||"GET",n.url,!0);try{n.credentials&&(i.withCredentials=!0),t.isObject(n.header)&&t.each(n.header,(function(e,t){i.setRequestHeader&&i.setRequestHeader(t,e)})),n.data&&(n.cors||i.setRequestHeader&&i.setRequestHeader("X-Requested-With","XMLHttpRequest"),"application/json"===n.contentType?i.setRequestHeader&&i.setRequestHeader("Content-type","application/json; charset=UTF-8"):i.setRequestHeader&&i.setRequestHeader("Content-type","application/x-www-form-urlencoded"))}catch(e){t.printLog(e)}i.send(n.data||null)},this.xhr=function(e){return e?void 0!==window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest?new XMLHttpRequest:null:void 0!==window.XMLHttpRequest?new XMLHttpRequest:null},this.getUA=function(){var e,t={},n=navigator.userAgent.toLowerCase();return(e=n.match(/opera.([\d.]+)/))?t.opera=Number(e[1].split(".")[0]):(e=n.match(/msie ([\d.]+)/))?t.ie=Number(e[1].split(".")[0]):(e=n.match(/edge.([\d.]+)/))?t.edge=Number(e[1].split(".")[0]):(e=n.match(/firefox\/([\d.]+)/))?t.firefox=Number(e[1].split(".")[0]):(e=n.match(/chrome\/([\d.]+)/))?t.chrome=Number(e[1].split(".")[0]):(e=n.match(/version\/([\d.]+).*safari/))?t.safari=Number(e[1].match(/^\d*.\d*/)):(e=n.match(/trident\/([\d.]+)/))&&(t.ie=11),t},this.isSupportBeaconSend=function(){var n=!1;if("object"!==("undefined"==typeof navigator?"undefined":e(navigator))||"function"!=typeof navigator.sendBeacon)return n;var r=t.getUA(),i=navigator.userAgent.toLowerCase();if(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)){var o=(i.match(/os [\d._]*/gi)+"").replace(/[^0-9|_.]/gi,"").replace(/_/gi,".").split(".");void 0===r.safari&&(r.safari=Number(o[0])),o[0]&&+o[0]<13?(r.chrome>41||r.firefox>30||r.opera>25||r.safari>12)&&(n=!0):(r.chrome>41||r.firefox>30||r.opera>25||r.safari>11.3)&&(n=!0)}else(r.chrome>38||r.edge>13||r.firefox>30||r.opera>25||r.safari>11)&&(n=!0);return n},this.throttle=function(e,t){var n=null,r=0;return function(){for(var i=[],o=0;o<arguments.length;o++)i[o]=arguments[o];var a=Date.now(),s=t-(a-r);s<=0||s>t?(n&&(clearTimeout(n),n=null),r=a,e.apply(void 0,i)):n||(n=window.setTimeout((function(){r=Date.now(),n=null,e.apply(void 0,i)}),s))}},this.debounce=function(e,t){var n=null;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];n&&clearTimeout(n),n=window.setTimeout((function(){e.apply(void 0,r)}),t)}},this.sendBeacon=function(e){if(!0===t.isSupportBeaconSend()){var n={type:e.contentType},r=new Blob([JSON.stringify(e.data)],n);return navigator.sendBeacon(e.url,r)?Promise.resolve({success:!0,message:"发送成功"}):Promise.reject({success:!1,message:"sendBeacon返回false"})}return Promise.reject({success:!1,message:"不支持sendBeacon,发送失败!"})},this.getDeviceId=function(){var e=t.getCookie("device_id")||t.getLocalStorage("device_id");if(e)return e;var n=t.collectFingerprint(),r=t.hashFingerprint(n);return t.setCookie("device_id",r,730),t.setLocalStorage("device_id",r),r},this.collectFingerprint=function(){var e={};return e.userAgent=navigator.userAgent,e.screenWidth=screen.width,e.screenHeight=screen.height,e.colorDepth=screen.colorDepth,e.pixelDepth=screen.pixelDepth,e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone,e.timezoneOffset=(new Date).getTimezoneOffset(),e.language=navigator.language,e.languages=Array.from(navigator.languages),e.platform=navigator.platform,e.webgl=t.getWebGLFingerprint(),e.canvas=t.getCanvasFingerprint(),e.audio=t.getAudioFingerprint(),e.fonts=t.getFontFingerprint(),e.plugins=t.getPluginsFingerprint(),e.localStorage=t.hasLocalStorage(),e.sessionStorage=t.hasSessionStorage(),e.indexedDB=t.hasIndexedDB(),e.hardwareConcurrency=navigator.hardwareConcurrency,e.deviceMemory=navigator.deviceMemory,e.maxTouchPoints=navigator.maxTouchPoints,e.connection=t.getConnectionFingerprint(),e},this.getWebGLFingerprint=function(){try{var e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!t)return"not-supported";var n=t.getExtension("WEBGL_debug_renderer_info");return(n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):"unknown")+"|"+(n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):"unknown")}catch(e){return"error"}},this.getCanvasFingerprint=function(){try{var e=document.createElement("canvas");e.width=200,e.height=50;var t=e.getContext("2d");return t?(t.textBaseline="top",t.font="14px Arial",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText("Canvas fingerprint",2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText("Canvas fingerprint",4,17),e.toDataURL().slice(-50)):"not-supported"}catch(e){return"error"}},this.getAudioFingerprint=function(){try{var e=window.AudioContext||window.webkitAudioContext;if(!e)return"not-supported";var t=new e,n=String(t.sampleRate||0);return t.close(),n}catch(e){return"error"}},this.getFontFingerprint=function(){try{var e=["monospace","sans-serif","serif"],t="mmmmmmmmmmlli",n=document.createElement("canvas").getContext("2d");if(!n)return"not-supported";var r=[],i={};return e.forEach((function(e){n.font="72px "+e,i[e]=n.measureText(t).width})),["Arial","Arial Black","Comic Sans MS","Courier New","Georgia","Helvetica","Impact","Times New Roman","Trebuchet MS","Verdana"].forEach((function(o){var a=!1;e.forEach((function(e){n.font="72px '"+o+"', "+e,n.measureText(t).width!==i[e]&&(a=!0)})),a&&r.push(o)})),r.join(",")}catch(e){return"error"}},this.getPluginsFingerprint=function(){try{var e=[];if(navigator.plugins)for(var t=0;t<navigator.plugins.length;t++){var n=navigator.plugins[t];n&&e.push(n.name+"|"+n.description+"|"+n.filename)}return e.join(";")}catch(e){return"error"}},this.hasLocalStorage=function(){try{var e="__test__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}},this.hasSessionStorage=function(){try{var e="__test__";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(e){return!1}},this.hasIndexedDB=function(){return"indexedDB"in window&&null!==indexedDB},this.getConnectionFingerprint=function(){try{var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?e.effectiveType||"unknown":"not-supported"}catch(e){return"error"}},this.hashFingerprint=function(e){for(var t=JSON.stringify(e,Object.keys(e).sort()),n=5381,r=52711,i=0;i<t.length;i++){var o=t.charCodeAt(i);n=(n<<5)+n+o,r=(r<<5)+r+o}return"fp_"+(n>>>0).toString(16).padStart(8,"0")+(r>>>0).toString(16).padStart(8,"0")}}return t.prototype.printLog=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];if(this.isObject(t[0])&&(t[0]=this.formatJsonString(t[0])),"object"===("undefined"==typeof console?"undefined":e(console))&&console.log)try{return console.log.apply(console,t)}catch(e){console.log(t[0])}},t.prototype.isObject=function(e){return null!=e&&"[object Object]"==toString.call(e)},t.prototype.isUndefined=function(e){return void 0===e},t.prototype.isString=function(e){return"[object String]"==toString.call(e)},t.prototype.isDate=function(e){return"[object Date]"==toString.call(e)},t.prototype.isBoolean=function(e){return"[object Boolean]"==toString.call(e)},t.prototype.isNumber=function(e){return"[object Number]"==toString.call(e)&&/[\d\.]+/.test(String(e))},t.prototype.isElement=function(e){return!(!e||1!==e.nodeType)},t.prototype.isFunction=function(e){if(!e)return!1;var t=toString.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t},t.prototype.isJSONString=function(e){if(!this.isString(e))return!1;try{JSON.parse(e)}catch(e){return!1}return!0},t.prototype._decodeURIComponent=function(e){var t=e;try{t=decodeURIComponent(e)}catch(n){t=e}return t},t.prototype.getMainHost=function(){var e="mh_"+Math.random(),t=new RegExp("(^|;)\\s*"+e+"=12345"),n=new Date(0),r=document.domain,i=r.split("."),o=[];for(o.unshift(i.pop());i.length;){o.unshift(i.pop());var a=o.join("."),s=e+"=12345;domain=."+a;if(document.cookie=s,t.test(document.cookie))return document.cookie=s+";expires="+n,a}return r},t}()))}));
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * web 数据埋点 SDK
3
3
  * @class WebTracking
4
- * @version 1.2.0
4
+ * @version 1.2.4
5
5
  * key由这几部分组成:appkey.pagekey.partkey 通过“.”来分割
6
6
  * appkey:应用唯一标识
7
7
  * pagekey:页面唯一标识,取当前路由 window.location.pathname.replace(/\//g, '_').substr(1)
@@ -21,6 +21,8 @@ declare class WebTracking extends Tools {
21
21
  private readonly PENDING_REQUESTS_STORAGE_KEY;
22
22
  private readonly DEFAULT_PENDING_REQUESTS_MAX_SIZE;
23
23
  private readonly MAX_STORAGE_SIZE;
24
+ private exposureObserver;
25
+ private exposureElementsMap;
24
26
  constructor();
25
27
  protected userInfo?: JsonProps;
26
28
  protected currentUrl: string;
@@ -226,6 +228,29 @@ declare class WebTracking extends Tools {
226
228
  * @return {[string]}
227
229
  */
228
230
  protected getItemKey: (partkey?: string | number, pageKey?: string | number) => string;
231
+ /**
232
+ * @description 从元素或其祖先节点提取 data-* 属性
233
+ * @param element 目标元素
234
+ * @returns 提取的业务参数对象
235
+ */
236
+ protected extractDataAttributes: (element: HTMLElement) => JsonProps;
237
+ /**
238
+ * @description 初始化曝光监听
239
+ */
240
+ private initExposureObserver;
241
+ /**
242
+ * @description 监听页面上的曝光元素
243
+ */
244
+ private observeExposureElements;
245
+ /**
246
+ * @description 上报曝光事件
247
+ * @param element 曝光元素
248
+ */
249
+ private reportExposure;
250
+ /**
251
+ * @description 停止曝光监听
252
+ */
253
+ private stopExposureObserver;
229
254
  }
230
255
  declare const _default: WebTracking;
231
256
  export default _default;
@@ -33,7 +33,7 @@ export declare type JsonValue = string | number | boolean | null | undefined | J
33
33
  /**
34
34
  * @description 事件类型
35
35
  */
36
- export declare type EventTypes = "PageView" | "PageRetained" | "CustomTrack" | "WebClick";
36
+ export declare type EventTypes = "PageView" | "PageRetained" | "CustomTrack" | "WebClick" | "WebExposure";
37
37
  export interface PresetParams {
38
38
  /**
39
39
  * @description 应用唯一标识(由接口生成)
@@ -137,6 +137,26 @@ export interface PresetParams {
137
137
  * @default 30000 (30秒)
138
138
  */
139
139
  pageDurationInterval?: number;
140
+ /**
141
+ * @description 是否启用曝光埋点
142
+ * @default false
143
+ */
144
+ autoTrackExposure?: boolean;
145
+ /**
146
+ * @description 曝光进入可视区判定阈值(0-1之间)
147
+ * @default 0.5
148
+ */
149
+ exposureThreshold?: number;
150
+ /**
151
+ * @description 曝光可见停留时长阈值(毫秒)
152
+ * @default 500
153
+ */
154
+ exposureTime?: number;
155
+ /**
156
+ * @description 同一元素允许上报的最大曝光次数
157
+ * @default 不限制
158
+ */
159
+ exposureNum?: number;
140
160
  }
141
161
  export interface InitParams extends PresetParams {
142
162
  /**
@@ -534,3 +554,28 @@ export interface DeviceFingerprint {
534
554
  */
535
555
  connection?: string | NetworkConnection;
536
556
  }
557
+ /**
558
+ * @description 曝光元素信息
559
+ */
560
+ export interface ExposureElementInfo {
561
+ /**
562
+ * @description 元素 DOM 节点
563
+ */
564
+ element: HTMLElement;
565
+ /**
566
+ * @description 元素可见开始时间戳
567
+ */
568
+ visibleStartTime: number;
569
+ /**
570
+ * @description 元素曝光次数
571
+ */
572
+ exposureCount: number;
573
+ /**
574
+ * @description 元素是否在可视区
575
+ */
576
+ isVisible: boolean;
577
+ /**
578
+ * @description 曝光定时器
579
+ */
580
+ exposureTimer: number | null;
581
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fle-sdk/event-tracking-web",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "event tracking in web",
5
5
  "author": "飞象前端团队",
6
6
  "license": "ISC",