PageSourceSearch

https://arquitectes.cat/sites/default/files/js/js_uS7HI6r6cwL2_YEsdipUYEen842FDiKiMHvakRjFt60.js

js arquitectes.cat collected 2026-09-24 09:32:39 UTC 53,266 bytes, 1,334 lines download raw bytes

1(function ($) {
2Drupal.behaviors.lang_dropdown = {
3  attach: function (context, settings) {
4    var settings = settings || Drupal.settings;
5
6    if (settings.lang_dropdown) {
7      var flags = settings.lang_dropdown.jsWidget.languageicons;
8      if (flags) {
9        $.each(flags, function(index, value) {
10          $('select.lang-dropdown-select-element option[value="' + index + '"]').attr('title', value);
11        });
12      }
13      var msddSettings = settings.lang_dropdown.jsWidget;
14
15      $('select.lang-dropdown-select-element').msDropDown({
16        visibleRows: msddSettings.visibleRows,
17        rowHeight: msddSettings.rowHeight,
18        animStyle: msddSettings.animStyle,
19        mainCSS: msddSettings.mainCSS
20      });
21    }
22
23    try {
24      $('select.lang-dropdown-select-element').change(function() {
25        var lang = this.options[this.selectedIndex].value;
26        var href = $(this).parents('form').find('input[name="' + lang + '"]').val();
27        window.location.href = href;
28      });
29    } catch (e) {
30      if (console) { console.log(e); }
31    }
32
33    $('form#lang-dropdown-form').after('<div style="clear:both;"></div>');
34  }
35};
36})(jQuery);
37;
38/**
39 * @file
40 * Some basic behaviors and utility functions for Views.
41 */
42(function ($) {
43
44  Drupal.Views = {};
45
46  /**
47   * JQuery UI tabs, Views integration component.
48   */
49  Drupal.behaviors.viewsTabs = {
50    attach: function (context) {
51      if ($.viewsUi && $.viewsUi.tabs) {
52        $('#views-tabset').once('views-processed').viewsTabs({
53          selectedClass: 'active'
54        });
55      }
56
57      $('a.views-remove-link').once('views-processed').click(function(event) {
58        var id = $(this).attr('id').replace('views-remove-link-', '');
59        $('#views-row-' + id).hide();
60        $('#views-removed-' + id).attr('checked', true);
61        event.preventDefault();
62      });
63      /**
64    * Here is to handle display deletion
65    * (checking in the hidden checkbox and hiding out the row).
66    */
67      $('a.display-remove-link')
68        .addClass('display-processed')
69        .click(function() {
70          var id = $(this).attr('id').replace('display-remove-link-', '');
71          $('#display-row-' + id).hide();
72          $('#display-removed-' + id).attr('checked', true);
73          return false;
74        });
75    }
76  };
77
78  /**
79 * Helper function to parse a querystring.
80 */
81  Drupal.Views.parseQueryString = function (query) {
82    var args = {};
83    var pos = query.indexOf('?');
84    if (pos != -1) {
85      query = query.substring(pos + 1);
86    }
87    var pairs = query.split('&');
88    for (var i in pairs) {
89      if (typeof(pairs[i]) == 'string') {
90        var pair = pairs[i].split('=');
91        // Ignore the 'q' path argument, if present.
92        if (pair[0] != 'q' && pair[1]) {
93          args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
94        }
95      }
96    }
97    return args;
98  };
99
100  /**
101 * Helper function to return a view's arguments based on a path.
102 */
103  Drupal.Views.parseViewArgs = function (href, viewPath) {
104
105    // Provide language prefix.
106    if (Drupal.settings.pathPrefix) {
107      var viewPath = Drupal.settings.pathPrefix + viewPath;
108    }
109    var returnObj = {};
110    var path = Drupal.Views.getPath(href);
111    // Ensure we have a correct path.
112    if (viewPath && path.substring(0, viewPath.length + 1) == viewPath + '/') {
113      var args = decodeURIComponent(path.substring(viewPath.length + 1, path.length));
114      returnObj.view_args = args;
115      returnObj.view_path = path;
116    }
117    return returnObj;
118  };
119
120  /**
121 * Strip off the protocol plus domain from an href.
122 */
123  Drupal.Views.pathPortion = function (href) {
124    // Remove e.g. http://example.com if present.
125    var protocol = window.location.protocol;
126    if (href.substring(0, protocol.length) == protocol) {
127      // 2 is the length of the '//' that normally follows the protocol.
128      href = href.substring(href.indexOf('/', protocol.length + 2));
129    }
130    return href;
131  };
132
133  /**
134 * Return the Drupal path portion of an href.
135 */
136  Drupal.Views.getPath = function (href) {
137    href = Drupal.Views.pathPortion(href);
138    href = href.substring(Drupal.settings.basePath.length, href.length);
139    // 3 is the length of the '?q=' added to the url without clean urls.
140    if (href.substring(0, 3) == '?q=') {
141      href = href.substring(3, href.length);
142    }
143    var chars = ['#', '?', '&'];
144    for (var i in chars) {
145      if (href.indexOf(chars[i]) > -1) {
146        href = href.substr(0, href.indexOf(chars[i]));
147      }
148    }
149    return href;
150  };
151
152})(jQuery);
153;
154(function ($) {
155
156/**
157 * A progressbar object. Initialized with the given id. Must be inserted into
158 * the DOM afterwards through progressBar.element.
159 *
160 * method is the function which will perform the HTTP request to get the
161 * progress bar state. Either "GET" or "POST".
162 *
163 * e.g. pb = new progressBar('myProgressBar');
164 *      some_element.appendChild(pb.element);
165 */
166Drupal.progressBar = function (id, updateCallback, method, errorCallback) {
167  var pb = this;
168  this.id = id;
169  this.method = method || 'GET';
170  this.updateCallback = updateCallback;
171  this.errorCallback = errorCallback;
172
173  // The WAI-ARIA setting aria-live="polite" will announce changes after users
174  // have completed their current activity and not interrupt the screen reader.
175  this.element = $('<div class="progress-wrapper" aria-live="polite"></div>');
176  this.element.html('<div id ="' + id + '" class="progress progress-striped active">' +
177                    '<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' +
178                    '<div class="percentage sr-only"></div>' +
179                    '</div></div>' +
180                    '</div><div class="percentage pull-right"></div>' +
181                    '<div class="message">&nbsp;</div>');
182};
183
184/**
185 * Set the percentage and status message for the progressbar.
186 */
187Drupal.progressBar.prototype.setProgress = function (percentage, message) {
188  if (percentage >= 0 && percentage <= 100) {
189    $('div.progress-bar', this.element).css('width', percentage + '%');
190    $('div.progress-bar', this.element).attr('aria-valuenow', percentage);
191    $('div.percentage', this.element).html(percentage + '%');
192  }
193  $('div.message', this.element).html(message);
194  if (this.updateCallback) {
195    this.updateCallback(percentage, message, this);
196  }
197};
198
199/**
200 * Start monitoring progress via Ajax.
201 */
202Drupal.progressBar.prototype.startMonitoring = function (uri, delay) {
203  this.delay = delay;
204  this.uri = uri;
205  this.sendPing();
206};
207
208/**
209 * Stop monitoring progress via Ajax.
210 */
211Drupal.progressBar.prototype.stopMonitoring = function () {
212  clearTimeout(this.timer);
213  // This allows monitoring to be stopped from within the callback.
214  this.uri = null;
215};
216
217/**
218 * Request progress data from server.
219 */
220Drupal.progressBar.prototype.sendPing = function () {
221  if (this.timer) {
222    clearTimeout(this.timer);
223  }
224  if (this.uri) {
225    var pb = this;
226    // When doing a post request, you need non-null data. Otherwise a
227    // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
228    $.ajax({
229      type: this.method,
230      url: this.uri,
231      data: '',
232      dataType: 'json',
233      success: function (progress) {
234        // Display errors.
235        if (progress.status == 0) {
236          pb.displayError(progress.data);
237          return;
238        }
239        // Update display.
240        pb.setProgress(progress.percentage, progress.message);
241        // Schedule next timer.
242        pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay);
243      },
244      error: function (xmlhttp) {
245        pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri));
246      }
247    });
248  }
249};
250
251/**
252 * Display errors on the page.
253 */
254Drupal.progressBar.prototype.displayError = function (string) {
255  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);
256  $(this.element).before(error).hide();
257
258  if (this.errorCallback) {
259    this.errorCallback(this);
260  }
261};
262
263})(jQuery);
264;
265/**
266 * @file
267 * Handles AJAX fetching of views, including filter submission and response.
268 */
269(function ($) {
270
271  /**
272   * Attaches the AJAX behavior to exposed filter forms and key views links.
273   */
274  Drupal.behaviors.ViewsAjaxView = {};
275  Drupal.behaviors.ViewsAjaxView.attach = function() {
276    if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
277      $.each(Drupal.settings.views.ajaxViews, function(i, settings) {
278        Drupal.views.instances[i] = new Drupal.views.ajaxView(settings);
279      });
280    }
281  };
282
283  Drupal.views = {};
284  Drupal.views.instances = {};
285
286  /**
287   * Javascript object for a certain view.
288   */
289  Drupal.views.ajaxView = function(settings) {
290    var selector = '.view-dom-id-' + settings.view_dom_id;
291    this.$view = $(selector);
292
293    // Retrieve the path to use for views' ajax.
294    var ajax_path = Drupal.settings.views.ajax_path;
295
296    // If there are multiple views this might've ended up showing up multiple
297    // times.
298    if (ajax_path.constructor.toString().indexOf("Array") != -1) {
299      ajax_path = ajax_path[0];
300    }
301
302    // Check if there are any GET parameters to send to views.
303    var queryString = window.location.search || '';
304    if (queryString !== '') {
305      // Remove the question mark and Drupal path component if any.
306      var queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, '');
307      if (queryString !== '') {
308        // If there is a '?' in ajax_path, clean url are on and & should be
309        // used to add parameters.
310        queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString;
311      }
312    }
313
314    this.element_settings = {
315      url: ajax_path + queryString,
316      submit: settings,
317      setClick: true,
318      event: 'click',
319      selector: selector,
320      progress: {
321        type: 'throbber'
322      }
323    };
324
325    this.settings = settings;
326
327    // Add the ajax to exposed forms.
328    this.$exposed_form = $('#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-'));
329    this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this));
330
331    // Store Drupal.ajax objects here for all pager links.
332    this.links = [];
333
334    // Add the ajax to pagers.
335    this.$view
336    // Don't attach to nested views. Doing so would attach multiple behaviors
337    // to a given element.
338      .filter(jQuery.proxy(this.filterNestedViews, this))
339      .once(jQuery.proxy(this.attachPagerAjax, this));
340
341    // Add a trigger to update this view specifically. In order to trigger a
342    // refresh use the following code.
343    //
344    // @code
345    // jQuery('.view-name').trigger('RefreshView');
346    // @endcode
347    // Add a trigger to update this view specifically.
348    var self_settings = this.element_settings;
349    self_settings.event = 'RefreshView';
350    this.refreshViewAjax = new Drupal.ajax(this.selector, this.$view, self_settings);
351  };
352
353  Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() {
354    var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form);
355    button = button[0];
356
357    // Call the autocomplete submit before doing AJAX.
358    $(button).click(function () {
359      if (Drupal.autocompleteSubmit) {
360        Drupal.autocompleteSubmit();
361      }
362    });
363
364    this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings);
365  };
366
367  Drupal.views.ajaxView.prototype.filterNestedViews = function() {
368    // If there is at least one parent with a view class, this view
369    // is nested (e.g., an attachment). Bail.
370    return !this.$view.parents('.view').length;
371  };
372
373  /**
374   * Attach the ajax behavior to each link.
375   */
376  Drupal.views.ajaxView.prototype.attachPagerAjax = function() {
377    this.$view.find('ul.pager > li > a, th.views-field a, .attachment .views-summary a')
378      .each(jQuery.proxy(this.attachPagerLinkAjax, this));
379  };
380
381  /**
382   * Attach the ajax behavior to a singe link.
383   */
384  Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) {
385    var $link = $(link);
386    var viewData = {};
387    var href = $link.attr('href');
388    // Construct an object using the settings defaults and then overriding
389    // with data specific to the link.
390    $.extend(
391    viewData,
392    this.settings,
393    Drupal.Views.parseQueryString(href),
394    // Extract argument data from the URL.
395    Drupal.Views.parseViewArgs(href, this.settings.view_base_path)
396    );
397
398    // For anchor tags, these will go to the target of the anchor rather
399    // than the usual location.
400    $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path));
401
402    this.element_settings.submit = viewData;
403    this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings);
404    this.links.push(this.pagerAjax);
405  };
406
407  Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) {
408    // Scroll to the top of the view. This will allow users
409    // to browse newly loaded content after e.g. clicking a pager
410    // link.
411    var offset = $(response.selector).offset();
412    // We can't guarantee that the scrollable object should be
413    // the body, as the view could be embedded in something
414    // more complex such as a modal popup. Recurse up the DOM
415    // and scroll the first element that has a non-zero top.
416    var scrollTarget = response.selector;
417    while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) {
418      scrollTarget = $(scrollTarget).parent();
419    }
420    // Only scroll upward.
421    if (offset.top - 10 < $(scrollTarget).scrollTop()) {
422      $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
423    }
424  };
425
426})(jQuery);
427;
428(function($) {
429  Drupal.behaviors.chosen = {
430    attach: function(context, settings) {
431      settings.chosen = settings.chosen || Drupal.settings.chosen;
432
433      // Prepare selector and add unwantend selectors.
434      var selector = settings.chosen.selector;
435
436      // Function to prepare all the options together for the chosen() call.
437      var getElementOptions = function (element) {
438        var options = $.extend({}, settings.chosen.options);
439
440        // The width default option is considered the minimum width, so this
441        // must be evaluated for every option.
442        if (settings.chosen.minimum_width > 0) {
443          if ($(element).width() < settings.chosen.minimum_width) {
444            options.width = settings.chosen.minimum_width + 'px';
445          }
446          else {
447            options.width = $(element).width() + 'px';
448          }
449        }
450
451        // Some field widgets have cardinality, so we must respect that.
452        // @see chosen_pre_render_select()
453        if ($(element).attr('multiple') && $(element).data('cardinality')) {
454          options.max_selected_options = $(element).data('cardinality');
455        }
456
457        return options;
458      };
459
460      // Process elements that have opted-in for Chosen.
461      // @todo Remove support for the deprecated chosen-widget class.
462      $('select.chosen-enable, select.chosen-widget', context).once('chosen', function() {
463        options = getElementOptions(this);
464        $(this).chosen(options);
465      });
466
467      $(selector, context)
468        // Disabled on:
469        // - Field UI
470        // - WYSIWYG elements
471        // - Tabledrag weights
472        // - Elements that have opted-out of Chosen
473        // - Elements already processed by Chosen
474        .not('#field-ui-field-overview-form select, #field-ui-display-overview-form select, .wysiwyg, .draggable select[name$="[weight]"], .draggable select[name$="[position]"], .chosen-disable, .chosen-processed')
475        .filter(function() {
476          // Filter out select widgets that do not meet the minimum number of
477          // options.
478          var minOptions = $(this).attr('multiple') ? settings.chosen.minimum_multiple : settings.chosen.minimum_single;
479          if (!minOptions) {
480            // Zero value means no minimum.
481            return true;
482          }
483          else {
484            return $(this).find('option').length >= minOptions;
485          }
486        })
487        .once('chosen', function() {
488          options = getElementOptions(this);
489          $(this).chosen(options);
490        });
491    }
492  };
493})(jQuery);
494;
495/**
496* hoverIntent r6 // 2011.02.26 // jQuery 1.5.1+
497* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
498* 
499* @param  f  onMouseOver function || An object with configuration options
500* @param  g  onMouseOut function  || Nothing (use configuration options object)
501* @author    Brian Cherne brian(at)cherne(dot)net
502*/
503(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type=="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.bind('mouseenter',handleHover).bind('mouseleave',handleHover)}})(jQuery);;
504/*
505 * sf-Touchscreen v1.3b - Provides touchscreen compatibility for the jQuery Superfish plugin.
506 *
507 * Developer's note:
508 * Built as a part of the Superfish project for Drupal (http://drupal.org/project/superfish)
509 * Found any bug? have any cool ideas? contact me right away! http://drupal.org/user/619294/contact
510 *
511 * jQuery version: 1.3.x or higher.
512 *
513 * Dual licensed under the MIT and GPL licenses:
514 *  http://www.opensource.org/licenses/mit-license.php
515 *  http://www.gnu.org/licenses/gpl.html
516 */
517
518(function($){
519  $.fn.sftouchscreen = function(options){
520    options = $.extend({
521      mode: 'inactive',
522      breakpoint: 768,
523      breakpointUnit: 'px',
524      useragent: '',
525      behaviour: 2,
526      disableHover: false
527    }, options);
528
529    function activate(menu){
530      var eventHandler = (('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) ? ['click touchstart','mouseup touchend'] : ['click','mouseup'];
531      // Select hyperlinks from parent menu items.
532      menu.find('li:has(ul)').children('a,span.nolink').each(function(){
533        var item = $(this),
534        parent = item.closest('li');
535        if (options.disableHover){
536          parent.unbind('mouseenter mouseleave');
537        }
538        if (options.behaviour == 2){
539          if (parent.children('a.menuparent,span.nolink.menuparent').length > 0 && parent.children('ul').children('.sf-clone-parent').length == 0){
540            var
541            // Cloning the hyperlink of the parent menu item.
542            cloneLink = parent.children('a.menuparent,span.nolink.menuparent').clone(),
543            // Wrapping the hyerplinks in <li>.
544            cloneLink = $('<li class="sf-clone-parent" />').html(cloneLink);
545            // Removing unnecessary stuff.
546            cloneLink.find('.sf-sub-indicator').remove(),
547            // Adding a helper class and attaching them to the sub-menus.
548            parent.children('ul').addClass('sf-has-clone-parent').prepend(clone
548Link);
549          }
550        }
551        // No .toggle() here as it's not possible to reset it.
552        item.bind(eventHandler[0], function(event){
553          // Already clicked?
554          if (item.hasClass('sf-clicked')){
555            // Depending on the preferred behaviour, either proceed to the URL.
556            if (options.behaviour == 0){
557              window.location = item.attr('href');
558            }
559            // or collapse the sub-menu.
560            else if (options.behaviour == 1 || options.behaviour == 2){
561              event.preventDefault();
562              item.removeClass('sf-clicked');
563              parent.hideSuperfishUl().find('a,span.nolink').removeClass('sf-clicked');
564            }
565          }
566          // Prevent the default action otherwise.
567          else {
568            event.preventDefault();
569            item.addClass('sf-clicked');
570            parent.showSuperfishUl().siblings('li:has(ul)').hideSuperfishUl().find('.sf-clicked').removeClass('sf-clicked');
571          }
572        });
573      });
574
575      $(document).bind(eventHandler[1], function(event){
576        if (menu.not(event.target) && menu.has(event.target).length === 0){
577          menu.find('.sf-clicked').removeClass('sf-clicked');
578          menu.find('li:has(ul)').hideSuperfishUl();
579        }
580      });
581    }
582    // Return original object to support chaining.
583    // This is not necessary actually because of the way the module uses these plugins.
584    for (var b = 0; b < this.length; b++) {
585      var menu = $(this).eq(b),
586      mode = options.mode;
587      // The rest is crystal clear, isn't it? :)
588      if (mode == 'always_active'){
589        activate(menu);
590      }
591      else if (mode == 'window_width'){
592        var breakpoint = (options.breakpointUnit == 'em') ? (options.breakpoint * parseFloat($('body').css('font-size'))) : options.breakpoint,
593        windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
594        timer;
595        if ((typeof Modernizr.mq === 'function' && Modernizr.mq('(max-width:' + (breakpoint - 1) + 'px)')) || (typeof Modernizr.mq === 'undefined' && windowWidth < breakpoint)){
596          activate(menu);
597        }
598        $(window).resize(function(){
599          clearTimeout(timer);
600          timer = setTimeout(function(){
601            var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
602            if ((typeof Modernizr.mq === 'function' && Modernizr.mq('(max-width:' + (breakpoint - 1) + 'px)')) || (typeof Modernizr.mq === 'undefined' && windowWidth < breakpoint)){
603              activate(menu);
604            }
605          }, 50);
606        });
607      }
608      else if (mode == 'useragent_custom'){
609        if (options.useragent != ''){
610          var ua = RegExp(options.useragent, 'i');
611          if (navigator.userAgent.match(ua)){
612            activate(menu);
613          }
614        }
615      }
616      else if (mode == 'useragent_predefined' && navigator.userAgent.match(/(android|bb\d+|meego)|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i)){
617        activate(menu);
618      }
619    }
620    return this;
621  }
622})(jQuery);;
623/*
624 * sf-Smallscreen v1.2b - Provides small-screen compatibility for the jQuery Superfish plugin.
625 *
626 * Developer's note:
627 * Built as a part of the Superfish project for Drupal (http://drupal.org/project/superfish)
628 * Found any bug? have any cool ideas? contact me right away! http://drupal.org/user/619294/contact
629 *
630 * jQuery version: 1.3.x or higher.
631 *
632 * Dual licensed under the MIT and GPL licenses:
633 *  http://www.opensource.org/licenses/mit-license.php
634 *  http://www.gnu.org/licenses/gpl.html
635  */
636
637(function($){
638  $.fn.sfsmallscreen = function(options){
639    options = $.extend({
640      mode: 'inactive',
641      type: 'accordion',
642      breakpoint: 768,
643      breakpointUnit: 'px',
644      useragent: '',
645      title: '',
646      addSelected: false,
647      menuClasses: false,
648      hyperlinkClasses: false,
649      excludeClass_menu: '',
650      excludeClass_hyperlink: '',
651      includeClass_menu: '',
652      includeClass_hyperlink: '',
653      accordionButton: 1,
654      expandText: 'Expand',
655      collapseText: 'Collapse'
656    }, options);
657
658    // We need to clean up the menu from anything unnecessary.
659    function refine(menu){
660      var
661      refined = menu.clone(),
662      // Things that should not be in the small-screen menus.
663      rm = refined.find('span.sf-sub-indicator, span.sf-description'),
664      // This is a helper class for those who need to add extra markup that shouldn't exist
665      // in the small-screen versions.
666      rh = refined.find('.sf-smallscreen-remove'),
667      // Mega-menus has to be removed too.
668      mm = refined.find('ul.sf-megamenu');
669      for (var a = 0; a < rh.length; a++){
670        rh.eq(a).replaceWith(rh.eq(a).html());
671      }
672      for (var b = 0; b < rm.length; b++){
673        rm.eq(b).remove();
674      }
675      if (mm.length > 0){
676        mm.removeClass('sf-megamenu');
677        var ol = refined.find('div.sf-megamenu-column > ol');
678        for (var o = 0; o < ol.length; o++){
679          ol.eq(o).replaceWith('<ul>' + ol.eq(o).html() + '</ul>');
680        }
681        var elements = ['div.sf-megamenu-column','.sf-megamenu-wrapper > ol','li.sf-megamenu-wrapper'];
682        for (var i = 0; i < elements.length; i++){
683          obj = refined.find(elements[i]);
684          for (var t = 0; t < obj.length; t++){
685            obj.eq(t).replaceWith(obj.eq(t).html());
686          }
687        }
688        refined.find('.sf-megamenu-column').removeClass('sf-megamenu-column');
689      }
690      refined.add(refined.find('*')).css({width:''});
691      return refined;
692    }
693
694    // Creating <option> elements out of the menu.
695    function toSelect(menu, level){
696      var
697      items = '',
698      childLI = $(menu).children('li');
699      for (var a = 0; a < childLI.length; a++){
700        var list = childLI.eq(a), parent = list.children('a, span');
701        for (var b = 0; b < parent.length; b++){
702          var
703          item = parent.eq(b),
704          path = item.is('a') ? item.attr('href') : '',
705          // Class names modification.
706          itemClone = item.clone(),
707          classes = (options.hyperlinkClasses) ? ((options.excludeClass_hyperlink && itemClone.hasClass(options.excludeClass_hyperlink)) ? itemClone.removeClass(options.excludeClass_hyperlink).attr('class') : itemClone.attr('class')) : '',
708          classes = (options.includeClass_hyperlink && !itemClone.hasClass(options.includeClass_hyperlink)) ? ((options.hyperlinkClasses) ? itemClone.addClass(options.includeClass_hyperlink).attr('class') : options.includeClass_hyperlink) : classes;
709          // Retaining the active class if requested.
710          if (options.addSelected && item.hasClass('active')){
711            classes += ' active';
712          }
713          // <option> has to be disabled if the item is not a link.
714          disable = item.is('span') || item.attr('href')=='#' ? ' disabled="disabled"' : '',
715          // Crystal clear.
716          subIndicator = 1 < level ? Array(level).join('-') + ' ' : '';
717          // Preparing the <option> element.
718          items += '<option value="' + path + '" class="' + classes + '"' + disable + '>' + subIndicator + $.trim(item.text()) +'</option>',
719          childUL = list.find('> ul');
720          // Using the function for the sub-menu of this item.
721          for (var u = 0; u < childUL.length; u++){
722            items += toSelect(childUL.eq(u), level + 1);
723          }
724        }
725      }
726      return items;
727    }
728
729    // Create the new version, hide the original.
730    function convert(menu){
731      var menuID = menu.attr('id'),
732      // Creating a refined version of the menu.
733      refinedMenu = refine(menu);
734      // Currently the plugin provides two reactions to small screens.
735      // Converting the menu to a <select>
735 element, and converting to an accordion version of the menu.
736      if (options.type == 'accordion'){
737        var
738        toggleID = menuID + '-toggle',
739        accordionID = menuID + '-accordion';
740        // Making sure the accordion does not exist.
741        if ($('#' + accordionID).length == 0){
742          var
743          // Getting the style class.
744          styleClass = menu.attr('class').split(' ').filter(function(item){
745            return item.indexOf('sf-style-') > -1 ? item : '';
746          }),
747          // Creating the accordion.
748          accordion = $(refinedMenu).attr('id', accordionID);
749          // Removing unnecessary classes.
750          accordion.removeClass('sf-horizontal sf-vertical sf-navbar sf-shadow sf-js-enabled');
751          // Adding necessary classes.
752          accordion.addClass('sf-accordion sf-hidden');
753          // Removing style attributes and any unnecessary class.
754          accordion.children('li').removeAttr('style').removeClass('sfHover');
755          // Doing the same and making sure all the sub-menus are off-screen (hidden).
756          accordion.find('ul').removeAttr('style').not('.sf-hidden').addClass('sf-hidden');
757          // Creating the accordion toggle switch.
758          var toggle = '<div class="sf-accordion-toggle ' + styleClass + '"><a href="#" id="' + toggleID + '"><span>' + options.title + '</span></a></div>';
759
760          // Adding Expand\Collapse buttons if requested.
761          if (options.accordionButton == 2){
762            var parent = accordion.find('li.menuparent');
763            for (var i = 0; i < parent.length; i++){
764              parent.eq(i).prepend('<a href="#" class="sf-accordion-button">' + options.expandText + '</a>');
765            }
766          }
767          // Inserting the according and hiding the original menu.
768          menu.before(toggle).before(accordion).hide();
769
770          var
771          accordionElement = $('#' + accordionID),
772          // Deciding what should be used as accordion buttons.
773          buttonElement = (options.accordionButton < 2) ? 'a.menuparent,span.nolink.menuparent' : 'a.sf-accordion-button',
774          button = accordionElement.find(buttonElement);
775
776          // Attaching a click event to the toggle switch.
777          $('#' + toggleID).bind('click', function(e){
778            // Preventing the click.
779            e.preventDefault();
780            // Adding the sf-expanded class.
781            $(this).toggleClass('sf-expanded');
782
783            if (accordionElement.hasClass('sf-expanded')){
784              // If the accordion is already expanded:
785              // Hiding its expanded sub-menus and then the accordion itself as well.
786              accordionElement.add(accordionElement.find('li.sf-expanded')).removeClass('sf-expanded')
787              .end().find('ul').hide()
788              // This is a bit tricky, it's the same trick that has been in use in the main plugin for sometime.
789              // Basically we'll add a class that keeps the sub-menu off-screen and still visible,
790              // and make it invisible and removing the class one moment before showing or hiding it.
791              // This helps screen reader software access all the menu items.
792              .end().hide().addClass('sf-hidden').show();
793              // Changing the caption of any existing accordion buttons to 'Expand'.
794              if (options.accordionButton == 2){
795                accordionElement.find('a.sf-accordion-button').text(options.expandText);
796              }
797            }
798            else {
799              // But if it's collapsed,
800              accordionElement.addClass('sf-expanded').hide().removeClass('sf-hidden').show();
801            }
802          });
803
804          // Attaching a click event to the buttons.
805          button.bind('click', function(e){
806            // Making sure the buttons does not exist already.
807            if ($(this).closest('li').children('ul').length > 0){
808              e.preventDefault();
809              // Selecting the parent menu items.
810              var parent = $(this).closest('li');
811              // Creating and inserting Expand\Collapse buttons to the parent menu items,
812              // of course only if not already happened.
813              if (options.accordionButton == 1 && parent.children('a.menuparent,span.nolink.menuparent').length > 0 && parent.children('ul').children('li.sf-clone-parent').length == 0){
814                var
815                // Cloning the hyperlink of the parent menu item.
816                cloneLink = parent.children('a.menuparent,span.nolink.menuparent').clone(),
817                // Wrapping the hyerplinks in <li>.
818                cloneLink = $('<li class="sf-clone-parent" />').html(cloneLink);
819                // Adding a helper class and attaching them to the sub-menus.
820                parent.children('ul').addClass('sf-has-clone-parent').prepend(cloneLink);
821              }
822              // Once the button is clicked, collapse the sub-menu if it's expanded.
823              if (parent.hasClass('sf-expanded')){
824                parent.children('ul').slideUp('fast', function(){
825                  // Doing the accessibility trick after hiding the sub-menu.
826                  $(this).closest('li').removeClass('sf-expanded').end().addClass('sf-hidden').show();
827                });
828                // Changing the caption of the inserted Collapse link to 'Expand', if any is inserted.
829                if (options.accordionButton == 2 && parent.children('.sf-accordion-button').length > 0){
830                  parent.children('.sf-accordion-button').text(options.expandText);
831                }
832              }
833              // Otherwise, expand the sub-menu.
834              else {
835                // Doing the accessibility trick and then showing the sub-menu.
836                parent.children('ul').hide().removeClass('sf-hidden').slideDown('fast')
837                // Changing the caption of the inserted Expand link to 'Collape', if any is inserted.
838                .end().addClass('sf-expanded').children('a.sf-accordion-button').text(options.collapseText)
839                // Hiding any expanded sub-menu of the same level.
840                .end().siblings('li.sf-expanded').children('ul')
841                .slideUp('fast', function(){
842                  // Doing the accessibility trick after hiding it.
843                  $(this).closest('li').removeClass('sf-expanded').end().addClass('sf-hidden').show();
844                })
845                // Assuming Expand\Collapse buttons do exist, resetting captions, in those hidden sub-menus.
846                .parent().children('a.sf-accordion-button').text(options.expandText);
847              }
848            }
849          });
850        }
851      }
852      else {
853        var
854        // Class names modification.
855        menuClone = menu.clone(), classes = (options.menuClasses) ? ((options.excludeClass_menu && menuClone.hasClass(options.excludeClass_menu)) ? menuClone.removeClass(options.excludeClass_menu).attr('class') : menuClone.attr('class')) : '',
856        classes = (options.includeClass_menu && !menuClone.hasClass(options.includeClass_menu)) ? ((options.menuClasses) ? menuClone.addClass(options.includeClass_menu).attr('class') : options.includeClass_menu) : classes,
857        classes = (classes) ? ' class="' + classes + '"' : '';
858
859        // Making sure the <select> element does not exist already.
860        if ($('#' + menuID + '-select').length == 0){
861          // Creating the <option> elements.
862          var newMenu = toSelect(refinedMenu, 1),
863          // Creating the <select> element and assigning an ID and class name.
864          selectList = $('<select class="' + classes + '" id="' + menuID + '-select"/>')
865          // Attaching the title and the items to the <select> element.
866          .html('<option>' + options.title + '</option>' + newMenu)
867          // Attaching an event then.
868          .change(function(){
869            // Except for the first option that is the menu title and not a real menu item.
870            if ($('option:selected', this).index()){
871              window.location = selectList.val();
872            }
873          });
874          // Applying the addSelected option to it.
875          if (options.addSelected){
876            selectList.find('.active').attr('selected', !0);
877          }
878          // Finally inserting the <select> element into the document then hiding the original menu.
879          menu.before(selectList).hide();
880        }
881      }
882    }
883
884    // Turn everything back to normal.
885    function turnBack(menu){
886      var
887      id = '#' + menu.attr('id');
888      // Removing the small screen version.
889      $(id + '-' + options.type).remove();
890      // Removing the accordion toggle switch as well.
891      if (options.type == 'accordion'){
892        $(id + '-toggle').parent('div').remove();
893      }
894      // Crystal clear!
895      $(id).show();
896    }
897
898    // Return original object to support chaining.
899    // Although this is unnecessary because of the way the module uses these plugins.
900    for (var s = 0; s < this.length; s++){
901      var
902      menu = $(this).eq(s),
903      mode = options.mode;
904      // The rest is crystal clear, isn't it? :)
905      if (mode == 'always_active'){
906        convert(menu);
907      }
908      else if (mode == 'window_width'){
909        var breakpoint = (options.breakpointUnit == 'em') ? (options.breakpoint * parseFloat($('body').css('font-size'))) : options.breakpoint,
910        windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
911        timer;
912        if ((typeof Modernizr.mq === 'function' && Modernizr.mq('(max-width:' + (breakpoint - 1) + 'px)')) || (typeof Modernizr.mq === 'undefined' && windowWidth < breakpoint)){
913          convert(menu);
914        }
915        $(window).resize(function(){
916          clearTimeout(timer);
917          timer = setTimeout(function(){
918            var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
919            if ((typeof Modernizr.mq === 'function' && Modernizr.mq('(max-width:' + (breakpoint - 1) + 'px)')) || (typeof Modernizr.mq === 'undefined' && windowWidth < breakpoint)){
920              convert(menu);
921            }
922            else {
923              turnBack(menu);
924            }
925          }, 50);
926        });
927      }
928      else if (mode == 'useragent_custom'){
929        if (options.useragent != ''){
930          var ua = RegExp(options.useragent, 'i');
931          if (navigator.userAgent.match(ua)){
932            convert(menu);
933          }
934        }
935      }
936      else if (mode == 'useragent_predefined' && navigator.userAgent.match(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i)){
937        convert(menu);
938      }
939    }
940    return this;
941  }
942})(jQuery);
943;
944/*
945 * Supposition v0.2 - an optional enhancer for Superfish jQuery menu widget.
946 *
947 * Copyright (c) 2008 Joel Birch - based mostly on work by Jesse Klaasse and credit goes largely to him.
948 * Special thanks to Karl Swedberg for valuable input.
949 *
950 * Dual licensed under the MIT and GPL licenses:
951 *  http://www.opensource.org/licenses/mit-license.php
952 *  http://www.gnu.org/licenses/gpl.html
953 */
954/*
955 * This is not the original jQuery Supposition plugin.
956 * Please refer to the README for more information.
957 */
958
959(function($){
960  $.fn.supposition = function(){
961    var $w = $(window), /*do this once instead of every onBeforeShow call*/
962    _offset = function(dir) {
963      return window[dir == 'y' ? 'pageYOffset' : 'pageXOffset']
964      || document.documentElement && document.documentElement[dir=='y' ? 'scrollTop' : 'scrollLeft']
965      || document.body[dir=='y' ? 'scrollTop' : 'scrollLeft'];
966    },
967    onHide = function(){
968      this.css({bottom:''});
969    },
970    onBeforeShow = function(){
971      this.each(function(){
972        var $u = $(this);
973        $u.css('display','block');
974        var $mul = $u.closest('.sf-menu'),
975        level = $u.parents('ul').length,
976        menuWidth = $u.width(),
977        menuParentWidth = $u.closest('li').outerWidth(true),
978        menuParentLeft = $u.closest('li').offset().left,
979        totalRight = $w.width() + _offset('x'),
980        menuRight = $u.offset().left + menuWidth,
981        exactMenuWidth = (menuRight > (menuParentWidth + menuParentLeft)) ? menuWidth - (menuRight - (menuParentWidth + menuParentLeft)) : menuWidth;
982        if ($u.parents('.sf-js-enabled').hasClass('rtl')) {
983          if (menuParentLeft < exactMenuWidth) {
984            if (($mul.hasClass('sf-horizontal') && level == 1) || ($mul.hasClass('sf-navbar') && level == 2)){
985              $u.css({left:0,right:'auto'});
986            }
987            else {
988              $u.css({left:menuParentWidth + 'px',right:'auto'});
989            }
990          }
991        }
992        else {
993          if (menuRight > totalRight && menuParentLeft > menuWidth) {
994            if (($mul.hasClass('sf-horizontal') && level == 1) || ($mul.hasClass('sf-navbar') && level == 2)){
995              $u.css({right:0,left:'auto'});
996            }
997            else {
998              $u.css({right:menuParentWidth + 'px',left:'auto'});
999            }
1000          }
1001        }
1002        var windowHeight = $w.height(),
1003        offsetTop = $u.offset().top,
1004        menuParentShadow = ($mul.hasClass('sf-shadow') && $u.css('padding-bottom').length > 0) ? parseInt($u.css('padding-bottom').slice(0,-2)) : 0,
1005        menuParentHeight = ($mul.hasClass('sf-vertical')) ? '-' + menuParentShadow : $u.parent().outerHeight(true) - menuParentShadow,
1006        menuHeight = $u.height(),
1007        baseline = windowHeight + _offset('y');
1008        var expandUp = ((offsetTop + menuHeight > baseline) && (offsetTop > menuHeight));
1009        if (expandUp) {
1010          $u.css({bottom:menuParentHeight + 'px',top:'auto'});
1011        }
1012        $u.css('display','none');
1013      });
1014    };
1015
1016    return this.each(function() {
1017      var o = $.fn.superfish.o[this.serial]; /* get this menu's options */
1018
1019      /* if callbacks already set, store them */
1020      var _onBeforeShow = o.onBeforeShow,
1021      _onHide = o.onHide;
1022
1023      $.extend($.fn.superfish.o[this.serial],{
1024        onBeforeShow: function() {
1025          onBeforeShow.call(this); /* fire our Supposition callback */
1026          _onBeforeShow.call(this); /* fire stored callbacks */
1027        },
1028        onHide: function() {
1029          onHide.call(this); /* fire our Supposition callback */
1030          _onHide.call(this); /* fire stored callbacks */
1031        }
1032      });
1033    });
1034  };
1035})(jQuery);;
1036/*
1037 * Superfish v1.4.8 - jQuery menu widget
1038 * Copyright (c) 2008 Joel Birch
1039 *
1040 * Dual licensed under the MIT and GPL licenses:
1041 *  http://www.opensource.org/licenses/mit-license.php
1042 *  http://www.gnu.org/licenses/gpl.html
1043 *
1044 * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
1045 */
1046/*
1047 * This is not the original jQuery Superfish plugin.
1048 * Please refer to the README for more information.
1049 */
1050
1051(function($){
1052  $.fn.superfish = function(op){
1053    var sf = $.fn.superfish,
1054      c = sf.c,
1055      $arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
1056      over = function(){
1057        var $$ = $(this), menu = getMenu($$);
1058        clearTimeout(menu.sfTimer);
1059        $$.showSuperfishUl().siblings().hideSuperfishUl();
1060      },
1061      out = function(){
1062        var $$ = $(this), menu = getMenu($$), o = sf.op;
1063        clearTimeout(menu.sfTimer);
1064        menu.sfTimer=setTimeout(function(){
1065          if ($$.children('.sf-clicked').length == 0){
1066            o.retainPath=($.inArray($$[0],o.$path)>-1);
1067            $$.hideSuperfishUl();
1068            if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
1069          }
1070        },o.delay);
1071      },
1072      getMenu = function($menu){
1073        var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
1074        sf.op = sf.o[menu.serial];
1075        return menu;
1076      },
1077      addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
1078
1079    return this.each(function() {
1080      var s = this.serial = sf.o.length;
1081      var o = $.extend({},sf.defaults,op);
1082      o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels),
1083      p = o.$path;
1084      for (var l = 0; l < p.length; l++){
1085        p.eq(l).addClass([o.hoverClass,c.bcClass].join(' ')).filter('li:has(ul)').removeClass(o.pathClass);
1086      }
1087      sf.o[s] = sf.op = o;
1088
1089      $('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
1090        if (o.autoArrows) addArrow( $(this).children('a:first-child, span.nolink:first-child') );
1091      })
1092      .not('.'+c.bcClass)
1093        .hideSuperfishUl();
1094
1095      var $a = $('a, span.nolink',this);
1096      $a.each(function(i){
1097        var $li = $a.eq(i).parents('li');
1098        $a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
1099      });
1100      o.onInit.call(this);
1101
1102    }).each(function() {
1103      var menuClasses = [c.menuClass],
1104      addShadow = true;
1105      if ($.browser !== undefined){
1106        if ($.browser.msie && $.browser.version < 7){
1107          addShadow = false;
1108        }
1109      }
1110      if (sf.op.dropShadows && addShadow){
1111        menuClasses.push(c.shadowClass);
1112      }
1113      $(this).addClass(menuClasses.join(' '));
1114    });
1115  };
1116
1117  var sf = $.fn.superfish;
1118  sf.o = [];
1119  sf.op = {};
1120  sf.IE7fix = function(){
1121    var o = sf.op;
1122    if ($.browser !== undefined){
1123      if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity != undefined) {
1124        this.toggleClass(sf.c.shadowClass+'-off');
1125      }
1126    }
1127  };
1128  sf.c = {
1129    bcClass: 'sf-breadcrumb',
1130    menuClass: 'sf-js-enabled',
1131    anchorClass: 'sf-with-ul',
1132    arrowClass: 'sf-sub-indicator',
1133    shadowClass: 'sf-shadow'
1134  };
1135  sf.defaults = {
1136    hoverClass: 'sfHover',
1137    pathClass: 'overideThisToUse',
1138    pathLevels: 1,
1139    delay: 800,
1140    animation: {opacity:'show'},
1141    speed: 'fast',
1142    autoArrows: true,
1143    dropShadows: true,
1144    disableHI: false, // true disables hoverIntent detection
1145    onInit: function(){}, // callback functions
1146    onBeforeShow: function(){},
1147    onShow: function(){},
1148    onHide: function(){}
1149  };
1150  $.fn.extend({
1151    hideSuperfishUl : function(){
1152      var o = sf.op,
1153        not = (o.retainPath===true) ? o.$path : '';
1154      o.retainPath = false;
1155      var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
1156          .children('ul').addClass('sf-hidden');
1157      o.onHide.call($ul);
1158      return this;
1159    },
1160    showSuperfishUl : function(){
1161      var o = sf.op,
1162        sh = sf.c.shadowClass+'-off',
1163        $ul = this.addClass(o.hoverClass)
1164          .children('ul.sf-hidden').hide().removeClass('sf-hidden');
1165      sf.IE7fix.call($ul);
1166      o.onBeforeShow.call($ul);
1167      $ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
1168      return this;
1169    }
1170  });
1171})(jQuery);;
1172/*
1173 * Supersubs v0.4b - jQuery plugin
1174 * Copyright (c) 2013 Joel Birch
1175 *
1176 * Dual licensed under the MIT and GPL licenses:
1177 *  http://www.opensource.org/licenses/mit-license.php
1178 *  http://www.gnu.org/licenses/gpl.html
1179 *
1180 * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
1181 * their longest list item children. If you use this, please expect bugs and report them
1182 * to the jQuery Google Group with the word 'Superfish' in the subject line.
1183 *
1184 */
1185/*
1186 * This is not the original jQuery Supersubs plugin.
1187 * Please refer to the README for more information.
1188 */
1189
1190(function($){ // $ will refer to jQuery within this closure
1191  $.fn.supersubs = function(options){
1192    var opts = $.extend({}, $.fn.supersubs.defaults, options);
1193    // return original object to support chaining
1194    // Although this is unnecessary due to the way the module uses these plugins.
1195    for (var a = 0; a < this.length; a++) {
1196      // cache selections
1197      var $$ = $(this).eq(a),
1198      // support metadata
1199      o = $.meta ? $.extend({}, opts, $$.data()) : opts;
1200      // Jump one level if it's a "NavBar"
1201      if ($$.hasClass('sf-navbar')) {
1202        $$ = $$.children('li').children('ul');
1203      }
1204      // cache all ul elements
1205      var $ULs = $$.find('ul'),
1206      // get the font size of menu.
1207      // .css('fontSize') returns various results cross-browser, so measure an em dash instead
1208      fontsize = $('<li id="menu-fontsize">&#8212;</li>'),
1209      size = fontsize.attr('style','padding:0;position:absolute;top:-99999em;width:auto;')
1210      .appendTo($$)[0].clientWidth; //clientWidth is faster than width()
1211      // remove em dash
1212      fontsize.remove();
1213
1214      // loop through each ul in menu
1215      for (var b = 0; b < $ULs.length; b++) {
1216        var
1217        // cache this ul
1218        $ul = $ULs.eq(b);
1219        // If a multi-column sub-menu, and only if correctly configured.
1220        if (o.megamenu && $ul.hasClass('sf-megamenu') && $ul.find('.sf-megamenu-column').length > 0){
1221          // Look through each column.
1222          var $column = $ul.find('div.sf-megamenu-column > ol'),
1223          // Overall width.
1224          mwWidth = 0;
1225          for (var d = 0; d < $column.length; d++){
1226            resize($column.eq(d));
1227            // New column width, in pixels.
1228            var colWidth = $column.width();
1229            // Just a trick to convert em unit to px.
1230            $column.css({width:colWidth})
1231            // Making column parents the same size.
1232            .parents('.sf-megamenu-column').css({width:colWidth});
1233            // Overall width.
1234            mwWidth += parseInt(colWidth);
1235          }
1236          // Resizing the columns container too.
1237          $ul.add($ul.find('li.sf-megamenu-wrapper, li.sf-megamenu-wrapper > ol')).css({width:mwWidth});
1238        }
1239        else {
1240          resize($ul);
1241        }
1242      }
1243    }
1244    function resize($ul){
1245      var
1246      // get all (li) children of this ul
1247      $LIs = $ul.children(),
1248      // get all anchor grand-children
1249      $As = $LIs.children('a');
1250      // force content to one line and save current float property
1251      $LIs.css('white-space','nowrap');
1252      // remove width restrictions and floats so elements remain vertically stacked
1253      $ul.add($LIs).add($As).css({float:'none',width:'auto'});
1254      // this ul will now be shrink-wrapped to longest li due to position:absolute
1255      // so save its width as ems.
1256      var emWidth = $ul.get(0).clientWidth / size;
1257      // add more width to ensure lines don't turn over at certain sizes in various browsers
1258      emWidth += o.extraWidth;
1259      // restrict to at least minWidth and at most maxWidth
1260      if (emWidth > o.maxWidth) {emWidth = o.maxWidth;}
1261      else if (emWidth < o.minWidth) {emWidth = o.minWidth;}
1262      emWidth += 'em';
1263      // set ul to width in ems
1264      $ul.css({width:emWidth});
1265      // restore li floats to avoid IE bugs
1266      // set li width to full width of this ul
1267      // revert white-space to normal
1268      $LIs.add($As).css({float:'',width:'',whiteSpace:''});
1269      // update offset position of descendant ul to reflect new width of parent.
1270      // set it to 100% in case it isn't already set to this in the CSS
1271      for (var c = 0; c < $LIs.length; c++) {
1272        var $childUl = $LIs.eq(c).children('ul');
1273        var offsetDirection = $childUl.css('left') !== undefined ? 'left' : 'right';
1274        $childUl.css(offsetDirection,'100%');
1275      }
1276    }
1277    return this;
1278  };
1279  // expose defaults
1280  $.fn.supersubs.defaults = {
1281    megamenu: true, // define width for multi-column sub-menus and their columns.
1282    minWidth: 12, // requires em unit.
1283    maxWidth: 27, // requires em unit.
1284    extraWidth: 1 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
1285  };
1286})(jQuery); // plugin code ends
1287;
1288/**
1289 * @file
1290 * The Superfish Drupal Behavior to apply the Superfish jQuery plugin to lists.
1291 */
1292
1293(function ($) {
1294  Drupal.behaviors.superfish = {
1295    attach: function (context, settings) {
1296      // Take a look at each list to apply Superfish to.
1297      $.each(settings.superfish || {}, function(index, options) {
1298        // Process all Superfish lists.
1299        $('#superfish-' + options.id, context).once('superfish', function() {
1300          var list = $(this);
1301
1302          // Check if we are to apply the Supersubs plug-in to it.
1303          if (options.plugins || false) {
1304            if (options.plugins.supersubs || false) {
1305              list.supersubs(options.plugins.supersubs);
1306            }
1307          }
1308
1309          // Apply Superfish to the list.
1310          list.superfish(options.sf);
1311
1312          // Check if we are to apply any other plug-in to it.
1313          if (options.plugins || false) {
1314            if (options.plugins.touchscreen || false) {
1315              list.sftouchscreen(options.plugins.touchscreen);
1316            }
1317            if (options.plugins.smallscreen || false) {
1318              list.sfsmallscreen(options.plugins.smallscreen);
1319            }
1320            if (options.plugins.automaticwidth || false) {
1321              list.sfautomaticwidth();
1322            }
1323            if (options.plugins.supposition || false) {
1324              list.supposition();
1325            }
1326            if (options.plugins.bgiframe || false) {
1327              list.find('ul').bgIframe({opacity:false});
1328            }
1329          }
1330        });
1331      });
1332    }
1333  };
1334})(jQuery);;

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.