PageSourceSearch

https://arahant.org/sites/default/files/js/js_Z7JYLCFSxhTJXeai6Pk-ZeMbTaEsqX7-aiiS8S6qcFg.js

js arahant.org collected 2026-10-02 07:22:23 UTC 26,355 bytes, 794 lines download raw bytes

1Drupal.TBMegaMenu = Drupal.TBMegaMenu || {};
2
3(function ($) {
4  Drupal.TBMegaMenu.oldWindowWidth = 0;
5  Drupal.TBMegaMenu.displayedMenuMobile = false;
6  Drupal.TBMegaMenu.supportedScreens = [980];
7  Drupal.TBMegaMenu.menuResponsive = function () {
8    var windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
9    var navCollapse = $('.tb-megamenu').children('.nav-collapse');
10    if (windowWidth < Drupal.TBMegaMenu.supportedScreens[0]) {
11      navCollapse.addClass('collapse');
12      if (Drupal.TBMegaMenu.displayedMenuMobile) {
13        navCollapse.css({height: 'auto', overflow: 'visible'});
14      } else {
15        navCollapse.css({height: 0, overflow: 'hidden'});
16      }
17    } else {
18      // If width of window is greater than 980 (supported screen).
19      navCollapse.removeClass('collapse');
20      if (navCollapse.height() <= 0) {
21        navCollapse.css({height: 'auto', overflow: 'visible'});
22      }
23    }
24  };
25  
26  Drupal.behaviors.tbMegaMenuAction = {
27    attach: function(context) {
28      $('.tb-megamenu-button', context).once('menuIstance', function () {
29        var This = this;
30        $(This).click(function() {
31          if(parseInt($(this).parent().children('.nav-collapse').height())) {
32            $(this).parent().children('.nav-collapse').css({height: 0, overflow: 'hidden'});
33            Drupal.TBMegaMenu.displayedMenuMobile = false;
34          }
35          else {
36            $(this).parent().children('.nav-collapse').css({height: 'auto', overflow: 'visible'});
37            Drupal.TBMegaMenu.displayedMenuMobile = true;
38          }
39        });
40      });
41      
42      
43      var isTouch = 'ontouchstart' in window && !(/hp-tablet/gi).test(navigator.appVersion);
44      if(!isTouch){
45        $(document).ready(function($){
46          var mm_duration = 0;
47          $('.tb-megamenu').each (function(){
48            if ($(this).data('duration')) {
49              mm_duration = $(this).data('duration');
50            }
51          });
52          var mm_timeout = mm_duration ? 100 + mm_duration : 500;
53          $('.nav > li, li.mega').hover(function(event) {
54            var $this = $(this);
55            if ($this.hasClass ('mega')) {
56              $this.addClass ('animating');
57              clearTimeout ($this.data('animatingTimeout'));
58              $this.data('animatingTimeout', setTimeout(function(){$this.removeClass ('animating')}, mm_timeout));
59              clearTimeout ($this.data('hoverTimeout'));
60              $this.data('hoverTimeout', setTimeout(function(){$this.addClass ('open')}, 100));  
61            } else {
62              clearTimeout ($this.data('hoverTimeout'));
63              $this.data('hoverTimeout', 
64              setTimeout(function(){$this.addClass ('open')}, 100));
65            }
66          },
67          function(event) {
68            var $this = $(this);
69            if ($this.hasClass ('mega')) {
70              $this.addClass ('animating');
71              clearTimeout ($this.data('animatingTimeout'));
72              $this.data('animatingTimeout', 
73              setTimeout(function(){$this.removeClass ('animating')}, mm_timeout));
74              clearTimeout ($this.data('hoverTimeout'));
75              $this.data('hoverTimeout', setTimeout(function(){$this.removeClass ('open')}, 100));
76            } else {
77              clearTimeout ($this.data('hoverTimeout'));
78              $this.data('hoverTimeout', 
79              setTimeout(function(){$this.removeClass ('open')}, 100));
80            }
81          });
82        });
83      }
84      
85      $(window).resize(function() {
86        var windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
87        if(windowWidth != Drupal.TBMegaMenu.oldWindowWidth){
88          Drupal.TBMegaMenu.oldWindowWidth = windowWidth;
89          Drupal.TBMegaMenu.menuResponsive();
90        }
91      });
92    },
93  }
94})(jQuery);
95
96;
97Drupal.TBMegaMenu = Drupal.TBMegaMenu || {};
98
99(function ($) {
100  Drupal.TBMegaMenu.createTouchMenu = function(items) {
101      items.children('a').each( function() {
102	var $item = $(this);
103        var tbitem = $(this).parent();
104        $item.click( function(event){
105          if ($item.hasClass('tb-megamenu-clicked')) {
106            var $uri = $item.attr('href');
107            window.location.href = $uri;
108          }
109          else {
110            event.preventDefault();
111            $item.addClass('tb-megamenu-clicked');
112            if(!tbitem.hasClass('open')){	
113              tbitem.addClass('open');
114            }
115          }
116        }).closest('li').mouseleave( function(){
117          $item.removeClass('tb-megamenu-clicked');
118          tbitem.removeClass('open');
119        });
120     });
121     /*
122     items.children('a').children('span.caret').each( function() {
123	var $item = $(this).parent();
124        $item.click(function(event){
125          tbitem = $item.parent();
126          if ($item.hasClass('tb-megamenu-clicked')) {
127            Drupal.TBMegaMenu.eventStopPropagation(event);
128            if(tbitem.hasClass('open')){	
129              tbitem.removeClass('open');
130              $item.removeClass('tb-megamenu-clicked');
131            }
132          }
133          else {
134            Drupal.TBMegaMenu.eventStopPropagation(event);
135            $item.addClass('tb-megamenu-clicked');
136            if(!tbitem.hasClass('open')){	
137              tbitem.addClass('open');
138              $item.removeClass('tb-megamenu-clicked');
139            }
140          }
141        });
142     });
143     */
144  }
145  
146  Drupal.TBMegaMenu.eventStopPropagation = function(event) {
147    if (event.stopPropagation) {
148      event.stopPropagation();
149    }
150    else if (window.event) {
151      window.event.cancelBubble = true;
152    }
153  }  
154  Drupal.behaviors.tbMegaMenuTouchAction = {
155    attach: function(context) {
156      var isTouch = 'ontouchstart' in window && !(/hp-tablet/gi).test(navigator.appVersion);
157      if(isTouch){
158        $('html').addClass('touch');
159        Drupal.TBMegaMenu.createTouchMenu($('.tb-megamenu ul.nav li.mega').has('.dropdown-menu'));
160      }
161    }
162  }
163})(jQuery);
164;
165(function ($) {
166
167  Drupal.behaviors.captcha = {
168    attach: function (context) {
169
170      // Turn off autocompletion for the CAPTCHA response field.
171      // We do it here with JavaScript (instead of directly in the markup)
172      // because this autocomplete attribute is not standard and
173      // it would break (X)HTML compliance.
174      $("#edit-captcha-response").attr("autocomplete", "off");
175
176    }
177  };
178
179  Drupal.behaviors.captchaAdmin = {
180    attach: function (context) {
181      // Add onclick handler to checkbox for adding a CAPTCHA description
182      // so that the textfields for the CAPTCHA description are hidden
183      // when no description should be added.
184      // @todo: div.form-item-captcha-description depends on theming, maybe
185      // it's better to add our own wrapper with id (instead of a class).
186      $("#edit-captcha-add-captcha-description").click(function() {
187        if ($("#edit-captcha-add-captcha-description").is(":checked")) {
188          // Show the CAPTCHA description textfield(s).
189          $("div.form-item-captcha-description").show('slow');
190        }
191        else {
192          // Hide the CAPTCHA description textfield(s).
193          $("div.form-item-captcha-description").hide('slow');
194        }
195      });
196      // Hide the CAPTCHA description textfields if option is disabled on page load.
197      if (!$("#edit-captcha-add-captcha-description").is(":checked")) {
198        $("div.form-item-captcha-description").hide();
199      }
200    }
201
202  };
203
204})(jQuery);
205;
206/**
207 * @file
208 * Some basic behaviors and utility functions for Views.
209 */
210(function ($) {
211
212  Drupal.Views = {};
213
214  /**
215   * JQuery UI tabs, Views integration component.
216   */
217  Drupal.behaviors.viewsTabs = {
218    attach: function (context) {
219      if ($.viewsUi && $.viewsUi.tabs) {
220        $('#views-tabset').once('views-processed').viewsTabs({
221          selectedClass: 'active'
222        });
223      }
224
225      $('a.views-remove-link').once('views-processed').click(function(event) {
226        var id = $(this).attr('id').replace('views-remove-link-', '');
227        $('#views-row-' + id).hide();
228        $('#views-removed-' + id).attr('checked', true);
229        event.preventDefault();
230      });
231      /**
232    * Here is to handle display deletion
233    * (checking in the hidden checkbox and hiding out the row).
234    */
235      $('a.display-remove-link')
236        .addClass('display-processed')
237        .click(function() {
238          var id = $(this).attr('id').replace('display-remove-link-', '');
239          $('#display-row-' + id).hide();
240          $('#display-removed-' + id).attr('checked', true);
241          return false;
242        });
243    }
244  };
245
246  /**
247 * Helper function to parse a querystring.
248 */
249  Drupal.Views.parseQueryString = function (query) {
250    var args = {};
251    var pos = query.indexOf('?');
252    if (pos != -1) {
253      query = query.substring(pos + 1);
254    }
255    var pairs = query.split('&');
256    for (var i in pairs) {
257      if (typeof(pairs[i]) == 'string') {
258        var pair = pairs[i].split('=');
259        // Ignore the 'q' path argument, if present.
260        if (pair[0] != 'q' && pair[1]) {
261          args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
262        }
263      }
264    }
265    return args;
266  };
267
268  /**
269 * Helper function to return a view's arguments based on a path.
270 */
271  Drupal.Views.parseViewArgs = function (href, viewPath) {
272
273    // Provide language prefix.
274    if (Drupal.settings.pathPrefix) {
275      var viewPath = Drupal.settings.pathPrefix + viewPath;
276    }
277    var returnObj = {};
278    var path = Drupal.Views.getPath(href);
279    // Ensure we have a correct path.
280    if (viewPath && path.substring(0, viewPath.length + 1) == viewPath + '/') {
281      var args = decodeURIComponent(path.substring(viewPath.length + 1, path.length));
282      returnObj.view_args = args;
283      returnObj.view_path = path;
284    }
285    return returnObj;
286  };
287
288  /**
289 * Strip off the protocol plus domain from an href.
290 */
291  Drupal.Views.pathPortion = function (href) {
292    // Remove e.g. http://example.com if present.
293    var protocol = window.location.protocol;
294    if (href.substring(0, protocol.length) == protocol) {
295      // 2 is the length of the '//' that normally follows the protocol.
296      href = href.substring(href.indexOf('/', protocol.length + 2));
297    }
298    return href;
299  };
300
301  /**
302 * Return the Drupal path portion of an href.
303 */
304  Drupal.Views.getPath = function (href) {
305    href = Drupal.Views.pathPortion(href);
306    href = href.substring(Drupal.settings.basePath.length, href.length);
307    // 3 is the length of the '?q=' added to the url without clean urls.
308    if (href.substring(0, 3) == '?q=') {
309      href = href.substring(3, href.length);
310    }
311    var chars = ['#', '?', '&'];
312    for (var i in chars) {
313      if (href.indexOf(chars[i]) > -1) {
314        href = href.substr(0, href.indexOf(chars[i]));
315      }
316    }
317    return href;
318  };
319
320})(jQuery);
321;
322(function ($) {
323
324/**
325 * A progressbar object. Initialized with the given id. Must be inserted into
326 * the DOM afterwards through progressBar.element.
327 *
328 * method is the function which will perform the HTTP request to get the
329 * progress bar state. Either "GET" or "POST".
330 *
331 * e.g. pb = new progressBar('myProgressBar');
332 *      some_element.appendChild(pb.element);
333 */
334Drupal.progressBar = function (id, updateCallback, method, errorCallback) {
335  var pb = this;
336  this.id = id;
337  this.method = method || 'GET';
338  this.updateCallback = updateCallback;
339  this.errorCallback = errorCallback;
340
341  // The WAI-ARIA setting aria-live="polite" will announce changes after users
342  // have completed their current activity and not interrupt the screen reader.
343  this.element = $('<div class="progress-wrapper" aria-live="polite"></div>');
344  this.element.html('<div id ="' + id + '" class="progress progress-striped active">' +
345                    '<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' +
346                    '<div class="percentage sr-only"></div>' +
347                    '</div></div>' +
348                    '</div><div class="percentage pull-right"></div>' +
349                    '<div class="message">&nbsp;</div>');
350};
351
352/**
353 * Set the percentage and status message for the progressbar.
354 */
355Drupal.progressBar.prototype.setProgress = function (percentage, message) {
356  if (percentage >= 0 && percentage <= 100) {
357    $('div.progress-bar', this.element).css('width', percentage + '%');
358    $('div.progress-bar', this.element).attr('aria-valuenow', percentage);
359    $('div.percentage', this.element).html(percentage + '%');
360  }
361  $('div.message', this.element).html(message);
362  if (this.updateCallback) {
363    this.updateCallback(percentage, message, this);
364  }
365};
366
367/**
368 * Start monitoring progress via Ajax.
369 */
370Drupal.progressBar.prototype.startMonitoring = function (uri, delay) {
371  this.delay = delay;
372  this.uri = uri;
373  this.sendPing();
374};
375
376/**
377 * Stop monitoring progress via Ajax.
378 */
379Drupal.progressBar.prototype.stopMonitoring = function () {
380  clearTimeout(this.timer);
381  // This allows monitoring to be stopped from within the callback.
382  this.uri = null;
383};
384
385/**
386 * Request progress data from server.
387 */
388Drupal.progressBar.prototype.sendPing = function () {
389  if (this.timer) {
390    clearTimeout(this.timer);
391  }
392  if (this.uri) {
393    var pb = this;
394    // When doing a post request, you need non-null data. Otherwise a
395    // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
396    $.ajax({
397      type: this.method,
398      url: this.uri,
399      data: '',
400      dataType: 'json',
401      success: function (progress) {
402        // Display errors.
403        if (progress.status == 0) {
404          pb.displayError(progress.data);
405          return;
406        }
407        // Update display.
408        pb.setProgress(progress.percentage, progress.message);
409        // Schedule next timer.
410        pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay);
411      },
412      error: function (xmlhttp) {
413        pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri));
414      }
415    });
416  }
417};
418
419/**
420 * Display errors on the page.
421 */
422Drupal.progressBar.prototype.displayError = function (string) {
423  var error = $('<div class="alert alert-block alert-error"><a class="close" data-dismiss="alert" href="#">&times;</a><h4>Error message</h4></div>').append(string);
424  $(this.element).before(error).hide();
425
426  if (this.errorCallback) {
427    this.errorCallback(this);
428  }
429};
430
431})(jQuery);
432;
433/**
434 * @file
435 * Handles AJAX fetching of views, including filter submission and response.
436 */
437(function ($) {
438
439  /**
440   * Attaches the AJAX behavior to exposed filter forms and key views links.
441   */
442  Drupal.behaviors.ViewsAjaxView = {};
443  Drupal.behaviors.ViewsAjaxView.attach = function() {
444    if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
445      $.each(Drupal.settings.views.ajaxViews, function(i, settings) {
446        Drupal.views.instances[i] = new Drupal.views.ajaxView(settings);
447      });
448    }
449  };
450
451  Drupal.views = {};
452  Drupal.views.instances = {};
453
454  /**
455   * JavaScript object for a certain view.
456   */
457  Drupal.views.ajaxView = function(settings) {
458    var selector = '.view-dom-id-' + settings.view_dom_id;
459    this.$view = $(selector);
460
461    // Retrieve the path to use for views' ajax.
462    var ajax_path = Drupal.settings.views.ajax_path;
463
464    // If there are multiple views this might've ended up showing up multiple
465    // times.
466    if (ajax_path.constructor.toString().indexOf("Array") != -1) {
467      ajax_path = ajax_path[0];
468    }
469
470    // Check if there are any GET parameters to send to views.
471    var queryString = window.location.search || '';
472    if (queryString !== '') {
473      // Remove the question mark and Drupal path component if any.
474      var queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, '');
475      if (queryString !== '') {
476        // If there is a '?' in ajax_path, clean url are on and & should be
477        // used to add parameters.
478        queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString;
479      }
480    }
481
482    this.element_settings = {
483      url: ajax_path + queryString,
484      submit: settings,
485      setClick: true,
486      event: 'click',
487      selector: selector,
488      progress: {
489        type: 'throbber'
490      }
491    };
492
493    this.settings = settings;
494
495    // Add the ajax to exposed forms.
496    this.$exposed_form = $('#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-'));
497    this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this));
498
499    // Store Drupal.ajax objects here for all pager links.
500    this.links = [];
501
502    // Add the ajax to pagers.
503    this.$view
504      .once(jQuery.proxy(this.attachPagerAjax, this));
505
506    // Add a trigger to update this view specifically. In order to trigger a
507    // refresh use the following code.
508    //
509    // @code
510    // jQuery('.view-name').trigger('RefreshView');
511    // @endcode
512    // Add a trigger to update this view specifically.
513    var self_settings = this.element_settings;
514    self_settings.event = 'RefreshView';
515    this.refreshViewAjax = new Drupal.ajax(this.selector, this.$view, self_settings);
516  };
517
518  Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() {
519    var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form);
520    button = button[0];
521
522    // Call the autocomplete submit before doing AJAX.
523    $(button).click(function () {
524      if (Drupal.autocompleteSubmit) {
525        Drupal.autocompleteSubmit();
526      }
527    });
528
529    this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings);
530  };
531
532  /**
533   * Attach the ajax behavior to each link.
534   */
535  Drupal.views.ajaxView.prototype.attachPagerAjax = function() {
536    this.$view.find('ul.pager > li > a, th.views-field a, .attachment .views-summary a')
537      .each(jQuery.proxy(this.attachPagerLinkAjax, this));
538  };
539
540  /**
541   * Attach the ajax behavior to a singe link.
542   */
543  Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) {
544    var $link = $(link);
545    // Don't attach to pagers inside nested views.
546    if ($link.closest('.view')[0] !== this.$view[0]) {
547      return;
548    }
549    var viewData = {};
550    var href = $link.attr('href');
551
552    // Provide a default page if none has been set. This must be done
553    // prior to merging with settings to avoid accidentally using the
554    // page landed on instead of page 1.
555    if (typeof(viewData.page) === 'undefined') {
556      viewData.page = 0;
557    }
558
559    // Construct an object using the settings defaults and then overriding
560    // with data specific to the link.
561    $.extend(
562    viewData,
563    this.settings,
564    Drupal.Views.parseQueryString(href),
565    // Extract argument data from the URL.
566    Drupal.Views.parseViewArgs(href, this.settings.view_base_path)
567    );
568
569    // For anchor tags, these will go to the target of the anchor rather
570    // than the usual location.
571    $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path));
572
573    this.element_settings.submit = viewData;
574    this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings);
575    this.links.push(this.pagerAjax);
576  };
577
578  Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) {
579    // Scroll to the top of the view. This will allow users
580    // to browse newly loaded content after e.g. clicking a pager
581    // link.
582    var offset = $(response.selector).offset();
583    // We can't guarantee that the scrollable object should be
584    // the body, as the view could be embedded in something
585    // more complex such as a modal popup. Recurse up the DOM
586    // and scroll the first element that has a non-zero top.
587    var scrollTarget = response.selector;
588    while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) {
589      scrollTarget = $(scrollTarget).parent();
590    }
591    // Only scroll upward.
592    if (offset.top - 10 < $(scrollTarget).scrollTop()) {
593      $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
594    }
595  };
596
597})(jQuery);
598;
599(function ($) {
600
601Drupal.googleanalytics = {};
602
603$(document).ready(function() {
604
605  // Attach mousedown, keyup, touchstart events to document only and catch
606  // clicks on all elements.
607  $(document.body).bind("mousedown keyup touchstart", function(event) {
608
609    // Catch the closest surrounding link of a clicked element.
610    $(event.target).closest("a,area").each(function() {
611
612      // Is the clicked URL internal?
613      if (Drupal.googleanalytics.isInternal(this.href)) {
614        // Skip 'click' tracking, if custom tracking events are bound.
615        if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
616          // Do nothing here. The custom event will handle all tracking.
617          //console.info("Click on .colorbox item has been detected.");
618        }
619        // Is download tracking activated and the file extension configured for download tracking?
620        else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
621          // Download link clicked.
622          ga("send", {
623            "hitType": "event",
624            "eventCategory": "Downloads",
625            "eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(),
626            "eventLabel": Drupal.googleanalytics.getPageUrl(this.href),
627            "transport": "beacon"
628          });
629        }
630        else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
631          // Keep the internal URL for Google Analytics website overlay intact.
632          ga("send", {
633            "hitType": "pageview",
634            "page": Drupal.googleanalytics.getPageUrl(this.href),
635            "transport": "beacon"
636          });
637        }
638      }
639      else {
640        if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
641          // Mailto link clicked.
642          ga("send", {
643            "hitType": "event",
644            "eventCategory": "Mails",
645            "eventAction": "Click",
646            "eventLabel": this.href.substring(7),
647            "transport": "beacon"
648          });
649        }
650        else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
651          if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
652            // External link clicked / No top-level cross domain clicked.
653            ga("send", {
654              "hitType": "event",
655              "eventCategory": "Outbound links",
656              "eventAction": "Click",
657              "eventLabel": this.href,
658              "transport": "beacon"
659            });
660          }
661        }
662      }
663    });
664  });
665
666  // Track hash changes as unique pageviews, if this option has been enabled.
667  if (Drupal.settings.googleanalytics.trackUrlFragments) {
668    window.onhashchange = function() {
669      ga("send", {
670        "hitType": "pageview",
671        "page": location.pathname + location.search + location.hash
672      });
673    };
674  }
675
676  // Colorbox: This event triggers when the transition has completed and the
677  // newly loaded content has been revealed.
678  if (Drupal.settings.googleanalytics.trackColorbox) {
679    $(document).bind("cbox_complete", function () {
680      var href = $.colorbox.element().attr("href");
681      if (href) {
682        ga("send", {
683          "hitType": "pageview",
684          "page": Drupal.googleanalytics.getPageUrl(href)
685        });
686      }
687    });
688  }
689
690});
691
692/**
693 * Check whether the hostname is part of the cross domains or not.
694 *
695 * @param string hostname
696 *   The hostname of the clicked URL.
697 * @param array crossDomains
698 *   All cross domain hostnames as JS array.
699 *
700 * @return boolean
701 */
702Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) {
703  /**
704   * jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is
705   * `null` or `undefined`, https://bugs.jquery.com/ticket/10076,
706   * https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
707   *
708   * @todo: Remove/Refactor in D8
709   */
710  if (!crossDomains) {
711    return false;
712  }
713  else {
714    return $.inArray(hostname, crossDomains) > -1 ? true : false;
715  }
716};
717
718/**
719 * Check whether this is a download URL or not.
720 *
721 * @param string url
722 *   The web url to check.
723 *
724 * @return boolean
725 */
726Drupal.googleanalytics.isDownload = function (url) {
727  var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
728  return isDownload.test(url);
729};
730
731/**
732 * Check whether this is an absolute internal URL or not.
733 *
734 * @param string url
735 *   The web url to check.
736 *
737 * @return boolean
738 */
739Drupal.googleanalytics.isInternal = function (url) {
740  var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
741  return isInternal.test(url);
742};
743
744/**
745 * Check whether this is a special URL or not.
746 *
747 * URL types:
748 *  - gotwo.module /go/* links.
749 *
750 * @param string url
751 *   The web url to check.
752 *
753 * @return boolean
754 */
755Drupal.googleanalytics.isInternalSpecial = function (url) {
756  var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
757  return isInternalSpecial.test(url);
758};
759
760/**
761 * Extract the relative internal URL from an absolute internal URL.
762 *
763 * Examples:
764 * - https://mydomain.com/node/1 -> /node/1
765 * - https://example.com/foo/bar -> https://example.com/foo/bar
766 *
767 * @param string url
768 *   The web url to check.
769 *
770 * @return string
771 *   Internal website URL
772 */
773Drupal.googleanalytics.getPageUrl = function (url) {
774  var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i");
775  return url.replace(extractInternalUrl, '');
776};
777
778/**
779 * Extract the download file extension from the URL.
780 *
781 * @param string url
782 *   The web url to check.
783 *
784 * @return string
785 *   The file extension of the passed url. e.g. "zip", "txt"
786 */
787Drupal.googleanalytics.getDownloadExtension = function (url) {
788  var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
789  var extension = extractDownloadextension.exec(url);
790  return (extension === null) ? '' : extension[1];
791};
792
793})(jQuery);
794;

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.