@adobe/helix-rum-enhancer 2.31.0-beta.2 → 2.31.0-beta.3

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/src/index.js CHANGED
@@ -14,33 +14,34 @@
14
14
 
15
15
  const h = (s, a) => [...s].reduce((p, c) => p + c.charCodeAt(0), a) % 1371;
16
16
  const fflags = {
17
- has: (f) => fflags[f].includes(h(window.origin, 1)) || /localhost/.test(window.origin),
17
+ has: f => fflags[f].includes(h(window.origin, 1)) || /localhost/.test(window.origin),
18
18
  enabled: (f, c) => fflags.has(f) && c(),
19
19
  disabled: (f, c) => !fflags.has(f) && c(),
20
20
  eagercwv: [683],
21
21
  redirect: [620, 1139],
22
22
  example: [543, 770, 1136],
23
23
  language: [543, 959, 1139, 620],
24
- allresources: [1139],
24
+ allresources: [1139]
25
25
  };
26
26
 
27
27
  const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB'];
28
28
  const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email', 'consent'];
29
29
  fflags.enabled('example', () => DEFAULT_TRACKING_EVENTS.push('example'));
30
30
 
31
- const { href } = window.location;
31
+ const {
32
+ href
33
+ } = window.location;
32
34
  const urlSanitizers = {
33
35
  full: (url = href) => new URL(url).toString(),
34
36
  origin: (url = href) => new URL(url).origin,
35
37
  path: (url = href) => {
36
38
  const u = new URL(url);
37
39
  return `${u.origin}${u.pathname}`;
38
- },
40
+ }
39
41
  };
40
42
 
41
- const getTargetValue = (el) => el.getAttribute('data-rum-target') || el.getAttribute('href')
42
- || el.currentSrc || el.getAttribute('src') || el.dataset.action || el.action;
43
- const targetSelector = (el) => {
43
+ const getTargetValue = el => el.getAttribute('data-rum-target') || el.getAttribute('href') || el.currentSrc || el.getAttribute('src') || el.dataset.action || el.action;
44
+ const targetSelector = el => {
44
45
  try {
45
46
  if (!el) return undefined;
46
47
  let v = getTargetValue(el);
@@ -67,14 +68,14 @@
67
68
  if (el.getAttribute('role') === 'alertdialog') return true;
68
69
  if (el.getAttribute('aria-modal') === 'true') return true;
69
70
  const cs = window.getComputedStyle(el);
70
- return (cs && cs.position === 'fixed' && cs.zIndex > 100);
71
+ return cs && cs.position === 'fixed' && cs.zIndex > 100;
71
72
  }
72
73
  function isButton(el) {
73
74
  if (el.tagName === 'BUTTON') return true;
74
75
  if (el.tagName === 'INPUT' && el.getAttribute('type') === 'button') return true;
75
76
  if (el.tagName === 'A') {
76
77
  const classes = Array.from(el.classList);
77
- return classes.some((className) => className.match(/button|cta/));
78
+ return classes.some(className => className.match(/button|cta/));
78
79
  }
79
80
  return el.getAttribute('role') === 'button';
80
81
  }
@@ -90,15 +91,12 @@
90
91
  if (el.closest('header')) return 'header';
91
92
  if (el.closest('footer')) return 'footer';
92
93
  if (el.closest('aside')) return 'aside';
93
- return (walk(el, (e) => e.id && `#${e.id}`));
94
+ return walk(el, e => e.id && `#${e.id}`);
94
95
  }
95
96
  function getSourceElement(el) {
96
97
  const f = el.closest('form');
97
98
  if (f && Array.from(f.elements).includes(el)) {
98
- return (el.tagName.toLowerCase()
99
- + (['INPUT', 'BUTTON'].includes(el.tagName)
100
- ? `[type='${el.getAttribute('type') || ''}']`
101
- : ''));
99
+ return el.tagName.toLowerCase() + (['INPUT', 'BUTTON'].includes(el.tagName) ? `[type='${el.getAttribute('type') || ''}']` : '');
102
100
  }
103
101
  if (walk(el, isButton)) return 'button';
104
102
  return el.tagName.toLowerCase().match(/^(a|img|video)$/) && el.tagName.toLowerCase();
@@ -106,9 +104,9 @@
106
104
  function getSourceIdentifier(el) {
107
105
  if (el.id) return `#${el.id}`;
108
106
  if (el.getAttribute('data-block-name')) return `.${el.getAttribute('data-block-name')}`;
109
- return (el.classList.length > 0 && `.${el.classList[0]}`);
107
+ return el.classList.length > 0 && `.${el.classList[0]}`;
110
108
  }
111
- const sourceSelector = (el) => {
109
+ const sourceSelector = el => {
112
110
  try {
113
111
  if (!el || el === document.body || el === document.documentElement) {
114
112
  return undefined;
@@ -125,92 +123,92 @@
125
123
  }
126
124
  };
127
125
 
128
- function addCookieConsentTracking(sampleRUM) {
129
- const cmpCookie = document.cookie.split(';')
130
- .map((c) => c.trim())
131
- .find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
132
- if (cmpCookie) {
133
- sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
134
- return;
126
+ const {
127
+ sampleRUM,
128
+ queue,
129
+ isSelected
130
+ } = window.hlx && window.hlx.rum ? window.hlx.rum : {};
131
+ const createMO = cb => window.MutationObserver ? new MutationObserver(cb) : {};
132
+ const [blocksMO, mediaMO] = [blocksMCB, mediaMCB].map(createMO);
133
+ const hasCookieKey = key => () => document.cookie.split(';').some(c => c.trim().startsWith(`${key}=`));
134
+ const pluginBasePath = new URL(document.currentScript.src).href.replace(/index\.(map\.)js/, 'plugins');
135
+ const PLUGINS = {
136
+ cwv: `${pluginBasePath}/cwv.js`,
137
+ form: {
138
+ url: `${pluginBasePath}/form.js`,
139
+ condition: () => document.querySelector('form'),
140
+ isBlockDependent: true
141
+ },
142
+ video: {
143
+ url: `${pluginBasePath}/video.js`,
144
+ condition: () => document.querySelector('video'),
145
+ isBlockDependent: true
146
+ },
147
+ martech: {
148
+ url: `${pluginBasePath}/martech.js`,
149
+ condition: ({
150
+ urlParameters
151
+ }) => urlParameters.size > 0
152
+ },
153
+ onetrust: {
154
+ url: `${pluginBasePath}/onetrust.js`,
155
+ condition: () => document.querySelector('#onetrust-consent-sdk') || hasCookieKey('OptanonAlertBoxClosed'),
156
+ isBlockDependent: true
135
157
  }
136
- let consentMO;
137
- const trackShowConsent = () => {
138
- const otsdk = document.querySelector('body > div#onetrust-consent-sdk');
139
- if (otsdk) {
140
- if (otsdk.checkVisibility && !otsdk.checkVisibility()) {
141
- sampleRUM('consent', { source: 'onetrust', target: 'suppressed' });
142
- } else {
143
- sampleRUM('consent', { source: 'onetrust', target: 'show' });
144
- }
145
- if (consentMO) {
146
- consentMO.disconnect();
147
- }
148
- return true;
149
- }
150
- return false;
151
- };
152
- if (!trackShowConsent()) {
153
- consentMO = window.MutationObserver
154
- ? new MutationObserver(trackShowConsent)
155
- : null;
156
- if (consentMO) {
157
- consentMO.observe(
158
- document.body,
159
- { attributes: false, childList: true, subtree: false },
160
- );
158
+ };
159
+ const PLUGIN_PARAMETERS = {
160
+ context: document.body,
161
+ fflags,
162
+ sampleRUM,
163
+ sourceSelector,
164
+ targetSelector
165
+ };
166
+ const pluginCache = new Map();
167
+ function loadPlugin(key, params) {
168
+ const plugin = PLUGINS[key];
169
+ const usp = new URLSearchParams(window.location.search);
170
+ if (!pluginCache.has(key) && plugin.condition && !plugin.condition({
171
+ urlParameters: usp
172
+ })) {
173
+ return null;
174
+ }
175
+ if (!pluginCache.has(key)) {
176
+ try {
177
+ pluginCache.set(key, import(`${plugin.url || plugin}`));
178
+ } catch (e) {
179
+ return null;
161
180
  }
162
181
  }
182
+ const pluginLoadPromise = pluginCache.get(key);
183
+ return pluginLoadPromise.then(p => p.default && p.default(params) || typeof p === 'function' && p(params));
163
184
  }
164
- function addUTMParametersTracking(sampleRUM) {
165
- const usp = new URLSearchParams(window.location.search);
166
- [...usp.entries()]
167
- .filter(([key]) => key.startsWith('utm_'))
168
- .filter(([key]) => key !== 'utm_id')
169
- .filter(([key]) => key !== 'utm_term')
170
- .forEach(([source, target]) => sampleRUM('utm', { source, target }));
171
- }
172
- function addAdsParametersTracking(sampleRUM) {
173
- const networks = {
174
- google: /gclid|gclsrc|wbraid|gbraid/,
175
- doubleclick: /dclid/,
176
- microsoft: /msclkid/,
177
- facebook: /fb(cl|ad_|pxl_)id/,
178
- twitter: /tw(clid|src|term)/,
179
- linkedin: /li_fat_id/,
180
- pinterest: /epik/,
181
- tiktok: /ttclid/,
182
- };
183
- const params = Array.from(new URLSearchParams(window.location.search).keys());
184
- Object.entries(networks).forEach(([network, regex]) => {
185
- params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
186
- });
187
- }
188
- function addEmailParameterTracking(sampleRUM) {
189
- const networks = {
190
- mailchimp: /mc_(c|e)id/,
191
- marketo: /mkt_tok/,
192
- };
193
- const params = Array.from(new URLSearchParams(window.location.search).keys());
194
- Object.entries(networks).forEach(([network, regex]) => {
195
- params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
196
- });
185
+ function loadPlugins(filter = () => true, params = PLUGIN_PARAMETERS) {
186
+ Object.entries(PLUGINS).filter(([, plugin]) => filter(plugin)).map(([key]) => loadPlugin(key, params));
197
187
  }
198
-
199
- const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum
200
- : {};
201
- const blocksMO = window.MutationObserver ? new MutationObserver(blocksMCB)
202
- : {};
203
- const mediaMO = window.MutationObserver ? new MutationObserver(mediaMCB)
204
- : {};
205
188
  function trackCheckpoint(checkpoint, data, t) {
206
- const { weight, id } = window.hlx.rum;
189
+ const {
190
+ weight,
191
+ id
192
+ } = window.hlx.rum;
207
193
  if (isSelected) {
208
194
  const sendPing = (pdata = data) => {
209
- const body = JSON.stringify({ weight, id, referer: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'](), checkpoint, t, ...data }, KNOWN_PROPERTIES);
195
+ const body = JSON.stringify({
196
+ weight,
197
+ id,
198
+ referer: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'](),
199
+ checkpoint,
200
+ t,
201
+ ...data
202
+ }, KNOWN_PROPERTIES);
210
203
  const urlParams = window.RUM_PARAMS ? `?${new URLSearchParams(window.RUM_PARAMS).toString()}` : '';
211
- const { href: url, origin } = new URL(`.rum/${weight}${urlParams}`, sampleRUM.collectBaseURL);
204
+ const {
205
+ href: url,
206
+ origin
207
+ } = new URL(`.rum/${weight}${urlParams}`, sampleRUM.collectBaseURL);
212
208
  if (window.location.origin === origin) {
213
- const headers = { type: 'application/json' };
209
+ const headers = {
210
+ type: 'application/json'
211
+ };
214
212
  navigator.sendBeacon(url, new Blob([body], headers));
215
213
  } else {
216
214
  navigator.sendBeacon(url, body);
@@ -226,52 +224,18 @@
226
224
  trackCheckpoint(...ck);
227
225
  }
228
226
  }
229
- function addCWVTracking() {
230
- setTimeout(() => {
231
- try {
232
- const cwvScript = new URL('.rum/web-vitals/dist/web-vitals.iife.js', sampleRUM.baseURL).href;
233
- if (document.querySelector(`script[src="${cwvScript}"]`)) {
234
- return;
235
- }
236
- const script = document.createElement('script');
237
- script.src = cwvScript;
238
- script.onload = () => {
239
- const storeCWV = (measurement) => {
240
- const data = { cwv: {} };
241
- data.cwv[measurement.name] = measurement.value;
242
- if (measurement.name === 'LCP' && measurement.entries.length > 0) {
243
- const { element } = measurement.entries.pop();
244
- data.target = targetSelector(element);
245
- data.source = sourceSelector(element) || (element && element.outerHTML.slice(0, 30));
246
- }
247
- sampleRUM('cwv', data);
248
- };
249
- const isEager = (metric) => ['CLS', 'LCP'].includes(metric);
250
- ['INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
251
- const metricFn = window.webVitals[`on${metric}`];
252
- if (typeof metricFn === 'function') {
253
- let opts = {};
254
- fflags.enabled('eagercwv', () => {
255
- opts = { reportAllChanges: isEager(metric) };
256
- });
257
- metricFn(storeCWV, opts);
258
- }
259
- });
260
- };
261
- document.head.appendChild(script);
262
- } catch (error) {
263
- }
264
- }, 2000);
265
- }
266
227
  function addNavigationTracking() {
267
228
  const navigate = (source, type, redirectCount) => {
268
- const payload = { source, target: document.visibilityState };
229
+ const payload = {
230
+ source,
231
+ target: document.visibilityState
232
+ };
269
233
  if (document.prerendering) {
270
234
  document.addEventListener('prerenderingchange', () => {
271
235
  payload.target = 'prerendered';
272
236
  sampleRUM('navigate', payload);
273
237
  }, {
274
- once: true,
238
+ once: true
275
239
  });
276
240
  if (type === 'navigate') {
277
241
  sampleRUM('prerender', payload);
@@ -288,79 +252,81 @@
288
252
  fflags.enabled('redirect', () => {
289
253
  const from = new URLSearchParams(window.location.search).get('redirect_from');
290
254
  if (redirectCount || from) {
291
- sampleRUM('redirect', { source: from, target: redirectCount || 1 });
255
+ sampleRUM('redirect', {
256
+ source: from,
257
+ target: redirectCount || 1
258
+ });
292
259
  }
293
260
  });
294
261
  };
295
262
  const processed = new Set();
296
- new PerformanceObserver((list) => list
297
- .getEntries()
298
- .filter(({ type }) => !processed.has(type))
299
- .map((e) => [e, processed.add(e.type)])
300
- .map(([e]) => navigate(
301
- window.hlx.referrer || document.referrer,
302
- e.type,
303
- e.redirectCount,
304
- ))).observe({ type: 'navigation', buffered: true });
263
+ new PerformanceObserver(list => list.getEntries().filter(({
264
+ type
265
+ }) => !processed.has(type)).map(e => [e, processed.add(e.type)]).map(([e]) => navigate(window.hlx.referrer || document.referrer, e.type, e.redirectCount))).observe({
266
+ type: 'navigation',
267
+ buffered: true
268
+ });
305
269
  }
306
270
  function addLoadResourceTracking() {
307
- const observer = new PerformanceObserver((list) => {
271
+ const observer = new PerformanceObserver(list => {
308
272
  try {
309
- list.getEntries()
310
- .filter((e) => !e.responseStatus || e.responseStatus < 400)
311
- .filter((e) => window.location.hostname === new URL(e.name).hostname || fflags.has('allresources'))
312
- .filter((e) => new URL(e.name).pathname.match('.*(\\.plain\\.html$|\\.json|graphql|api)'))
313
- .forEach((e) => {
314
- sampleRUM('loadresource', { source: e.name, target: Math.round(e.duration) });
273
+ list.getEntries().filter(e => !e.responseStatus || e.responseStatus < 400).filter(e => window.location.hostname === new URL(e.name).hostname || fflags.has('allresources')).filter(e => new URL(e.name).pathname.match('.*(\\.plain\\.html$|\\.json|graphql|api)')).forEach(e => {
274
+ sampleRUM('loadresource', {
275
+ source: e.name,
276
+ target: Math.round(e.duration)
315
277
  });
316
- list.getEntries()
317
- .filter((e) => e.responseStatus >= 400)
318
- .forEach((e) => {
319
- sampleRUM('missingresource', { source: e.name, target: e.responseStatus });
278
+ });
279
+ list.getEntries().filter(e => e.responseStatus >= 400).forEach(e => {
280
+ sampleRUM('missingresource', {
281
+ source: e.name,
282
+ target: e.responseStatus
320
283
  });
321
- } catch (error) {
322
- }
284
+ });
285
+ } catch (error) {}
286
+ });
287
+ observer.observe({
288
+ type: 'resource',
289
+ buffered: true
323
290
  });
324
- observer.observe({ type: 'resource', buffered: true });
325
291
  }
326
292
  function activateBlocksMO() {
327
293
  if (!blocksMO || blocksMO.active) {
328
294
  return;
329
295
  }
330
296
  blocksMO.active = true;
331
- blocksMO.observe(
332
- document.body,
333
- { subtree: true, attributes: true, attributeFilter: ['data-block-status'] },
334
- );
297
+ blocksMO.observe(document.body, {
298
+ subtree: true,
299
+ attributes: true,
300
+ attributeFilter: ['data-block-status']
301
+ });
335
302
  }
336
303
  function activateMediaMO() {
337
304
  if (!mediaMO || mediaMO.active) {
338
305
  return;
339
306
  }
340
307
  mediaMO.active = true;
341
- mediaMO.observe(
342
- document.body,
343
- { subtree: true, attributes: false, childList: true },
344
- );
308
+ mediaMO.observe(document.body, {
309
+ subtree: true,
310
+ attributes: false,
311
+ childList: true
312
+ });
345
313
  }
346
314
  function getIntersectionObsever(checkpoint) {
347
315
  if (!window.IntersectionObserver) {
348
316
  return null;
349
317
  }
350
- activateBlocksMO();
351
- activateMediaMO();
352
- const observer = new IntersectionObserver((entries) => {
318
+ const observer = new IntersectionObserver(entries => {
353
319
  try {
354
- entries
355
- .filter((e) => e.isIntersecting)
356
- .forEach((e) => {
357
- observer.unobserve(e.target);
358
- const target = targetSelector(e.target);
359
- const source = sourceSelector(e.target);
360
- sampleRUM(checkpoint, { target, source });
320
+ entries.filter(e => e.isIntersecting).forEach(e => {
321
+ observer.unobserve(e.target);
322
+ const target = targetSelector(e.target);
323
+ const source = sourceSelector(e.target);
324
+ sampleRUM(checkpoint, {
325
+ target,
326
+ source
361
327
  });
362
- } catch (error) {
363
- }
328
+ });
329
+ } catch (error) {}
364
330
  });
365
331
  return observer;
366
332
  }
@@ -368,14 +334,14 @@
368
334
  const blockobserver = getIntersectionObsever('viewblock');
369
335
  if (blockobserver) {
370
336
  const blocks = element.getAttribute('data-block-status') ? [element] : element.querySelectorAll('div[data-block-status="loaded"]');
371
- blocks.forEach((b) => blockobserver.observe(b));
337
+ blocks.forEach(b => blockobserver.observe(b));
372
338
  }
373
339
  }
374
340
  const observedMedia = new Set();
375
341
  function addViewMediaTracking(parent) {
376
342
  const mediaobserver = getIntersectionObsever('viewmedia');
377
343
  if (mediaobserver) {
378
- parent.querySelectorAll('img, video, audio, iframe').forEach((m) => {
344
+ parent.querySelectorAll('img, video, audio, iframe').forEach(m => {
379
345
  if (!observedMedia.has(m)) {
380
346
  observedMedia.add(m);
381
347
  mediaobserver.observe(m);
@@ -383,71 +349,52 @@
383
349
  });
384
350
  }
385
351
  }
386
- function addFormTracking(parent) {
387
- activateBlocksMO();
388
- activateMediaMO();
389
- parent.querySelectorAll('form').forEach((form) => {
390
- form.addEventListener('submit', (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }), { once: true });
391
- let lastSource;
392
- form.addEventListener('change', (e) => {
393
- const source = sourceSelector(e.target);
394
- if (source !== lastSource) {
395
- sampleRUM('fill', { source });
396
- lastSource = source;
397
- }
398
- });
399
- form.addEventListener('focusin', (e) => {
400
- if (['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'].includes(e.target.tagName)
401
- || e.target.getAttribute('contenteditable') === 'true') {
402
- sampleRUM('click', { source: sourceSelector(e.target) });
403
- }
404
- });
405
- });
406
- }
407
352
  function addObserver(ck, fn, block) {
408
353
  return DEFAULT_TRACKING_EVENTS.includes(ck) && fn(block);
409
354
  }
410
355
  function blocksMCB(mutations) {
411
- mutations
412
- .filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status')
413
- .filter((m) => m.target.dataset.blockStatus === 'loaded')
414
- .forEach((m) => {
415
- addObserver('form', addFormTracking, m.target);
416
- addObserver('viewblock', addViewBlockTracking, m.target);
417
- });
356
+ mutations.filter(m => m.type === 'attributes' && m.attributeName === 'data-block-status').filter(m => m.target.dataset.blockStatus === 'loaded').forEach(m => {
357
+ addObserver('form', el => loadPlugins(p => p.isBlockDependent, {
358
+ ...PLUGIN_PARAMETERS,
359
+ context: el
360
+ }), m.target);
361
+ addObserver('viewblock', addViewBlockTracking, m.target);
362
+ });
418
363
  }
419
364
  function mediaMCB(mutations) {
420
- mutations
421
- .forEach((m) => {
422
- addObserver('viewmedia', addViewMediaTracking, m.target);
423
- });
365
+ mutations.forEach(m => {
366
+ addObserver('viewmedia', addViewMediaTracking, m.target);
367
+ });
424
368
  }
425
369
  function addTrackingFromConfig() {
370
+ activateBlocksMO();
371
+ activateMediaMO();
426
372
  let lastSource;
427
373
  let lastTarget;
428
- document.addEventListener('click', (event) => {
374
+ document.addEventListener('click', event => {
429
375
  const source = sourceSelector(event.target);
430
376
  const target = targetSelector(event.target);
431
377
  if (source !== lastSource || target !== lastTarget) {
432
- sampleRUM('click', { target, source });
378
+ sampleRUM('click', {
379
+ target,
380
+ source
381
+ });
433
382
  lastSource = source;
434
383
  lastTarget = target;
435
384
  }
436
385
  });
437
- addCWVTracking();
438
- addFormTracking(window.document.body);
439
386
  addNavigationTracking();
440
387
  addLoadResourceTracking();
441
- addUTMParametersTracking(sampleRUM);
442
- addViewBlockTracking(window.document.body);
443
- addViewMediaTracking(window.document.body);
444
- addCookieConsentTracking(sampleRUM);
445
- addAdsParametersTracking(sampleRUM);
446
- addEmailParameterTracking(sampleRUM);
388
+ addViewBlockTracking(document.body);
389
+ addViewMediaTracking(document.body);
390
+ loadPlugins();
447
391
  fflags.enabled('language', () => {
448
392
  const target = navigator.language;
449
393
  const source = document.documentElement.lang;
450
- sampleRUM('language', { source, target });
394
+ sampleRUM('language', {
395
+ source,
396
+ target
397
+ });
451
398
  });
452
399
  }
453
400
  function initEnhancer() {
@@ -457,8 +404,7 @@
457
404
  window.hlx.rum.collector = trackCheckpoint;
458
405
  processQueue();
459
406
  }
460
- } catch (error) {
461
- }
407
+ } catch (error) {}
462
408
  }
463
409
  initEnhancer();
464
410
 
package/src/index.md5 CHANGED
@@ -1 +1 @@
1
- 5424a86261f2304969b6951549ac3941
1
+ 14a535c39191de54a3eed8ed6a7f8369