PageSourceSearch

https://www.olomedia.com/wp-content/plugins/google-analytics-dashboard-for-wp/assets/js/frontend-gtag.js

js olomedia.com collected 2026-09-24 10:58:04 UTC 31,054 bytes, 832 lines download raw bytes

1/**
2 * Developer's Notice:
3 *
4 * Note: JS in this file (and this file itself) is not guaranteed backwards compatibility. JS can be added, changed or removed at any time without notice.
5 * For more information see the `Backwards Compatibility Guidelines for Developers` section of the README.md file.
6 */
7/**
8 * Handles:
9 * - JS Events handling
10 *
11 * @since 7.15.0
12 */
13var ExactMetrics = function () {
14  /* ExactMetrics JS  events tracking works on all major browsers, including IE starting at IE 7, via polyfills for any major JS function used that
15     is not supported by at least  95% of the global and/or US browser marketshare. Currently, IE 7 & 8 which as of 2/14/17 have under 0.25% global marketshare, require
16     us to polyfill Array.prototype.lastIndexOf, and if they continue to drop, we might remove this polyfill at some point. In that case note that events tracking
17     for IE 7/8 will continue to work, with the exception of events tracking of downloads. */
18  var lastClicked = [];
19  var internalAsOutboundCategory = '';
20  var beforeUnloadChanged = false;
21
22  this.setLastClicked = function (valuesArray, fieldsArray, tracked) {
23    valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
24    fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : [];
25    tracked = typeof tracked !== 'undefined' ? tracked : false;
26
27    lastClicked.valuesArray = valuesArray;
28    lastClicked.fieldsArray = fieldsArray;
29  };
30
31  this.getLastClicked = function () {
32    return lastClicked;
33  };
34
35  this.setInternalAsOutboundCategory = function (category) {
36    internalAsOutboundCategory = category;
37  };
38
39  this.getInternalAsOutboundCategory = function () {
40    return internalAsOutboundCategory;
41  };
42
43  this.sendEvent = function (type, action, fieldsArray) {
44    __gtagTrackerSend(type, action, fieldsArray, []);
45  };
46
47  function __gtagTrackerIsDebug() {
48    if (window.exactmetrics_debug_mode) {
49      return true;
50    } else {
51      return false;
52    }
53  }
54
55  function cloneFields(fields, allowedKeys, disallowedKeys) {
56    var clone = {};
57
58    for (var key in fields) {
59      if (!fields.hasOwnProperty(key)) {
60        continue
61      }
62
63      if (allowedKeys && allowedKeys.indexOf(key) === -1) {
64        continue
65      }
66
67      if (disallowedKeys && disallowedKeys.indexOf(key) > -1) {
68        continue
69      }
70
71      clone[key] = fields[key];
72    }
73
74    return clone;
75  }
76
77  function __gtagMaybeTrackerV4(type, action, fieldsArray) {
78    if (!exactmetrics_frontend.v4_id || type !== 'event') {
79      return;
80    }
81
82    var eventCategory = fieldsArray.event_category || '';
83
84    var fieldsToRemove = [
85      'event_name',
86      'event_category',
87      'event_label',
88      'value',
89    ];
90
91    var fields = cloneFields(fieldsArray, null, fieldsToRemove);
92    fields.action = action;
93    fields.send_to = exactmetrics_frontend.v4_id;
94
95    let hitType = eventCategory.replace('-', '_');
96    if (eventCategory.indexOf('outbound-link') !== -1) {
97      hitType = 'click'
98    } else if (eventCategory === 'download') {
99      hitType = 'file_download'
100    }
101
102    __gtagTracker(type, hitType, fields);
103  }
104
105  function __gtagMaybeTrackerUA(type, action, fieldsArray) {
106    if (!exactmetrics_frontend.ua) {
107      return;
108    }
109
110    var allowedFields = [
111      'event_category',
112      'event_label',
113      'value',
114    ];
115
116    var uaFields = cloneFields(fieldsArray, allowedFields);
117    uaFields.send_to = exactmetrics_frontend.ua;
118
119    __gtagTracker(type, action, uaFields);
120  }
121
122  function __gtagTrackerSendDual(type, action, fieldsArray, valuesArray) {
123    type = typeof type !== 'undefined' ? type : 'event';
124    action = typeof action !== 'undefined' ? action : '';
125    valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
126    fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : {};
127
128    __gtagMaybeTrackerUA(type, action, fieldsArray);
129    __gtagMaybeTrackerV4(type, action, fieldsArray);
130
131    lastClicked.valuesArray = valuesArray;
132    lastClicked.fieldsArray = fieldsArray;
133    lastClicked.fieldsArray.event_action = action;
134    lastClicked.tracked = true;
135    __gtagTrackerLog('Tracked: ' + valuesArray.type);
136    __gtagTrackerLog(lastClicked);
137  }
138
139  /**
140   * This attempts to be compatible with the gtag function.
141   *
142   * @see https://developers.google.com/analytics/devguides/collection/gtagjs
143   * @param type string Type of request, event, timing, config.
144   * @param action string Event action or UA for config.
145   * @param fieldsArray object The configuration object.
146   * @param valuesArray object The values for the log.
147   * @private
148   */
149  function __gtagTrackerSend(type, action, fieldsArray, valuesArray) {
150    type = typeof type !== 'undefined' ? type : 'event';
151    action = typeof action !== 'undefined' ? action : '';
152    valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
153    fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : {};
154
155    __gtagTracker(type, action, fieldsArray);
156
157    lastClicked.valuesArray = valuesArray;
158    lastClicked.fieldsArray = fieldsArray;
159    lastClicked.fieldsArray.event_action = action;
160    lastClicked.tracked = true;
161    __gtagTrackerLog('Tracked: ' + valuesArray.type);
162    __gtagTrackerLog(lastClicked);
163  }
164
165  function __gtagTrackerNotSend(valuesArray) {
166    valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
167
168    lastClicked.valuesArray = valuesArray;
169    lastClicked.fieldsArray = [];
170    lastClicked.tracked = false;
171    __gtagTrackerLog('Not Tracked: ' + valuesArray.exit);
172    __gtagTrackerLog(lastClicked);
173  }
174
175  function __gtagTrackerLog(message) {
176    if (__gtagTrackerIsDebug()) {
177      console.dir(message);
178    }
179  }
180
181  function __gtagTrackerStringTrim(x) {
182    return x.replace(/^\s+|\s+$/gm, '');
183  }
184
185  function __gtagTrackerGetDomain() {
186    var i = 0, currentdomain = document.domain, p = currentdomain.split('.'), s = '_gd' + (
187      new Date()
188    ).getTime();
189    while (i < (p.length - 1) && document.cookie.indexOf(s + '=' + s) == -1) {
190      currentdomain = p.slice(-1 - (
191        ++i
192      )).join('.');
193      document.cookie = s + "=" + s + ";domain=" + currentdomain + ";";
194    }
195    document.cookie = s + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain=" + currentdomain + ";";
196    return currentdomain;
197  }
198
199  function __gtagTrackerGetExtension(extension) {
200    extension = extension.toString();
201    extension = extension.substring(0, (
202      extension.indexOf("#") == -1
203    ) ? extension.length : extension.indexOf("#")); /* Remove the anchor at the end, if there is one */
204    extension = extension.substring(0, (
205      extension.indexOf("?") == -1
206    ) ? extension.length : extension.indexOf("?")); /* Remove the query after the file name, if there is one */
207    extension = extension.substring(extension.lastIndexOf("/") + 1, extension.length); /* Remove everything before the last slash in the path */
208    if (extension.length > 0 && extension.indexOf('.') !== -1) { /* If there's a period left in the URL, then there's a extension. Else it is not a extension. */
209      extension = extension.substring(extension.lastIndexOf(".") + 1); /* Remove everything but what's after the first period */
210      return extension;
211    } else {
212      return "";
213    }
214  }
215
216  function __gtagTrackerTrackedClick(event) {
217    return event.which == 1 || event.which == 2 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
218  }
219
220  function __gtagTrackerGetDownloadExtensions() {
221    var download_extensions = [];
222    if (typeof exactmetrics_frontend.download_extensions == 'string') {
223      download_extensions = exactmetrics_frontend.download_extensions.split(",");
224    }
225    return download_extensions;
226  }
227
228  function __gtagTrackerGetInboundPaths() {
229    var inbound_paths = [];
230    if (typeof exactmetrics_frontend.inbound_paths == 'string') {
231      inbound_paths = JSON.parse(exactmetrics_frontend.inbound_paths);
232    }
233
234    return inbound_paths;
235  }
236
237  function __gtagTrackerTrackedClickType(event) {
238    if (event.which == 1) {
239      return 'event.which=1';
240    } else if (event.which == 2) {
241      return 'event.which=2';
242    } else if (event.metaKey) {
243      return 'metaKey';
244    } else if (event.ctrlKey) {
245      return 'ctrlKey';
246    } else if (event.shiftKey) {
247      return 'shiftKey';
248    } else if (event.altKey) {
249      return 'altKey';
250    } else {
251      return '';
252    }
253  }
254
255  function __gtagTrackerLinkType(el) {
256    var download_extensions = __gtagTrackerGetDownloadExtensions();
257    var inbound_paths = __gtagTrackerGetInboundPaths();
258    var type = 'unknown';
259    var link = el.href;
260    var extension = __gtagTrackerGetExtension(el.href);
261    var currentdomain = __gtagTrackerGetDomain();
262    var hostname = el.hostname;
263    var protocol = el.protocol;
264    var pathname = el.pathname;
265    link = link.toString();
266    var index, len;
267    var category = el.getAttribute("data-vars-ga-category");
268
269    if (category) {
270      return category;
271    }
272
273    if (link.match(/^javascript\:/i)) {
274      type = 'internal'; /* if it's a JS link, it's internal */
275    } else if (protocol && protocol.length > 0 && (
276      __gtagTrackerStringTrim(protocol) == 'tel' || __gtagTrackerStringTrim(protocol) == 'tel:'
277    )) { /* If it's a telephone link */
278      type = "tel";
279    } else if (protocol && protocol.length > 0 && (
280      __gtagTrackerStringTrim(protocol) == 'mailto' || __gtagTrackerStringTrim(protocol) == 'mailto:'
281    )) { /* If it's a email */
282      type = "mailto";
283    } else if (hostname && currentdomain && hostname.length > 0 && currentdomain.length > 0 && !hostname.endsWith('.' + currentdomain) && hostname !== currentdomain) { /* If it's a outbound */
284      type = "external";
285    } else if (pathname && JSON.stringify(inbound_paths) != "{}" && pathname.length > 0) { /* If it's an internal as outbound */
286      var inbound_paths_length = inbound_paths.length;
287      for (var inbound_paths_index = 0; inbound_paths_index < inbound_paths_length; inbound_paths_index++) {
288        if (inbound_paths[inbound_paths_index].path && inbound_paths[inbound_paths_index].label && inbound_paths[inbound_paths_index].path.length > 0 && inbound_paths[inbound_paths_index].label.length > 0 && pathname.startsWith(inbound_paths[inbound_paths_index].path)) {
289          type = "internal-as-outbound";
290          internalAsOutboundCategory = "outbound-link-" + inbound_paths[inbound_paths_index].label;
291          break;
292        }
293      }
294      /* Enable window.exactmetrics_experimental_mode at your own risk. We might eventually remove it. Also you may/can/will burn through GA quota for your property quickly. */
295    } else if (hostname && window.exactmetrics_experimental_mode && hostname.length > 0 && document.domain.length > 0 && hostname !== document.domain) { /* If it's a cross-hostname link */
296      type = "cross-hostname";
297    }
298
299    if (extension && (
300      type === 'unknown' || 'external' === type
301    ) && download_extensions.length > 0 && extension.length > 0) { /* If it's a download */
302      for (index = 0, len = download_extensions.length; index < len; ++index) {
303        if (download_extensions[index].length > 0 && (
304          link.endsWith(download_extensions[index]) || download_extensions[index] == extension
305        )) {
306          type = "download";
307          break;
308        }
309      }
310    }
311
312    if (type === 'unknown') {
313      type = 'internal';
314    }
315    return type;
316  }
317
318  function __gtagTrackerLinkTarget(el, event) {
319
320    /* Is actual target set and not _(self|parent|top)? */
321    var target = (
322      el.target && !el.target.match(/^_(self|parent|top)$/i)
323    ) ? el.target : false;
324
325    /* Assume a target if Ctrl|shift|meta-click */
326    if (event.ctrlKey || event.shiftKey || event.metaKey || event.which == 2) {
327      target = "_blank";
328    }
329    return target;
330  }
331
332  function __gtagTrackerGetTitle(el) {
333    if (el.getAttribute("data-vars-ga-label") && el.getAttribute("data-vars-ga-label").replace(/\n/ig, '')) {
334      return el.getAttribute("data-vars-ga-label").replace(/\n/ig, '');
335    } else if (el.title && el.title.replace(/\n/ig, '')) {
336      return el.title.replace(/\n/ig, '');
337    } else if (el.innerText && el.innerText.replace(/\n/ig, '')) {
338      return el.innerText.replace(/\n/ig, '');
339    } else if (el.getAttribute('aria-label') && el.getAttribute('aria-label').replace(/\n/ig, '')) {
340      return el.getAttribute('aria-label').replace(/\n/ig, '');
341    } else if (el.alt && el.alt.replace(/\n/ig, '')) {
342      return el.alt.replace(/\n/ig, '');
343    } else if (el.textContent && el.textContent.replace(/\n/ig, '')) {
344      return el.textContent.replace(/\n/ig, '');
345    } else {
346      return undefined;
347    }
348  }
349
350  function __gtagTrackerGetInnerTitle(el) {
351    var children = el.children;
352    var count = 0;
353    var child;
354    var value;
355    for (var i = 0; i < children.length; i++) {
356      child = children[i];
357      value = __gtagTrackerGetTitle(child);
358      if (value) {
359        return value;
360      }
361      /* max search 100 elements to ensure performance */
362      if (count == 99) {
363        return undefined;
364      }
365      count++;
366    }
367    return undefined;
368  }
369
370  function __gtagTrackerClickEvent(event) {
371    var el = event.srcElement || event.target;
372    var valuesArray = [];
373    var fieldsArray;
374
375    /* Start Values Array */
376    valuesArray.el = el;
377    valuesArray.click_type = __gtagTrackerTrackedClickType(event);
378
379    /* If GA is blocked or not loaded, or not main|middle|touch click then don't track */
380    if ('undefined' === typeof __gtagTracker || !__gtagTrackerTrackedClick(event)) {
381      valuesArray.exit = 'loaded';
382      __gtagTrackerNotSend(valuesArray);
383      return;
384    }
385
386    /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
387    while (el && (
388      typeof el.tagName == 'undefined' || el.tagName.toLowerCase() != 'a' || !el.href
389    )) {
390      el = el.parentNode;
391    }
392
393    /* if a link with valid href has been clicked */
394    if (el && el.href && !el.hasAttribute('xlink:href')) {
395      var link = el.href;														/* What link are we tracking */
396      var extension = __gtagTrackerGetExtension(el.href);							/* What extension is this link */
397      var download_extensions = __gtagTrackerGetDownloadExtensions(); 							/* Let's get the extensions to track */
398      var inbound_paths = __gtagTrackerGetInboundPaths(); 								/* Let's get the internal paths to track */
399      var home_url = exactmetrics_frontend.home_url; 							/* Let's get the url to compare for external/internal use */
400      var currentdomain = __gtagTrackerGetDomain();										/* What domain are we on? */
401      var type = __gtagTrackerLinkType(el); 									/* What type of link is this? */
402      var target = __gtagTrackerLinkTarget(el, event);							/* Is a new tab/window being opened? */
403      var action = el.getAttribute("data-vars-ga-action");
404      var label = el.getAttribute("data-vars-ga-label");
405
406      /* Element */
407      valuesArray.el = el;					/* el is an a element so we can parse it */
408      valuesArray.el_href = el.href; 				/* "http://example.com:3000/pathname/?search=test#hash" */
409      valuesArray.el_protocol = el.protocol; 			/* "http:" */
410      valuesArray.el_hostname = el.hostname; 			/* "example.com" */
411      valuesArray.el_port = el.port; 				/* "3000" */
412      valuesArray.el_pathname = el.pathname; 			/* "/pathname/" */
413      valuesArray.el_search = el.search; 			/* "?search=test" */
414      valuesArray.el_hash = el.hash;				/* "#hash" */
415      valuesArray.el_host = el.host; 				/* "example.com:3000" */
416      valuesArray.el_classes = el.getAttribute('class')
417      valuesArray.el_id = el.id
418
419      /* Settings */
420      valuesArray.debug_mode = __gtagTrackerIsDebug(); /* "example.com:3000" */
421      valuesArray.download_extensions = download_extensions;  /* Let's get the extensions to track */
422      valuesArray.inbound_paths = inbound_paths; 		/* Let's get the internal paths to track */
423      valuesArray.home_url = home_url;				/* Let's get the url to compare for external/internal use */
424
425      /* Parsed/Logic */
426      valuesArray.link = link; 				/* What link are we tracking */
427      valuesArray.extension = extension; 			/* What extension is this link */
428      valuesArray.type = type; 				/* What type of link is this */
429      valuesArray.target = target;				/* Is a new tab/window being opened? */
430      valuesArray.title = __gtagTrackerGetTitle(el); /* Try link title, then text content */
431
432      /* only find innerTitle if we need one */
433      if (!valuesArray.label && !valuesArray.title) {
434        valuesArray.title = __gtagTrackerGetInnerTitle(el);
435      }
436
437      /* Let's track everything but internals (that aren't internal-as-externals) and javascript */
438      if (type !== 'internal' && type !== 'javascript') {
439
440        var __gtagTrackerHitBackRun = false; /* Tracker has not yet run */
441
442        /* HitCallback to open link in same window after tracker */
443        var __gtagTrackerHitBack = function () {
444          /* Run the hitback only once */
445          if (__gtagTrackerHitBackRun) {
446            return;
447          }
448          maybePreventBeforeUnload();
449          __gtagTrackerHitBackRun = true;
450
451          if ( el.attributes.download ) {
452            var linkTag = document.createElement('a');
453            linkTag.href = el.href;
454            linkTag.download = el.download;
455            linkTag.click();
456          } else {
457            window.location.href = link;
458          }
459        };
460
461        var __gtagTrackerNoRedirectExternal = function () {
462          valuesArray.exit = 'external';
463          __gtagTrackerNotSend(valuesArray);
464        };
465
466        var __gtagTrackerNoRedirectInboundAsExternal = function () {
467          valuesArray.exit = 'internal-as-outbound';
468          __gtagTrackerNotSend(valuesArray);
469        };
470        var __gtagTrackerNoRedirectCrossHostname = function () {
471          valuesArray.exit = 'cross-hostname';
472          __gtagTrackerNotSend(valuesArray);
473        };
474
475        if (target || type == 'mailto' || type == 'tel') { /* If target opens a new window then just track */
476          if (type == 'download') {
477            fieldsArray = {
478              event_category: 'download',
479              event_label: label || valuesArray.title,
480              file_extension: valuesArray.extension,
481              file_name: valuesArray.link.replace(/^.*\//g, ''),
482              link_text: label || valuesArray.title,
483              link_url: link,
484              link_domain: valuesArray.el_hostname,
485              link_classes: valuesArray.el_classes,
486              link_id: valuesArray.el_id,
487            };
488          } else if (type == 'tel') {
489            fieldsArray = {
490              event_category: 'tel',
491              event_label: label || valuesArray.title.replace('tel:', ''),
492              tel_number: link.replace('tel:', ''),
493              link_text: label || valuesArray.title,
494              link_url: link,
495              link_classes: valuesArray.el_classes,
496              link_id: valuesArray.el_id,
497            };
498          } else if (type == 'mailto') {
499            fieldsArray = {
500              event_category: 'mailto',
501              event_label: label || valuesArray.title.replace('mailto:', ''),
502              email_address: link.replace('mailto:', ''),
503              link_text: label || valuesArray.title.replace('mailto:', ''),
504              link_url: link,
505              link_classes: valuesArray.el_classes,
506              link_id: valuesArray.el_id,
507            };
508          } else if (type == 'internal-as-outbound') {
509            fieldsArray = {
510              event_category: internalAsOutboundCategory,
511              event_label: label || valuesArray.title,
512              event_name: 'click',
513              is_affiliate_link: true,
514              affiliate_label: internalAsOutboundCategory.replace('outbound-link-', ''),
515              link_text: label || valuesArray.title,
516              link_url: link,
517              link_domain: valuesArray.el_hostname,
518              link_classes: valuesArray.el_classes,
519              link_id: valuesArray.el_id,
520              outbound: true,
521            };
522          } else if (type == 'external') {
523            fieldsArray = {
524              event_category: 'outbound-link',
525              event_label: label || valuesArray.title,
526              is_affiliate_link: false,
527              link_text: label || valuesArray.title,
528              link_url: link,
529              link_domain: valuesArray.el_hostname,
530              link_classes: valuesArray.el_classes,
531              link_id: valuesArray.el_id,
532              outbound: true,
533            };
534          } else if (type == 'cross-hostname') {
535            fieldsArray = {
536              event_category: 'cross-hostname',
537              event_label: label || valuesArray.title,
538              link_text: label || valuesArray.title,
539              link_url: link,
540              link_domain: valuesArray.el_hostname,
541              link_classes: valuesArray.el_classes,
542              link_id: valuesArray.el_id,
543            };
544          }
545
546          if (fieldsArray) {
547            __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
548          } else {
549            if (type && type != 'internal') {
550              fieldsArray = {
551                event_category: type,
552                event_label: label || valuesArray.title,
553                link_text: label || valuesArray.title,
554                link_url: link,
555                link_domain: valuesArray.el_hostname,
556                link_classes: valuesArray.el_classes,
557                link_id: valuesArray.el_id,
558              };
559
560              __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
561            } else {
562              valuesArray.exit = 'type';
563              __gtagTrackerNotSend(valuesArray);
564            }
565          }
566        } else {
567          /* Prevent standard click, track then open */
568          if (type != 'cross-hostname' && type != 'external' && type != 'internal-as-outboun
568d') {
569            if (!event.defaultPrevented) {
570              if (event.preventDefault) {
571                event.preventDefault();
572              } else {
573                event.returnValue = false;
574              }
575            }
576          }
577
578          if (type == 'download') {
579            fieldsArray = {
580              event_category: 'download',
581              event_label: label || valuesArray.title,
582              event_callback: __gtagTrackerHitBack,
583              file_extension: valuesArray.extension,
584              file_name: valuesArray.link.replace(/^.*\//g, ''),
585              link_text: label || valuesArray.title,
586              link_url: link,
587              link_domain: valuesArray.el_hostname,
588              link_classes: valuesArray.el_classes,
589              link_id: valuesArray.el_id,
590            };
591
592            __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
593          } else if (type == 'internal-as-outbound') {
594            beforeUnloadChanged = true;
595            window.onbeforeunload = function (e) {
596              if (!event.defaultPrevented) {
597                if (event.preventDefault) {
598                  event.preventDefault();
599                } else {
600                  event.returnValue = false;
601                }
602              }
603
604              fieldsArray = {
605                event_category: internalAsOutboundCategory,
606                event_label: label || valuesArray.title,
607                event_callback: __gtagTrackerHitBack,
608                is_affiliate_link: true,
609                affiliate_label: internalAsOutboundCategory.replace('outbound-link-', ''),
610                link_text: label || valuesArray.title,
611                link_url: link,
612                link_domain: valuesArray.el_hostname,
613                link_classes: valuesArray.el_classes,
614                link_id: valuesArray.el_id,
615                outbound: true,
616              };
617
618              if (navigator.sendBeacon) {
619                fieldsArray.transport = 'beacon';
620              }
621
622              __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
623
624              setTimeout(__gtagTrackerHitBack, 1000);
625            };
626          } else if (type == 'external') {
627            beforeUnloadChanged = true;
628            window.onbeforeunload = function (e) {
629
630              fieldsArray = {
631                event_category: 'outbound-link',
632                event_label: label || valuesArray.title,
633                event_callback: __gtagTrackerHitBack,
634                is_affiliate_link: false,
635                link_text: label || valuesArray.title,
636                link_url: link,
637                link_domain: valuesArray.el_hostname,
638                link_classes: valuesArray.el_classes,
639                link_id: valuesArray.el_id,
640                outbound: true,
641              };
642
643              if (navigator.sendBeacon) {
644                fieldsArray.transport = 'beacon';
645              }
646
647              __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
648            };
649          } else if (type == 'cross-hostname') {
650            beforeUnloadChanged = true;
651            window.onbeforeunload = function (e) {
652              if (!event.defaultPrevented) {
653                if (event.preventDefault) {
654                  event.preventDefault();
655                } else {
656                  event.returnValue = false;
657                }
658              }
659
660              fieldsArray = {
661                event_category: 'cross-hostname',
662                event_label: label || valuesArray.title,
663                event_callback: __gtagTrackerHitBack,
664                link_text: label || valuesArray.title,
665                link_url: link,
666                link_domain: valuesArray.el_hostname,
667                link_classes: valuesArray.el_classes,
668                link_id: valuesArray.el_id,
669              };
670
671              if (navigator.sendBeacon) {
672                fieldsArray.transport = 'beacon';
673              }
674
675              __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
676              setTimeout(__gtagTrackerHitBack, 1000);
677            };
678          } else {
679            if (type && type !== 'internal') {
680              fieldsArray = {
681                event_category: type,
682                event_label: label || valuesArray.title,
683                event_callback: __gtagTrackerHitBack,
684                link_text: label || valuesArray.title,
685                link_url: link,
686                link_domain: valuesArray.el_hostname,
687                link_classes: valuesArray.el_classes,
688                link_id: valuesArray.el_id,
689              };
690
691              __gtagTrackerSendDual('event', action || link, fieldsArray, valuesArray);
692            } else {
693              valuesArray.exit = 'type';
694              __gtagTrackerNotSend(valuesArray);
695            }
696          }
697
698          if (type != 'external' && type != 'cross-hostname' && type != 'internal-as-outbound') {
699            /* Run event_callback again if GA takes longer than 1 second */
700            setTimeout(__gtagTrackerHitBack, 1000);
701          } else {
702            if (type == 'external') {
703              setTimeout(__gtagTrackerNoRedirectExternal, 1100);
704            } else if (type == 'cross-hostname') {
705              setTimeout(__gtagTrackerNoRedirectCrossHostname, 1100);
706            } else {
707              setTimeout(__gtagTrackerNoRedirectInboundAsExternal, 1100);
708            }
709          }
710
711          // Clear out the beforeunload event if it was set to avoid sending false events.
712          setTimeout(maybePreventBeforeUnload, 100);
713        }
714      } else {
715        maybePreventBeforeUnload();
716        valuesArray.exit = 'internal';
717        __gtagTrackerNotSend(valuesArray);
718      }
719    } else {
720      valuesArray.exit = 'notlink';
721      __gtagTrackerNotSend(valuesArray);
722    }
723  }
724
725  var prevHash = window.location.hash;
726
727  function __gtagTrackerHashChangeEvent() {
728    /* Todo: Ready this section for JS unit testing */
729    if (exactmetrics_frontend.hash_tracking === "true" && prevHash != window.location.hash && (exactmetrics_frontend.ua || exactmetrics_frontend.v4_id)) {
730      prevHash = window.location.hash;
731      if (exactmetrics_frontend.ua) {
732        __gtagTracker('config', exactmetrics_frontend.ua, {
733          page_path: location.pathname + location.search + location.hash,
734        });
735      }
736
737      if (exactmetrics_frontend.v4_id) {
738        __gtagTracker('config', exactmetrics_frontend.v4_id, {
739          page_path: location.pathname + location.search + location.hash,
740        });
741      }
742      __gtagTrackerLog("Hash change to: " + location.pathname + location.search + location.hash);
743    } else {
744      __gtagTrackerLog("Hash change to (untracked): " + location.pathname + location.search + location.hash);
745    }
746  }
747
748  function maybePreventBeforeUnload() {
749    if (beforeUnloadChanged) {
750      window.onbeforeunload = null;
751    }
752  }
753
754  /* Attach the event to all clicks in the document after page has loaded */
755  var __gtagTrackerWindow = window;
756  if (__gtagTrackerWindow.addEventListener) {
757    __gtagTrackerWindow.addEventListener(
758      "load",
759      function () {
760        document.body.addEventListener(
761          "click",
762          __gtagTrackerClickEvent,
763          false
764        );
765      },
766      false
767    );
768    window.addEventListener("hashchange", __gtagTrackerHashChangeEvent, false);
769  } else {
770    if (__gtagTrackerWindow.attachEvent) {
771      __gtagTrackerWindow.attachEvent(
772        "onload",
773        function () {
774          document.body.attachEvent("onclick", __gtagTrackerClickEvent);
775        }
776      );
777      window.attachEvent("onhashchange", __gtagTrackerHashChangeEvent);
778    }
779  }
780
781  if (typeof String.prototype.endsWith !== 'function') {
782    String.prototype.endsWith = function (suffix) {
783      return this.indexOf(suffix, this.length - suffix.length) !== -1;
784    };
785  }
786  if (typeof String.prototype.startsWith !== 'function') {
787    String.prototype.startsWith = function (prefix) {
788      return this.indexOf(prefix) === 0;
789    };
790  }
791
792  if (typeof Array.prototype.lastIndexOf !== 'function') {
793    Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) {
794      'use strict';
795
796      if (this === void 0 || this === null) {
797        throw new TypeError();
798      }
799
800      var n, k,
801        t = Object(this),
802        len = t.length >>> 0; /* jshint ignore:line */
803      if (len === 0) {
804        return -1;
805      }
806
807      n = len - 1;
808      if (arguments.length > 1) {
809        n = Number(arguments[1]);
810        if (n != n) {
811          n = 0;
812        } else if (n != 0 && n != (
813          1 / 0
814        ) && n != -(
815          1 / 0
816        )) { /* jshint ignore:line */
817          n = (
818            n > 0 || -1
819          ) * Math.floor(Math.abs(n));
820        }
821      }
822
823      for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) {
824        if (k in t && t[k] === searchElement) {
825          return k;
826        }
827      }
828      return -1;
829    };
830  }
831};
832var ExactMetricsObject = new ExactMetrics();

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