@fle-sdk/event-tracking-web 1.0.6 → 1.1.1

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,167 +1,389 @@
1
1
  # @fle.sdk/event-tracking-web
2
+ > **构建用户数据体系,让用户行为数据发挥深远的价值。**
2
3
 
3
- > 前端数据埋点 sdk(web)
4
+ <a name="hunDt"></a>
5
+ ## 前言
6
+ **WEB数据埋点sdk,开始之前请确保了解埋点的架构和基础知识**
7
+ > 埋点中比较重要的组成部分就是每个事件的 key,注意的是 key 至少由两部分组成。
8
+ > 完整的 key 由这几部分组成:appkey.pagekey.partkey 通过“.”来分割
4
9
 
5
- ## Install
10
+ - appkey:APP应用唯一标识
11
+ - pagekey:页面唯一标识,默认取当前路由
12
+ - partkey:控件/自定义事件的唯一标识,当是控件触发且没有partkey时,会取当前控件的 id名、class类名、dom节点名称
6
13
 
7
- > 使用 npm 或 yarn 下载
8
14
 
9
- ```js
15
+ <a name="Install"></a>
16
+ ## 一、下载
17
+ ```jsx
10
18
  // npm
11
- npm install @fle.sdk/event-tracking-web --save-dev
19
+ npm install @fle-sdk/event-tracking-web --save-dev
12
20
 
13
21
  // yarn
14
- yarn add @fle.sdk/event-tracking-web
22
+ yarn add @fle-sdk/event-tracking-web
15
23
  ```
16
24
 
17
- ## Brief Introduction
18
25
 
19
- > 埋点中比较重要的组成部分就是每个事件的 key,注意的是 key 至少由两部分组成。完整的 key 由这几部分组成:appkey.pagekey.partkey 通过“.”来分割
20
-
21
- - appkey:应用唯一标识
22
- - pagekey:页面唯一标识,取当前路由 window.location.pathname.replace(/\//g, '\_').substr(1)
23
- - partkey:控件/自定义事件的唯一标识,当是控件触发且没有 partkey 时,会取当前控件的 id/class/dom
24
-
25
- #### Automatic Tracking
26
-
27
- > 初始化 sdk 后,sdk 会对应用进行事件监听,进行自动上报,主要监听以下几个事件
26
+ <a name="uenOv"></a>
27
+ ## 二、全埋点
28
+ > 全埋点包括三种事件:Web 页面浏览、Web 元素点击、Web 页面留存时长,对应的配置如下:
29
+
30
+ ```jsx
31
+ // 初始化
32
+ WebTracking.init({
33
+ appKey: "218844",
34
+ showLog: true,
35
+ autoTrack: true, // 设置该属性之后,SDK 就会自动收集页面浏览事件
36
+ isTrackSinglePage: true,
37
+ contentType: "application/json",
38
+ serverUrl: "https://xxx/push",
39
+ });
40
+ ```
41
+ <a name="yw2Ck"></a>
42
+ ###
43
+ <a name="LTcZG"></a>
44
+ ### 2.1 元素点击
45
+ > 元素的点击事件上报 attr 属性中必须含有 **data-part-key** ,否则会被过滤。
28
46
 
29
- - load(页面初始化)
30
- - beforeunload(页面卸载)
31
- - pushState(追加新路由)
32
- - replaceState(替换当前路由)
33
- - popstate(前进、回退、hash 值改变)
34
- - hashchange(hash 值改变)
35
- - click(点击事件,这个要单独拎出去补充)
47
+ ```jsx
48
+ // 对充值按钮的点击次数进行统计
49
+ <button data-part-key="recharge_btn" data-desc="显示充值弹窗">
50
+ 充值
51
+ </button>
52
+ ```
36
53
 
37
- #### Request Params
54
+ <br />
38
55
 
39
- > 上报参数示例
56
+ <a name="aNxuy"></a>
57
+ ### 2.2 全埋点参数示例
58
+ > 全埋点三种类型的上报参数示例,建议都了解一下
40
59
 
41
60
  ```json
42
61
  {
62
+ "desc": "Web 浏览页面",
63
+ "event": "PageView",
43
64
  "appKey": "218844",
44
- "pageKey": "goods_detail",
45
65
  "siteId": "",
46
- "event": "load",
47
- "desc": "浏览器上报事件:页面加载",
48
- "itemKey": "218844.goods_detail",
49
- "requestTime": 1627377493049,
50
- "deviceId": "c12918a5b139734a78fab0843c62ff51",
66
+ "itemKey": "218844.app_other",
67
+ "requestTime": 1638456820316,
68
+ "deviceId": "f9e3f35a6371f369a2c9f21c48dcabe8",
51
69
  "privateParamMap": {
52
- "sourceUrl": "/app/other",
53
- "sdkVersion": "1.0.6",
54
- "platformType": "pc",
55
- "system": {
70
+ "currentUrl": "http://localhost:9999/app/other",
71
+ "targetUrl": null,
72
+ "sdkVersion": "1.1.0",
73
+ "pageWidth": 742,
74
+ "pageHeight": 867,
75
+ "screenWidth": 1680,
76
+ "screenHeight": 1050,
77
+ "systemsInfo": {
56
78
  "language": "zh-CN",
57
- "location": "https://xxx/goods/detail?goodsId=1000139",
79
+ "platform": "pc",
58
80
  "client": "Mac, MacOS 10.15.7",
59
- "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
60
- "navigationStart": 1627377492850,
61
- "navigation": "6ms",
62
- "dns": "12ms",
63
- "tcp": "30ms",
64
- "request": "300ms",
65
- "response": "8ms"
81
+ "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36",
82
+ "navigationStart": 1638456820099,
83
+ "navigation": "1ms",
84
+ "dns": "0ms",
85
+ "tcp": "0ms",
86
+ "request": "2ms",
87
+ "response": "1ms"
88
+ },
89
+ "urlParams": {},
90
+ "userInfo": {
91
+ "userId": 20211232232123
92
+ }
93
+ }
94
+ }
95
+
96
+ {
97
+ "desc": "Web 元素点击",
98
+ "event": "WebClick",
99
+ "appKey": "218844",
100
+ "siteId": "",
101
+ "itemKey": "218844.main.h1",
102
+ "requestTime": 1638460476808,
103
+ "deviceId": "f9e3f35a6371f369a2c9f21c48dcabe8",
104
+ "privateParamMap": {
105
+ "position": [
106
+ 126,
107
+ 87
108
+ ],
109
+ "targetEle": {
110
+ "id": "",
111
+ "nodeName": "H1",
112
+ "className": ""
113
+ },
114
+ "pointerType": "mouse",
115
+ "currentUrl": "http://localhost:9999/main?a=1",
116
+ "elementSelector": "#root > div:nth-of-type(1) > div:nth-of-type(1) > h1:nth-of-type(1)",
117
+ "sdkVersion": "1.1.0",
118
+ "pageWidth": 742,
119
+ "pageHeight": 867,
120
+ "screenWidth": 1680,
121
+ "screenHeight": 1050,
122
+ "systemsInfo": {
123
+ "language": "zh-CN",
124
+ "platform": "pc",
125
+ "client": "Mac, MacOS 10.15.7",
126
+ "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36",
127
+ "navigationStart": 1638456820099,
128
+ "navigation": "1ms",
129
+ "dns": "0ms",
130
+ "tcp": "0ms",
131
+ "request": "2ms",
132
+ "response": "1ms",
133
+ "domComplete (domLoaded)": "201ms (186ms)",
134
+ "loadEvent": "1ms",
135
+ "total (DOM)": "218ms (217ms)"
66
136
  },
67
137
  "urlParams": {
68
- "goodsId": 1000139
138
+ "a": "1"
139
+ },
140
+ "userInfo": {
141
+ "userId": 20211232232123
69
142
  }
70
143
  }
71
144
  }
72
- ```
73
145
 
74
- #### Click
146
+ {
147
+ "desc": "Web 页面浏览时长",
148
+ "event": "PageRetained",
149
+ "appKey": "218844",
150
+ "siteId": "",
151
+ "itemKey": "218844.app_other",
152
+ "requestTime": 1638460554657,
153
+ "deviceId": "f9e3f35a6371f369a2c9f21c48dcabe8",
154
+ "privateParamMap": {
155
+ "sdkVersion": "1.1.0",
156
+ "pageWidth": 742,
157
+ "pageHeight": 867,
158
+ "screenWidth": 1680,
159
+ "screenHeight": 1050,
160
+ "currentUrl": "http://localhost:9999/app/other",
161
+ "systemsInfo": {
162
+ "language": "zh-CN",
163
+ "platform": "pc",
164
+ "client": "Mac, MacOS 10.15.7",
165
+ "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36",
166
+ "navigationStart": 1638456820099,
167
+ "navigation": "1ms",
168
+ "dns": "0ms",
169
+ "tcp": "0ms",
170
+ "request": "2ms",
171
+ "response": "1ms",
172
+ "domComplete (domLoaded)": "201ms (186ms)",
173
+ "loadEvent": "1ms",
174
+ "total (DOM)": "218ms (217ms)"
175
+ },
176
+ "urlParams": {},
177
+ "userInfo": {
178
+ "userId": 20211232232123
179
+ }
180
+ },
181
+ "retainedStartTime": 1638460451953
182
+ }
183
+ ```
75
184
 
76
- > 监听点击事件上报是有条件的,并不是所有的点击事件都会上报,只有 attr 属性中含有 <b>data-part-key</b> 的控件所触发的事件才会上报。
185
+ <br />
77
186
 
78
- ```js
79
- // 对充值按钮的点击次数进行统计
80
- <button data-part-key="recharge_btn" data-desc="显示充值弹窗">
81
- 充值
82
- </button>
83
- ```
84
187
 
85
188
  ---
86
189
 
87
- ## WebTracking Fun
88
190
 
89
- > 主要用到的两个函数,一个是初始化时调用,一个在手动业务埋点时调用。
90
191
 
91
- - WebTracking.init() ---初始化 sdk
92
- - WebTracking.tracking() ---手动上报
192
+ <a name="95185770"></a>
193
+ ## API
194
+ WebTracking
93
195
 
94
- ### WebTracking.init
196
+ - init() ---初始化
197
+ - preset() ---配置全局参数(注意:如果配置的全局属性初始化已配置,将覆盖。)
198
+ - login() ---用户登录
199
+ - track() ---自定义代码埋点上报
200
+ - getDeviceId() ---获取设备唯一标识
95
201
 
96
- > sdk 初始化说明
97
202
 
98
- #### Params
99
203
 
100
- > sdk 初始化时的参数
204
+ <a name="WebTracking.init"></a>
205
+ ### Init
206
+ <a name="Params"></a>
207
+ #### 参数
208
+ | 参数名 | type | 描述 | 是否必填 | 默认值 |
209
+ | --- | --- | --- | --- | --- |
210
+ | appKey | string | 应用唯一标识(由接口生成) | 是 | - |
211
+ | serverUrl | string | 数据接收地址 | 是 | - |
212
+ | autoTrack | boolean | 是否开启全埋点(指的是:页面浏览、元素点击事件自动上报) | 否 | false |
213
+ | showLog | boolean | 是否在网页控制台打印发送的数据 | 否 | false |
214
+ | useClientTime | boolean | 是否使用客户端系统时间 | 否 | true |
215
+ | sendTimeout | number | 接口发送超时时长,超过该时长未发送成功将强制取消 | 否 | 3000 |
216
+ | isTrackSinglePage | boolean | 是否采集单页面应用的路由变化 | 否 | false |
217
+ | siteId | number/string | 站点 Id | 否 | - |
218
+ | contentType | string | 数据类型:application/json 或 application/x-www-form-urlencoded | 否 | application/x-www-form-urlencoded |
101
219
 
102
- | 参数名 | type | 描述 | 是否必填 | 默认值 |
103
- | ---------- | ------------- | ----------------------------- | -------- | ------ |
104
- | appKey | string | 应用唯一标识(由接口生成) | 是 | - |
105
- | serverApi | string | 接口名 | 是 | - |
106
- | serverHost | string | 服务端 host | 是 | - |
107
- | userId | number/string | 用户 Id,无则根据设备 Id 区分 | 否 | - |
108
- | siteId | number/string | 站点 Id | 否 | - |
220
+ <a name="df0e1504"></a>
221
+ #### 例子
222
+ > 初始化 sdk 例子,建议在 src/App.js 中初始化,且需在**useLayoutEffect**中初始化。
109
223
 
110
- #### Init tracking example
224
+ ```jsx
225
+ import React, { useLayoutEffect } from "react";
226
+ import WebTracking from "@fle-sdk/event-tracking-web";
111
227
 
112
- > 初始化 sdk 例子,建议在 src/App.js 中初始化,且需在<b>useLayoutEffect</b>中初始化。
228
+ const App = () => {
229
+ useLayoutEffect(() => {
230
+ // init tracking
231
+ WebTracking.init({
232
+ appKey: "xxxxxx", // 由接口生成,应用唯一标识
233
+ serverUrl: "https://www.serverHost.com/serverApi/push",
234
+ autoTrack: true,
235
+ showLog: true,
236
+ isTrackSinglePage: true
237
+ });
238
+ }, []);
113
239
 
114
- ```js
240
+ return <div className="App"></div>;
241
+ };
242
+
243
+ export default App;
244
+ ```
245
+
246
+
247
+ <a name="EIsxL"></a>
248
+ ### Preset
249
+ > 除了不可配置appKey、serverUrl,本质上和init差不多,这么做是为了更好的区分使用场景,不产生歧义。
250
+
251
+ <a name="qnIie"></a>
252
+ #### 参数
253
+ | 参数名 | type | 描述 | 是否必填 | 默认值 |
254
+ | --- | --- | --- | --- | --- |
255
+ | autoTrack | boolean | 是否开启全埋点(指的是:页面浏览、元素点击事件自动上报) | 否 | false |
256
+ | showLog | boolean | 是否在网页控制台打印发送的数据 | 否 | false |
257
+ | useClientTime | boolean | 是否使用客户端系统时间 | 否 | true |
258
+ | sendTimeout | number | 接口发送超时时长,超过该时长未发送成功将强制取消 | 否 | 3000 |
259
+ | isTrackSinglePage | boolean | 是否采集单页面应用的路由变化 | 否 | false |
260
+ | siteId | number/string | 站点 Id | 否 | - |
261
+
262
+ <a name="mFBcr"></a>
263
+ #### 例子
264
+ ```jsx
115
265
  import React, { useLayoutEffect } from "react";
116
- import WebTracking from "@fle-sdk/event-tracking-web/lib/index.ems";
266
+ import WebTracking from "@fle-sdk/event-tracking-web";
117
267
 
118
268
  const App = () => {
119
269
  useLayoutEffect(() => {
120
270
  // init tracking
121
271
  WebTracking.init({
122
- appKey: "xxx", // 由接口生成,应用唯一标识
123
- serverApi: "/serverApi/push",
124
- serverHost: "https://www.serverHost.com",
272
+ appKey: "xxxxxx", // 由接口生成,应用唯一标识
273
+ serverUrl: "https://www.serverHost.com/serverApi/push",
125
274
  });
275
+
276
+ // 配置全局参数,初始化后预置属性用该方法。
277
+ // 注意:如果配置的全局属性初始化已配置,将覆盖
278
+ WebTracking.preset({
279
+ autoTrack: true,
280
+ showLog: true,
281
+ isTrackSinglePage: true,
282
+ sendTimeout: 10000
283
+ })
126
284
  }, []);
285
+
286
+ const pageHandle = () => {
287
+ WebTracking.preset({
288
+ autoTrack: false, // 关闭全埋点
289
+ })
290
+ }
127
291
 
128
- return <div className="App"></div>;
292
+ return <div className="App" onClick={pageHandle}></div>;
129
293
  };
130
294
 
131
295
  export default App;
132
296
  ```
133
297
 
134
- ## WebTracking.tracking
135
298
 
136
- #### Params
299
+ <a name="ivnlQ"></a>
300
+ ### Login
301
+ <a name="j3Vbe"></a>
302
+ #### 参数
303
+ | 参数名 | type | 描述 | 是否必填 | 默认值 |
304
+ | --- | --- | --- | --- | --- |
305
+ | userId | string/number | 用户ID | 否 | - |
306
+
307
+ <a name="tN0S5"></a>
308
+ #### 例子
309
+ ```jsx
310
+ import React, { useEffect } from "react";
311
+ import WebTracking from "@fle-sdk/event-tracking-web";
312
+ import { LoginStore } from "store";
313
+
314
+ const Test = () => {
315
+ const getUserInfo = () => {
316
+ const { userId } = await LoginStore.getUserInfo();
317
+ WebTracking.Login("用户ID");
318
+ }
319
+ useEffect(() => {
320
+ getUserInfo()
321
+ }, []);
322
+
323
+ return <div className="Test"></div>;
324
+ };
325
+
326
+ export default Test;
327
+ ```
328
+
329
+ <br />
330
+
331
+ <a name="z7aZJ"></a>
332
+ ### GetDeviceId
333
+ <a name="zzyLD"></a>
334
+ #### 例子
335
+ > 获取设备唯一标识,单用户没有登录时即用户唯一标识
137
336
 
138
- > 手动上报时的参数
337
+ ```jsx
338
+ import React, { useEffect } from "react";
339
+ import WebTracking from "@fle-sdk/event-tracking-web";
340
+ import { LoginStore } from "store";
139
341
 
140
- | 参数名 | type | 描述 | 是否必填 | 默认值 |
141
- | -------- | ------ | ------------------------------------------------------------------------------- | -------- | -------------- |
142
- | partkey | string | 上报事件 Key(由前端自定义,该应用下需唯一且具有一定意义,例:goods_detail_pv) | 是 | - |
143
- | desc | string | 上报事件描述 | 否 | 自定义上报事件 |
144
- | business | object | 上报事件业务参数 | 否 | - |
342
+ const Test = () => {
343
+ useEffect(() => {
344
+ WebTracking.getDeviceId();
345
+ }, []);
346
+
347
+ return <div className="Test"></div>;
348
+ };
349
+
350
+ export default Test;
351
+ ```
145
352
 
146
- #### Custom tracking example
353
+ <br />
147
354
 
148
- > 手动上报例子
355
+ <a name="g6lIP"></a>
356
+ ### Track
357
+ > 手动代码埋点上报
149
358
 
150
- ```js
359
+ <a name="Params-1"></a>
360
+ #### 上报参数
361
+ | 参数名 | type | 描述 | 是否必填 | 默认值 |
362
+ | --- | --- | --- | --- | --- |
363
+ | partkey | string/number | 上报事件 Key(由前后端协商定义或由后端接口生成,该应用下需唯一且具有一定意义,例:goods_detail_pv) | 是 | - |
364
+ | desc | string | 上报事件描述 | 否 | 自定义上报事件 |
365
+ | business | object | 上报的业务参数 | 否 | - |
366
+
367
+
368
+
369
+ <a name="88291229"></a>
370
+ #### 例子
371
+ ```jsx
151
372
  import React, { useEffect } from "react";
152
- import WebTracking from "@fle-sdk/event-tracking-web/lib/index.ems";
373
+ import WebTracking from "@fle-sdk/event-tracking-web";
153
374
 
154
375
  const Index = () => {
155
376
  const history = useHistory();
156
377
 
157
- const tracking = () =>
158
- WebTracking.tracking({ desc: "我是描述", partkey: "xxx" })
159
- .then((res) => alert(res.message || "上报成功!"))
160
- .catch((err) => alert(err.message || "上报失败!"));
378
+ const tracking = () => {
379
+ WebTracking.track({ desc: "我是描述", partkey: "xxx" })
380
+ .then((res) => console.log(res || "上报成功!"))
381
+ .catch((err) => console.log(err || "上报失败!"));
382
+ }
161
383
 
162
384
  // 手动上报商品详情浏览量示例
163
385
  useEffect(() => {
164
- WebTracking.tracking({
386
+ WebTracking.track({
165
387
  desc: "商品详情PV埋点",
166
388
  partkey: "goods_detail_pv",
167
389
  business: {
package/lib/index.ems.js CHANGED
@@ -12,5 +12,5 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
12
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
13
  PERFORMANCE OF THIS SOFTWARE.
14
14
  ***************************************************************************** */
15
- var e=function(){return(e=Object.assign||function(e){for(var t,n=1,o=arguments.length;n<o;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e}).apply(this,arguments)},t=new(function(){function t(){var t=this;this.init=function(e){if(e instanceof Object)for(var n=0,o=Object.entries(e);n<o.length;n++){var a=o[n],r=a[0],i=a[1];void 0!==t.config[r]&&(t.config[r]=i),void 0!==t.otherInfo[r]&&(t.otherInfo[r]=i),void 0!==t.apiConfig[r]&&(t.apiConfig[r]=i)}t.config.pageKey=window.location.pathname.replace(/\//g,"_").substr(1),t.otherInfo.platformType=t.getPlatformType(),t.otherInfo.system=t.systemInfo(),t.currentUrl=window.location.pathname,t.rewriteHistory(),t.listener()},this.tracking=function(e){var n=e.desc,o=e.partkey,a=e.business;return t.trackingPost({event:"customTrack",desc:n||t.eventDescMap.customTrack,itemKey:t.getItemKey(o||"customTrack"),extroInfo:{business:a}})},this.trackingPost=function(n){var o=n.event,a=n.desc,r=n.itemKey,i=n.extroInfo,s=e(e({},t.config),{event:o,desc:a,itemKey:r,requestTime:t.getTimeStamp(),deviceId:t.getDistinctId(),privateParamMap:e(e(e({},i),t.otherInfo),{urlParams:t.getQueryValue()})}),c={url:""+t.apiConfig.serverHost+t.apiConfig.serverApi,headers:{"Content-Type":"application/json"},params:JSON.stringify(s)};return"beforeunload"===o?t.sendBeacon(c):t.httpPost(c)},this.onClick=function(e){if(e.target.dataset.partKey){var n=[e.pageX,e.pageY],o=e.target.id,a=e.target.className,r={nodeName:e.target.nodeName,id:o,className:a},i=document.documentElement.offsetWidth,s=document.documentElement.offsetHeight,c=window.screen.width,d=window.screen.height,u=window.screen.availWidth,h=window.screen.availHeight,p=window.innerWidth,l=window.innerHeight;t.trackingPost({event:"click",desc:e.target.dataset.desc||t.eventDescMap.click,itemKey:t.getItemKey(e.target.dataset.partKey),extroInfo:{position:n,targetEle:r,pageWidth:i,pageHeight:s,screenWidth:c,screenHeight:d,screenAvailWidth:u,screenAvailHeight:h,windowInnerWidth:p,windowInnerHeight:l}})}},this.addRouteEvent=function(e){["load","beforeunload","pushState","replaceState",window.history.pushState?"popstate":"hashchange"].forEach((function(n){t.addEventListener(window,n,e)}))},this.onPushStateHandler=function(e){var n;t.trackingPost({event:e.type,desc:t.eventDescMap[e.type],itemKey:t.getItemKey(),extroInfo:{sourceUrl:t.currentUrl,targetUrl:null===(n=e.arguments)||void 0===n?void 0:n[2]}}),t.currentUrl=window.location.pathname,t.config.pageKey=window.location.pathname.replace(/\//g,"_").substr(1)},this.listener=function(){t.addRouteEvent(t.onPushStateHandler),t.addEventListener(window,"click",t.onClick),t.addEventListener(window,"unload",t.unload)},this.unload=function(){["load","beforeunload","pushState","replaceState",window.history.pushState?"popstate":"hashchange"].forEach((function(e){t.removeEventListener(window,e,t.onPushStateHandler)})),t.removeEventListener(window,"click",t.onClick),t.removeEventListener(window,"unload",t.unload)},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.getItemKey=function(e){var n=t.config;return[n.appKey,n.pageKey,e].filter((function(e){return!!e})).reduce((function(e,t){return e+(e.length?".":"")+t}),"")},this.getQueryValue=function(e){for(var t=decodeURI(window.location.search.substring(1)).split("&"),n={},o=0;o<t.length;o++){var a=t[o].split("=");if(a[0]===e)return a[1];n[a[0]]=a[1]}return e?null:n},this.getTimeStamp=function(){return(new Date).getTime()},this.getDistinctId=function(){var e=t.getCookie("distinctId");return e||(e=t.uuid(),t.setCookie("distinctId",e),e)},this.getPlatformType=function(){for(var e=navigator.userAgent,t=new Array("Android","iPhone","SymbianOS","Windows Phone","iPad","iPod"),n=!0,o=0;o<t.length;o++)if(e.indexOf(t[o])>0){n=!1;break}return n?"pc":"h5"},this.setCookie=function(e,t){document.cookie=e+"="+t+";"+document.cookie},this.getCookie=function(e){e+="=";for(var t=decodeURIComponent(document.cookie).split(";"),n=0;n<t.length;n++){for(var o=t[n];" "===o.charAt(0);)o=o.substring(1);if(0===o.indexOf(e))return o.substring(e.length,o.length)}return""},this.httpPost=function(e){var t=e.url,n=e.headers,o=e.params;return new Promise((function(e,a){var r=new XMLHttpRequest;r.open("post",t),r.onreadystatechange=function(){if(4===r.readyState){if(200===r.status){var t=r.responseText;if(!t)return a({message:"Request Error"});var n=null;try{n=JSON.parse(t)}catch(e){}return n&&"2000"===n.code?e(n):a({message:"Request Error"})}return console.log(r.statusText),a({message:r.statusText})}},r.onerror=function(e){return console.log(r.statusText),a({message:r.statusText})},n instanceof Object&&Object.keys(n).forEach((function(e){r.setRequestHeader(e,n[e])})),r.send(o)}))},this.sendBeacon=function(e){var t=e.url,n=e.params;return"object"==typeof navigator&&"function"==typeof navigator.sendBeacon&&navigator.sendBeacon(t,n),Promise.resolve({message:"发送成功!"})},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.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.rewriteHistory=function(){var e=window.history,t=function(e){var t=window.history,n=t[e],o=new Event(e);return function(){var e=n.apply(t,arguments);return o.arguments=arguments,window.dispatchEvent(o),e}};window.history.pushState&&(e.pushState=t("pushState"),e.replaceState=t("replaceState"))},this.config={appKey:"",pageKey:"",siteId:""},this.otherInfo={sdkVersion:"1.0.6",platformType:"pc"},this.currentUrl="",this.apiConfig={serverApi:"",serverHost:""},this.eventDescMap={load:"浏览器上报事件:页面加载",beforeunload:"浏览器上报事件:页面卸载",pushState:"浏览器上报事件:追加新路由",replaceState:"浏览器上报事件:替换当前路由为新路由",popstate:"浏览器上报事件:前进、回退、hash值改变",hashchange:"浏览器上报事件:hash值改变",click:"点击上报事件",customTrack:"自定义上报事件"}}return t.prototype.systemInfo=function(){var e=navigator.userAgent,t=[],n={language:navigator.language},o=e.match(/MicroMessenger\/([\d\.]+)/i),a=o&&o[1]?o[1]:null;"servicewechat.com"===location.host||(n.location=location.href);var r=e.match(/(ipod).*\s([\d_]+)/i),i=e.match(/(ipad).*\s([\d_]+)/i),s=e.match(/(iphone)\sos\s([\d_]+)/i),c=e.match(/(android)\s([\d\.]+)/i),d=e.match(/(Mac OS X)\s([\d_]+)/i);t=[],c?t.push("Android "+c[2]):s?t.push("iPhone, iOS "+s[2].replace(/_/g,".")):i?t.push("iPad, iOS "+i[2].replace(/_/g,".")):r?t.push("iPod, iOS "+r[2].replace(/_/g,".")):d&&t.push("Mac, MacOS "+d[2].replace(/_/g,".")),a&&t.push("WeChat "+a),n.client=t.length?t.join(", "):"Unknown";var u=e.toLowerCase().match(/ nettype\/([^ ]+)/g);return u&&u[0]&&(t=[(u=u[0].split("/"))[1]],n.network=t.length?t.join(", "):"Unknown"),n.ua=e,setTimeout((function(){var e=window.performance||window.msPerformance||window.webkitPerformance;if(e&&e.timing){var t=e.timing;t.navigationStart&&(n.navigationStart=t.navigationStart),t.navigationStart&&t.domainLookupStart&&(n.navigation=t.domainLookupStart-t.navigationStart+"ms"),t.domainLookupEnd&&t.domainLookupStart&&(n.dns=t.domainLookupEnd-t.domainLookupStart+"ms"),t.connectEnd&&t.connectStart&&(t.connectEnd&&t.secureConnectionStart?n["tcp (ssl)"]=t.connectEnd-t.connectStart+"ms ("+(t.connectEnd-t.secureConnectionStart)+"ms)":n.tcp=t.connectEnd-t.connectStart+"ms"),t.responseStart&&t.requestStart&&(n.request=t.responseStart-t.requestStart+"ms"),t.responseEnd&&t.responseStart&&(n.response=t.responseEnd-t.responseStart+"ms"),t.domComplete&&t.domLoading&&(t.domContentLoadedEventStart&&t.domLoading?n["domComplete (domLoaded)"]=t.domComplete-t.domLoading+"ms ("+(t.domContentLoadedEventStart-t.domLoading)+"ms)":n.domComplete=t.domComplete-t.domLoading+"ms"),t.loadEventEnd&&t.loadEventStart&&(n.loadEvent=t.loadEventEnd-t.loadEventStart+"ms"),t.navigationStart&&t.loadEventEnd&&(n["total (DOM)"]=t.loadEventEnd-t.navigationStart+"ms ("+(t.domComplete-t.navigationStart)+"ms)")}}),0),n},t}());export default t;
15
+ var e=function(t,n){return(e=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])})(t,n)};var t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)},n=new(function(n){function r(){var e=n.call(this)||this;return e.userId=null,e.currentUrl="",e.pageKey="",e.eventDescMap={PageView:"Web 浏览页面",WebClick:"Web 元素点击",PageRetained:"Web 页面浏览时长",CustomTrack:"Web 自定义代码上报"},e.init=function(t){e.preset(t);var n=window.location.pathname;e.currentUrl=window.location.href,e.pageKey=n.replace(/\//g,"_").substr(1),e.systemsInfo=e.getSystemsInfo(),e.setCookie("retainedStartTime",e.getTimeStamp())},e.preset=function(t){t instanceof Object&&e.each(t,(function(t,n){void 0!==e.config[n]&&(e.config[n]=t)})),/^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-\(\)]*[\w@?^=%&/~+#-\(\)])?$/.test(e.config.serverUrl)||(e.printLog("当前 server_url 为空或不正确,只在控制台打印日志,network 中不会发数据,请配置正确的 server_url!"),e.config.showLog=!0),e.config.autoTrack?e.listener():e.unlistener()},e.login=function(t){["number","string"].includes(typeof t)&&(e.userId=t)},e.track=function(t){var n=t.desc,r=t.partkey,o=t.business,i=e.getParams({desc:n,event:"CustomTrack",itemKey:e.getItemKey(r),extroInfo:{business:o}});return e.sendAjax(i)},e.listener=function(){e.config.isTrackSinglePage&&(e.rewriteHistory(),e.addSinglePageEvent(e.onPageViewCallback)),e.each(["load","beforeunload"],(function(t){e.addEventListener(window,t,e.onPageViewCallback)})),e.addEventListener(window,"click",e.onClickCallback)},e.unlistener=function(){if(e.config.isTrackSinglePage){var t=window.history.pushState?"popstate":"hashchange";e.each(["pushState","replaceState",t],(function(t){e.removeEventListener(window,t,e.onPageViewCallback)}))}e.each(["load","beforeunload"],(function(t){e.removeEventListener(window,t,e.onPageViewCallback)})),e.removeEventListener(window,"click",e.onClickCallback)},e.onClickCallback=function(t){var n,r;if(null===(r=null===(n=null==t?void 0:t.target)||void 0===n?void 0:n.dataset)||void 0===r?void 0:r.partKey){var o=[t.pageX,t.pageY],i=t.target.id,a=t.target.className,s={id:i,nodeName:t.target.nodeName,className:a},c=e.getParams({event:"WebClick",desc:e.eventDescMap.WebClick,itemKey:e.getItemKey(t.target.dataset.partKey),extroInfo:{position:o,targetEle:s,pointerType:t.pointerType,currentUrl:e.currentUrl,elementSelector:e.getDomSelector(t.target)}});return e.sendAjax(c)}},e.onPageViewCallback=function(t){var n,r,o=window.location.origin;e.sendPageViewData(t.type,{event:"PageView",desc:e.eventDescMap.PageView,extroInfo:{currentUrl:e.currentUrl,targetUrl:(null===(n=t.arguments)||void 0===n?void 0:n[2])?o+(null===(r=t.arguments)||void 0===r?void 0:r[2]):null}}),e.currentUrl=window.location.href,e.pageKey=window.location.pathname.replace(/\//g,"_").substr(1)},e.getParams=function(n){var r=n.event,o=n.desc,i=n.itemKey,a=n.extroInfo,s=void 0===a?{}:a,c=e.config,u=c.appKey,d=c.sdkVersion,l=c.siteId,p=window.innerWidth,g=window.innerHeight,f=window.screen.width,m=window.screen.height;return{desc:o,event:r,appKey:u,siteId:l,itemKey:i||e.getItemKey(),requestTime:e.getTimeStamp(),deviceId:e.getDistinctId(),privateParamMap:t(t({},s),{sdkVersion:d,pageWidth:p,pageHeight:g,screenWidth:f,screenHeight:m,currentUrl:s.currentUrl||e.currentUrl,systemsInfo:e.systemsInfo,urlParams:e.getQueryValue(),userInfo:{userId:e.userId}})}},e.sendPageViewData=function(t,n){var r=e.getParams(n);return e.sendRetained(t),e.sendAjax(r)},e.sendAjax=function(t){var n=e.config,r=n.serverUrl,o=n.sendTimeout,i=n.contentType;return n.showLog&&e.printLog(t),new Promise((function(n,a){e.ajax({url:r,type:"POST",data:JSON.stringify(t),contentType:i,credentials:!1,timeout:o,cors:!0,success:function(e){return n(e)},error:function(e){return a(e)}})}))},e.sendRetained=function(n){var r=e.config.serverUrl,o=e.getParams({event:"PageRetained",desc:e.eventDescMap.PageRetained});if(["beforeunload","pushState","replaceState","hashchange","popstate"].indexOf(n)>=0){var i=e.getCookie("retainedStartTime"),a=i?+i:e.getTimeStamp(),s=t(t({},o),{retainedStartTime:a});"beforeunload"===n?e.sendBeacon({url:r,data:s}):e.sendAjax(s).finally((function(){return e.setCookie("retainedStartTime",e.getTimeStamp())}))}},e.getItemKey=function(t){return[e.config.appKey,e.pageKey,t?t.toString():void 0].filter((function(e){return!!e})).reduce((function(e,t){return e+(e.length?".":"")+t}),"")},e.config={sdkVersion:"1.1.0",appKey:"",siteId:"",showLog:!1,serverUrl:"",autoTrack:!1,useClientTime:!0,queueTimeout:500,sendTimeout:3e3,isTrackSinglePage:!1,contentType:"application/x-www-form-urlencoded"},e.systemsInfo={},e}return function(t,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=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(r,n),r.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)}))},r}(function(){function e(){var e=this;this.getPlatformType=function(){for(var e=navigator.userAgent,t=new Array("Android","iPhone","SymbianOS","Windows Phone","iPad","iPod"),n=!0,r=0;r<t.length;r++)if(e.indexOf(t[r])>0){n=!1;break}return n?"pc":"h5"},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(t,n,r){if(null==t)return!1;if(e.nativeForEach&&t.forEach===e.nativeForEach)t.forEach(n,r);else if(e.isArray(t)&&t.length===+t.length){for(var o=0,i=t.length;o<i;o++)if(o in t&&n.call(r,t[o],o,t)===e.breaker)return!1}else for(var a in t)if(e.hasOwnProperty.call(t,a)&&n.call(r,t[a],a,t)===e.breaker)return!1},this.getDomIndex=function(e){if(!e.parentNode)return-1;for(var t=0,n=e.tagName,r=e.parentNode.children,o=0;o<r.length;o++)if(r[o].tagName===n){if(e===r[o])return t;t++}return-1},this.selector=function(t){var n=t.parentNode&&9==t.parentNode.nodeType?-1:e.getDomIndex(t);return t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?"#"+t.getAttribute("id"):t.tagName.toLowerCase()+(~n?":nth-of-type("+(n+1)+")":"")},this.getDomSelector=function(t,n){if(!t||!t.parentNode||!t.parentNode.children)return!1;n=n&&n.join?n:[];var r=t.nodeName.toLowerCase();return t&&"body"!==r&&1==t.nodeType?(n.unshift(e.selector(t)),t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?n.join(" > "):e.getDomSelector(t.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 o=n[r];" "==o.charAt(0);)o=o.substring(1,o.length);if(0==o.indexOf(t))return this._decodeURIComponent(o.substring(t.length,o.length))}return null},this.setCookie=function(e,t,n){var r,o="";n=null==n?73e3:n;var i=this.getMainHost();if(r=i?"; domain="+i:"",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),o="; expires="+a.toUTCString()}function s(e){return e||!1}var c="",u="",d="";e&&(c=s(e)),t&&(u=s(t)),r&&(d=s(r)),c&&u&&(document.cookie=c+"="+encodeURIComponent(u)+o+"; path=/"+d)},this.removeCookie=function(t){e.setCookie(t,"",-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 t=e.getCookie("distinctId");return t||(t=e.uuid(),e.setCookie("distinctId",t),t)},this.getQueryValue=function(e){for(var t=decodeURI(window.location.href).match(new RegExp("[?&][^?&]+=[^?&]+","g"))||[],n={},r=0;r<t.length;r++){var o=t[r].replace(/\?|\&/,"").split("=");if(o[0]===e)return o[1];n[o[0]]=o[1]}return e?null:n},this.ajax=function(t){function n(e){if(!e)return"";try{return JSON.parse(e)}catch(e){return{}}}t.timeout=t.timeout||3e4,t.credentials=void 0===t.credentials||t.credentials;var r=e.xhr(t.cors);if(!r)return!1;t.type||(t.type=t.data?"POST":"GET");var o,i=t.success,a=t.error;t.success=function(e){i(e),o&&(clearTimeout(o),o=null)},t.error=function(e){a(e),o&&(clearTimeout(o),o=null)},o=setTimeout((function(){!function(){try{e.isObject(r)&&r.abort&&r.abort()}catch(t){e.printLog(t)}o&&(clearTimeout(o),o=null,t.error&&t.error(),r.onreadystatechange=null,r.onload=null,r.onerror=null)}()}),t.timeout),r.onreadystatechange=function(){try{4==r.readyState&&(r.status>=200&&r.status<300||304==r.status?t.success(n(r.responseText)):t.error(n(r.responseText),r.status),r.onreadystatechange=null,r.onload=null)}catch(e){r.onreadystatechange=null,r.onload=null}},r.open(t.type,t.url,!0);try{t.credentials&&(r.withCredentials=!0),e.isObject(t.header)&&e.each(t.header,(function(e,t){r.setRequestHeader&&r.setRequestHeader(t,e)})),t.data&&(t.cors||r.setRequestHeader&&r.setRequestHeader("X-Requested-With","XMLHttpRequest"),"application/json"===t.contentType?r.setRequestHeader&&r.setRequestHeader("Content-type","application/json; charset=UTF-8"):r.setRequestHeader&&r.setRequestHeader("Content-type","application/x-www-form-urlencoded"))}catch(t){e.printLog(t)}r.send(t.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.sendBeacon=function(e){return"object"==typeof navigator&&"function"==typeof navigator.sendBeacon?(navigator.sendBeacon(e.url,new URLSearchParams(JSON.stringify(e.data||{}))),Promise.resolve({message:"发送成功!"})):Promise.reject({message:"不支持sendBeacon,发送失败!"})}}return e.prototype.printLog=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];if(this.isObject(e[0])&&(e[0]=this.formatJsonString(e[0])),"object"==typeof console&&console.log)try{return console.log.apply(console,e)}catch(t){console.log(e[0])}},e.prototype.getSystemsInfo=function(){var e=navigator.userAgent,t=[],n={language:navigator.language},r=e.match(/MicroMessenger\/([\d\.]+)/i),o=r&&r[1]?r[1]:null,i=e.match(/(ipod).*\s([\d_]+)/i),a=e.match(/(ipad).*\s([\d_]+)/i),s=e.match(/(iphone)\sos\s([\d_]+)/i),c=e.match(/(android)\s([\d\.]+)/i),u=e.match(/(Mac OS X)\s([\d_]+)/i);t=[],c?t.push("Android "+c[2]):s?t.push("iPhone, iOS "+s[2].replace(/_/g,".")):a?t.push("iPad, iOS "+a[2].replace(/_/g,".")):i?t.push("iPod, iOS "+i[2].replace(/_/g,".")):u&&t.push("Mac, MacOS "+u[2].replace(/_/g,".")),o&&t.push("WeChat "+o),n.platform=this.getPlatformType(),n.client=t.length?t.join(", "):"Unknown";var d=e.toLowerCase().match(/ nettype\/([^ ]+)/g);return d&&d[0]&&(t=[(d=d[0].split("/"))[1]],n.network=t.length?t.join(", "):"Unknown"),n.ua=e,setTimeout((function(){var e=window.performance||window.msPerformance||window.webkitPerformance;if(e&&e.timing){var t=e.timing;t.navigationStart&&(n.navigationStart=t.navigationStart),t.navigationStart&&t.domainLookupStart&&(n.navigation=t.domainLookupStart-t.navigationStart+"ms"),t.domainLookupEnd&&t.domainLookupStart&&(n.dns=t.domainLookupEnd-t.domainLookupStart+"ms"),t.connectEnd&&t.connectStart&&(t.connectEnd&&t.secureConnectionStart?n["tcp (ssl)"]=t.connectEnd-t.connectStart+"ms ("+(t.connectEnd-t.secureConnectionStart)+"ms)":n.tcp=t.connectEnd-t.connectStart+"ms"),t.responseStart&&t.requestStart&&(n.request=t.responseStart-t.requestStart+"ms"),t.responseEnd&&t.responseStart&&(n.response=t.responseEnd-t.responseStart+"ms"),t.domComplete&&t.domLoading&&(t.domContentLoadedEventStart&&t.domLoading?n["domComplete (domLoaded)"]=t.domComplete-t.domLoading+"ms ("+(t.domContentLoadedEventStart-t.domLoading)+"ms)":n.domComplete=t.domComplete-t.domLoading+"ms"),t.loadEventEnd&&t.loadEventStart&&(n.loadEvent=t.loadEventEnd-t.loadEventStart+"ms"),t.navigationStart&&t.loadEventEnd&&(n["total (DOM)"]=t.loadEventEnd-t.navigationStart+"ms ("+(t.domComplete-t.navigationStart)+"ms)")}}),0),n},e.prototype.isObject=function(e){return null!=e&&"[object Object]"==toString.call(e)},e.prototype.isUndefined=function(e){return void 0===e},e.prototype.isString=function(e){return"[object String]"==toString.call(e)},e.prototype.isDate=function(e){return"[object Date]"==toString.call(e)},e.prototype.isBoolean=function(e){return"[object Boolean]"==toString.call(e)},e.prototype.isNumber=function(e){return"[object Number]"==toString.call(e)&&/[\d\.]+/.test(String(e))},e.prototype.isElement=function(e){return!(!e||1!==e.nodeType)},e.prototype.isFunction=function(e){if(!e)return!1;var t=toString.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t},e.prototype.isJSONString=function(e){try{JSON.parse(e)}catch(e){return!1}return!0},e.prototype._decodeURIComponent=function(e){var t=e;try{t=decodeURIComponent(e)}catch(n){t=e}return t},e.prototype.getMainHost=function(){var e="mh_"+Math.random(),t=new RegExp("(^|;)\\s*"+e+"=12345"),n=new Date(0),r=document.domain.split("."),o=[];for(o.unshift(r.pop());r.length;){o.unshift(r.pop());var i=o.join("."),a=e+"=12345;domain=."+i;if(document.cookie=a,t.test(document.cookie))return document.cookie=a+";expires="+n,i}},e}()));export default n;
16
16
  //# sourceMappingURL=index.ems.js.map