PageSourceSearch

https://forward-am.com/wp-content/themes/uncode/library/js/lib/jquery.smartmenus.js?ver=24322628

js forward-am.com collected 2026-09-24 19:36:45 UTC 45,082 bytes, 1,136 lines download raw bytes

1/*
2 * SmartMenus jQuery v0.9.6
3 * http://www.smartmenus.org/
4 *
5 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
6 * http://vadikom.com/
7 *
8 * Released under the MIT license:
9 * http://www.opensource.org/licenses/MIT
10 */
11
12(function($) {
13
14	var menuTrees = [],
15		IE = !!window.createPopup, // we need to detect it, unfortunately
16		IElt9 = IE && !document.defaultView,
17		IElt8 = IE && !document.querySelector,
18		IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined',
19		mouse = false, // optimize for touch by default - we will detect for mouse input
20		mouseDetectionEnabled = false;
21
22	// Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.)
23	function initMouseDetection(disable) {
24		if (!mouseDetectionEnabled && !disable) {
25			// if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present
26			// in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events)
27			var firstTime = true,
28				lastMove = null;
29			$(document).bind({
30				'mousemove.smartmenus_mouse': function(e) {
31					var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() };
32					if (lastMove) {
33						var deltaX = Math.abs(lastMove.x - thisMove.x),
34							deltaY = Math.abs(lastMove.y - thisMove.y);
35	 					if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) {
36							mouse = true;
37							// if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes
38							if (firstTime) {
39								var $a = $(e.target).closest('a');
40								if ($a.is('a')) {
41									$.each(menuTrees, function() {
42										if ($.contains(this.$root[0], $a[0])) {
43											this.itemEnter({ currentTarget: $a[0] });
44											return false;
45										}
46									});
47								}
48								firstTime = false;
49							}
50						}
51					}
52					lastMove = thisMove;
53				},
54				'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) {
55					if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) {
56						mouse = false;
57					}
58				}
59			});
60			mouseDetectionEnabled = true;
61		} else if (mouseDetectionEnabled && disable) {
62			$(document).unbind('.smartmenus_mouse');
63			mouseDetectionEnabled = false;
64		}
65	};
66
67	$.SmartMenus = function(elm, options) {
68		this.$root = $(elm);
69		this.opts = options;
70		this.rootId = ''; // internal
71		this.$subArrow = null;
72		this.subMenus = []; // all sub menus in the tree (UL elms) in no particular order (only real - e.g. UL's in mega sub menus won't be counted)
73		this.activatedItems = []; // stores last activated A's for each level
74		this.visibleSubMenus = []; // stores visible sub menus UL's
75		this.showTimeout = 0;
76		this.hideTimeout = 0;
77		this.scrollTimeout = 0;
78		this.clickActivated = false;
79		this.zIndexInc = 0;
80		this.$firstLink = null; // we'll use these for some tests
81		this.$firstSub = null; // at runtime so we'll cache them
82		this.disabled = false;
83		this.$disableOverlay = null;
84		this.init();
85	};
86
87	$.extend($.SmartMenus, {
88		hideAll: function() {
89			$.each(menuTrees, function() {
90				this.menuHideAll();
91			});
92		},
93		destroy: function() {
94			while (menuTrees.length) {
95				menuTrees[0].destroy();
96			}
97			initMouseDetection(true);
98		},
99		prototype: {
100			init: function(refresh) {
101				var self = this;
102
103				if (!refresh) {
104					menuTrees.push(this);
105
106					this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, '');
107
108					if (this.$root.hasClass('sm-rtl')) {
109						this.opts.rightToLeftSubMenus = true;
110					}
111
112					// init root (main menu)
113					this.$root
114						.data('smartmenus', this)
115						.attr('data-smartmenus-id', this.rootId)
116						.dataSM('level', 1)
117						.bind({
118							'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
119							'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this)
120						})
121						.delegate('a, div.logo-container', {
122							'mouseenter.smartmenus': $.proxy(this.itemEnter, this),
123							'mouseleave.smartmenus': $.proxy(this.itemLeave, this),
124							'mousedown.smartmenus': $.proxy(this.itemDown, this),
125							'focus.smartmenus': $.proxy(this.itemFocus, this),
126							'blur.smartmenus': $.proxy(this.itemBlur, this),
127							'click.smartmenus': $.proxy(this.itemClick, this),
128							'touchend.smartmenus': $.proxy(this.itemTouchEnd, this)
129						});
130
131					var eNamespace = '.smartmenus' + this.rootId;
132					// hide menus on tap or click outside the root UL
133					if (this.opts.hideOnClick) {
134							$(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this))
135								.on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this))
136								.on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this))
137								// for Opera Mobile < 11.5, webOS browser, etc. we'll check click too
138								.on('click' + eNamespace, $.proxy(this.docClick, this));
139					}
140					// hide sub menus on resize
141					$(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
142					var $vmenu = $('body.vmenu .vmenu-container');
143					if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) {
144						$(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
145					}
146
147					if (this.opts.subIndicators) {
148						this.$subArrow = $('<span/>').addClass('sub-arrow');
149						if (this.opts.subIndicatorsText) {
150							this.$subArrow.html(this.opts.subIndicatorsText);
151						}
152					}
153
154					// make sure mouse detection is enabled
155					initMouseDetection();
156				}
157
158				// init sub menus
159				this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0);
160
161				this.$firstLink = this.$root.find('a').eq(0);
162
163				// find current item
164				if (this.opts.markCurrentItem) {
165					var reDefaultDoc = /(index|default)\.[^#\?\/]*/i,
166						reHash = /#.*/,
167						locHref = window.location.href.replace(reDefaultDoc, ''),
168						locHrefNoHash = locHref.replace(reHash, '');
169					this.$root.find('a').each(function() {
170						var href = this.href.replace(reDefaultDoc, ''),
171							$this = $(this);
172						if (href == locHref || href == locHrefNoHash) {
173							$this.addClass('current');
174							if (self.opts.markCurrentTree) {
175								$this.parents('li').each(function() {
176									var $this = $(this);
177									if ($this.dataSM('sub')) {
178										$this.children('a').addClass('current');
179									}
180								});
181							}
182						}
183					});
184				}
185			},
186			destroy: function() {
187				this.menuHideAll();
188				this.$root
189					.removeData('smartmenus')
190					.removeAttr('data-smartmenus-id')
191					.removeDataSM('level')
192					.unbind('.smartmenus')
193					.undelegate('.smartmenus');
194				var eNamespace = '.smartmenus' + this.rootId;
195				$(document).unbind(eNamespace);
196				$(window).unbind(eNamespace);
197				if (this.opts.subIndicators) {
198					this.$subArrow = null;
199				}
200				var self = this;
201				$.each(this.subMenus, function() {
202					if (this.hasClass('mega-menu')) {
203						this.find('ul').removeDataSM('in-mega');
204					}
205					if (this.dataSM('shown-before')) {
206						if (IElt8) {
207							this.children().css({ styleFloat: '', width: '' });
208						}
209						if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) {
210							if (!IE6) {
211								this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap');
212							} else {
213								this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', '');
214							}
215						}
216						if (this.dataSM('scroll-arrows')) {
217							this.dataSM('scroll-arrows').remove();
218						}
219						this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' });
220					}
221					if (self.opts.subIndicators) {
222						this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove();
223					}
224					this.removeDataSM('shown-before')
225						.removeDataSM('ie-shim')
226						.removeDataSM('scroll-arrows')
227						.removeDataSM('parent-a')
228						.removeDataSM('level')
229						.removeDataSM('beforefirstshowfired')
230						.parent().removeDataSM('sub');
231				});
232				if (this.opts.markCurrentItem) {
233					this.$root.find('a.current').removeClass('current');
234				}
235				this.$root = null;
236				this.$firstLink = null;
237				this.$firstSub = null;
238				if (this.$disableOverlay) {
239					this.$disableOverlay.remove();
240					this.$disableOverlay = null;
241				}
242				menuTrees.splice($.inArray(this, menuTrees), 1);
243			},
244			disable: function(noOverlay) {
245				if (!this.disabled) {
246					this.menuHideAll();
247					// display overlay over the menu to prevent interaction
248					if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) {
249						var pos = this.$root.offset();
250						this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({
251							position: 'absolute',
252							top: pos.top,
253							left: pos.left,
254							width: this.$root.outerWidth(),
255							height: this.$root.outerHeight(),
256							zIndex: this.getStartZIndex() + 1,
257							opacity: 0
258						}).appendTo(document.body);
259					}
260					this.disabled = true;
261				}
262			},
263			docClick: function(e) {
264				// hide on any click outside the menu or on a menu link
265				if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) {
266					this.menuHideAll($(e.target));
267				}
268			},
269			docTouchEnd: function(e) {
270				if (!this.lastTouch) {
271					return;
272				}
273				if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) {
274					if (this.hideTimeout) {
275						clearTimeout(this.hideTimeout);
276						this.hideTimeout = 0;
277					}
278					// hide with a delay to prevent triggering accidental unwanted click on some page element
279					var self = this;
280					this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350);
281				}
282				this.lastTouch = null;
283			},
284			docTouchMove: function(e) {
285				if (!this.lastTouch) {
286					return;
287				}
288				var touchPoint = e.originalEvent.touches[0];
289				this.lastTouch.x2 = touchPoint.pageX;
290				this.lastTouch.y2 = touchPoint.pageY;
291			},
292			docTouchStart: function(e) {
293				var touchPoint = e.originalEvent.touches[0];
294				this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target };
295			},
296			enable: function() {
297				if (this.disabled) {
298					if (this.$disableOverlay) {
299						this.$disableOverlay.remove();
300						this.$disableOverlay = null;
301					}
302					this.disabled = false;
303				}
304			},
305			getHeight: function($elm) {
306				return this.getOffset($elm, true);
307			},
308			// returns precise width/height float values in IE9+, FF4+, recent WebKit
309			// http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/
310			getOffset: function($elm, height) {
311				var old,
312					$win = $(window),
313					winW = $win.width();
314				if ($elm.css('display') == 'none') {
315					old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility };
316					$elm.css({ position: 'absolute', visibility: 'hidden' }).show();
317					if ( 
318						($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length)
319						||
320						(( $('body').hasClass('vmenu-offcanvas-overlay') || $('body').hasClass('vmenu') ) && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length)
321					) {
322						$elm.closest('li').addClass('smartmenu-open-item');
323					}
324				}
325				var defaultView = $elm[0].ownerDocument.defaultView,
326					compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null),
327					val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']);
328				if (val) {
329					val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft'])
330	 					+ parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight'])
331	 					+ parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth'])
332	 					+ parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']);
333				} else {
334					val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth;
335				}
336				if (old) {
337					$elm.hide().css(old);
338				}
339				return val;
340			},
341			getWidth: function($elm) {
342				return this.getOffset($elm);
343			},
344			getStartZIndex: function() {
345				var zIndex = parseInt(this.$root.css('z-index'));
346				return !isNaN(zIndex) ? zIndex : 1;
347			},
348			handleEvents: function() {
349				return !this.disabled && this.isCSSOn();
350			},
351			handleItemEvents: function($a) {
352				return this.handleEvents() && !this.isLinkInMegaMenu($a);
353			},
354			isCollapsible: function() {
355				return this.$firstSub.css('position') == 'static';
356			},
357			isCSSOn: function() {
358				return this.$firstLink.css('display') == 'block' || this.$firstLink.css('display') == 'flex' || this.$firstLink.css('display') == 'inline-flex' || this.$firstLink.css('display') == 'table-cell' || this.$firstLink.css('display') == 'inline';
359			},
360			isFixed: function() {
361				return this.$root.css('position') == 'fixed';
362			},
363			isLinkInMegaMenu: function($a) {
364				return !$a.parent().parent().dataSM('level');
365			},
366			isTouchMode: function() {
367				return !mouse || this.isCollapsible();
368			},
369			itemActivate: function($a) {
370				var $li = $a.parent(),
371					$ul = $li.parent(),
372					level = $ul.dataSM('level');
373				// if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first
374				if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) {
375					var self = this;
376					$($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() {
377						self.itemActivate($(this).dataSM('parent-a'));
378					});
379				}
380				// hide any visible deeper level sub menus
381				if (this.visibleSubMenus.length > level) {
382					for (var i = this.visibleSubMenus.length - 1, l = !this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level; i > l; i--) {
383						//if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) {
384							this.menuHide(this.visibleSubMenus[i]);
385						//}
386					}
387				}
388				// save new active item and sub menu for this level
389				this.activatedItems[level - 1] = $a;
390				this.visibleSubMenus[level - 1] = $ul;
391				if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) {
392					return;
393				}
394				// show the sub menu if this item has one
395				var $sub = $li.dataSM('sub');
396				if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) {
397					this.menuShow($sub);
398				}
399			},
400			itemBlur: function(e) {
401				var $a = $(e.currentTarget);
402				if (!this.handleItemEvents($a)) {
403					return;
404				}
405				this.$root.triggerHandler('blur.smapi', $a[0]);
406			},
407			itemClick: function(e) {
408				var $a = $(e.currentTarget);
409
410				if (!this.handleItemEvents($a)) {
411					return;
412				}
413				$a.removeDataSM('mousedown');
414				if (this.$root.triggerHandler('click.smapi', $a[0]) === false) {
415					return false;
416				}
417				var $sub = $a.parent().dataSM('sub');
418				if (this.isTouchMode()) {
419					// undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu
420					if ($a.dataSM('href')) {
421						$a.attr('href', $a.dataSM('href')).removeDataSM('href');
422					}
423					// if the sub is not visible
424					if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
425						// try to activate the item and show the sub
426						this.itemActivate($a);
427						// if "itemActivate" showed the sub, prevent the click so that the link is not loaded
428						// if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded
429						if ($sub.is(':visible')) {
430							return false;
431						}
432					}
433				} else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) {
434					this.clickActivated = true;
435					this.menuShow($sub);
436					return false;
437				}
438				if ($a.hasClass('disabled')) {
439					return false;
440				}
441				if (this.$root.triggerHandler('select.smapi', $a[0]) === false) {
442					return false;
443				}
444			},
445			itemDown: function(e) {
446				var $a = $(e.currentTarget);
447				if (!this.handleItemEvents($a)) {
448					return;
449				}
450				$a.dataSM('mousedown', true);
451			},
452			itemEnter: function(e) {
453				var $a = $(e.currentTarget);
454				if (!this.handleItemEvents($a)) {
455					return;
456				}
457				if (!this.isTouchMode()) {
458					if (this.showTimeout) {
459						clearTimeout(this.showTimeout);
460						this.showTimeout = 0;
461					}
462					var self = this;
463					this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout);
464				}
465				this.$root.triggerHandler('mouseenter.smapi', $a[0]);
466			},
467			itemFocus: function(e) {
468				var $a = $(e.currentTarget);
469				if (!this.handleItemEvents($a)) {
470					return;
471				}
472				// fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus
473				if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) {
474					this.itemActivate($a);
475				}
476				this.$root.triggerHandler('focus.smapi', $a[0]);
477			},
478			itemLeave: function(e) {
479				var $a = $(e.currentTarget);
480				if (!this.handleItemEvents($a)) {
481					return;
482				}
483				if (!this.isTouchMode()) {
484					if ($a[0].blur) {
485						$a[0].blur();
486					}
487					if (this.showTimeout) {
488						clearTimeout(this.showTimeout);
489						this.showTimeout = 0;
490					}
491				}
492				$a.removeDataSM('mousedown');
493				this.$root.triggerHandler('mouseleave.smapi', $a[0]);
494			},
495			itemTouchEnd: function(e) {
496				var $a = $(e.currentTarget);
497				if (!this.handleItemEvents($a)) {
498					return;
499				}
500				// prevent the address bar on iPhone from sliding down when expanding a sub menu
501				var $sub = $a.parent().dataSM('sub');
502				if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
503					$a.dataSM('href', $a.attr('href'));
504					$a.attr('href', '#');
505				}
506			},
507			menuFixLayout: function($ul) {
508				// fixes a menu that is being shown for the first time
509				if (!$ul.dataSM('shown-before')) {
510					$ul.hide().dataSM('shown-before', true);
511					// fix the layout of the items in IE<8
512					if (IElt8) {
513						$ul.children().css({ styleFloat: 'left', width: '100%' });
514					}
515				}
516			},
517			menuHide: function($sub) {
518				if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) {
519					return;
520				}
521				$sub.stop(true, true);
522				if ($sub.is(':visible')) {
523					var complete = function() {
524						// unset z-index
525						if (IElt9) {
526							$sub.parent().css('z-index', '');
527						} else {
528							$sub.css('z-index', '');
529						}
530					};
531					// if sub is collapsible (mobile view)
532					if (this.isCollapsible()) {
533						if (this.opts.collapsibleHideFunction) {
534							this.opts.collapsibleHideFunction.call(this, $sub, complete);
535						} else {
536							$sub.hide(this.opts.collapsibleHideDuration, complete);
537						}
538					} else {
539						if (this.opts.hideFunction) {
540							this.opts.hideFunction.call(this, $sub, complete);
541						} else {
542							$sub.hide(this.opts.hideDuration, complete);
543						}
544					}
545					// remove IE iframe shim
546					if ($sub.dataSM('ie-shim')) {
547						$sub.dataSM('ie-shim').remove();
548					}
549					// deactivate scrolling if it is activated for this sub
550					if ($sub.dataSM('scroll')) {
551						$sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide();
552					}
553					// unhighlight parent item
554					$sub.dataSM('parent-a').removeClass('highlighted');
555					var level = $sub.dataSM('level');
556					this.activatedItems.splice(level - 1, 1);
557					this.visibleSubMenus.splice(level - 1, 1);
558					this.$root.triggerHandler('hide.smapi', $sub[0]);
559				}
560			},
561			menuHideAll: function($item) {
562				if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return;
563				var $win = $(window),
564					winW = $win.width();
565				if (this.showTimeout) {
566					clearTimeout(this.showTimeout);
567					this.showTimeout = 0;
568				}
569				// hide all subs
570				for (var i = this.visibleSubMenus.length - 1; i > 0; i--) {
571					if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) {
572						if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) {
573							this.menuHide(this.visibleSubMenus[i]);
574							$(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item');
575						} else {
576							return;
577						}
578					} else {
579						//if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) {
580							this.menuHide(this.visibleSubMenus[i]);
581						//}
582					}
583				}
584				// hide root if it's popup
585				if (this.opts.isPopup) {
586					this.$root.stop(true, true);
587					if (this.$root.is(':visible')) {
588						if (this.opts.hideFunction) {
589							this.opts.hideFunction.call(this, this.$root);
590						} else {
591							this.$root.hide(this.opts.hideDuration);
592						}
593						// remove IE iframe shim
594						if (this.$root.dataSM('ie-shim')) {
595							this.$root.dataSM('ie-shim').remove();
596						}
597					}
598				}
599				this.activatedItems = [];
600				this.visibleSubMenus = [];
601				this.clickActivated = false;
602				// reset z-index increment
603				this.zIndexInc = 0;
604			},
605			menuIframeShim: function($ul) {
606				// create iframe shim for the menu
607				if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) {
608					$ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 })
609						.css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' })
610					);
611				}
612			},
613			menuInit: function($ul) {
614				if (!$ul.dataSM('in-mega')) {
615					this.subMenus.push($ul);
616					// mark UL's in mega drop downs (if any) so we can neglect them
617					if ($ul.hasClass('mega-menu')) {
618						$ul.find('ul').dataSM('in-mega', true);
619					}
620					// get level (much faster than, for example, using parentsUntil)
621					var level = 2,
622						par = $ul[0];
623					while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) {
624						level++;
625					}
626					// cache stuff
627					$ul.dataSM('parent-a', $ul.prevAll('a').eq(-1))
628						.dataSM('level', level)
629						.parent().dataSM('sub', $ul);
630					// add sub indicator to parent item
631					if (this.opts.subIndicators) {
632						$ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone());
633					}
634				}
635			},
636			menuPosition: function($sub) {
637				var fixIE = $('html.ie').length;
638				// if (fixIE) {
639				// 	var $rowParent = $($sub).closest('.main-menu-container');
640				// 	$rowParent.height($rowParent.height());
641				// }
642				var $a = $sub.dataSM('parent-a'),
643					$li = $sub.parent(),
644					$ul = $sub.parent().parent(),
645					// $container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? ( $('body').hasClass('boxed-width') ? $ul.closest('.row-menu') : $(window) ) : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'),
646					$container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? $ul.closest('.row-menu') : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'),
647					level = $sub.dataSM('level'),
648					subW = this.getWidth($sub),
649					subH = this.getHeight($sub),
650					itemOffset = $a.offset(),
651					itemX = itemOffset.left,
652					itemY = itemOffset.top,
653					itemW = this.getWidth($a),
654					itemH = this.getHeight($a),
655					$win = $(window),
656					winX = $win.scrollLeft(),
657					winY = $win.scrollTop(),
658					winW = $win.width(),
659					winH = $win.height(),
660					containerW = $container.width(),
661					containerOffsetX = containerW + ((winW - containerW) / 2),
662					horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'),
663					subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX,
664					subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY,
665					x, y, leftPos;
666
667				if (horizontalParent) {
668					x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX;
669					y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY;
670				} else {
671					x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX;
672					y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY;
673				}
674				if (this.opts.keepInViewport && !this.isCollapsible()) {
675					if (this.isFixed()) {
676						itemX -= winX;
677						itemY -= winY;
678						winX = winY = 0;
679					}
680					var absX = itemX + x,
681						absY = itemY + y;
682					if (this.opts.rightToLeftSubMenus && absX < winX) {
683						x = horizontalParent ? winX - absX + x : itemW - subOffsetX;
684					} else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) {
685						x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW;
686					}
687					if (!horizontalParent) {
688						if (subH < winH && absY + subH > winY + winH) {
689							y += winY + winH - subH - absY;
690						} else if (subH >= winH || absY < winY) {
691							y += winY - absY;
692						}
693					}
694					// do we need scrolling?
695					// 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH"
696					if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) {
697						var self = this;
698						if (!$sub.dataSM('scroll-arrows')) {
699							$sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]])
700								.bind({
701									mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); },
702									mouseleave: function(e) {
703										self.menuScrollStop($sub);
704										self.menuScrollOut($sub, e);
705									},
706									'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); }
707								})
708								.insertAfter($sub)
709							);
710						}
711						// bind events to show/hide arrows on hover and save scrolling data for this sub
712						var vportY = winY - (itemY + itemH);
713						$sub.dataSM('scroll', {
714								vportY: vportY,
715								subH: subH,
716								winH: winH,
717								step: 1
718							})
719							.bind({
720								'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); },
721								'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); },
722								'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); }
723							})
724							.dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: this.getWidth($sub) - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: this.get
724StartZIndex() + this.zIndexInc })
725							.eq(0).css('margin-top', vportY).end()
726							.eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end()
727							.eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show();
728					}
729				}
730				if ( !$sub.closest('.menu-accordion').length ) {
731					var rightPos = 'auto';
732					if ( $sub.closest('.grid-filters').length ) {
733						if ( $sub.closest('.text-right').length ) {
734							leftPos = '0px';
735							rightPos = 'auto';
736						} else {
737							leftPos = 'auto';
738							rightPos = '0px';
739						}
740						x = 0;
741					} else {
742						if ( $sub.hasClass('mega-menu-inner') ) {
743							$sub.css({ width: containerW});
744							leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left));
745							if ( ! $('body').hasClass('megamenu-side-to-side') ) {
746								leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft'));
747							}
748							x = 0;
749						} else {
750							leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px';
751							x = (level > 2 && x >= 0) ? x + 1 : x - 1;
752						}
753					}
754				}
755
756				// $sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length ? 1 : 0) });
757				$sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length && !$sub.closest('.menu-borders.needs-after').length ? 1 : 0) });
758				// IE iframe shim
759				this.menuIframeShim($sub);
760				if ($sub.dataSM('ie-shim')) {
761					$sub.dataSM('ie-shim').css({ zIndex: $sub.css('z-index'), width: subW, height: subH, marginLeft: x, marginTop: y - itemH + ($sub.closest('.menu-mini').length ? 0 : 1) });
762				}
763			},
764			menuScroll: function($sub, up, wheel) {
765				var y = parseFloat($sub.css('margin-top')),
766					scroll = $sub.dataSM('scroll'),
767					navH = $('.navbar-main').outerHeight(),
768					end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH),
769					step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step);
770				$sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end);
771				y = parseFloat($sub.css('margin-top'));
772				// show opposite arrow if appropriate
773				if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) {
774					$sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show();
775				}
776				// accelerate when not using mousewheel to scroll
777				if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) {
778					$sub.dataSM('scroll').step += 0.5;
779				}
780				// "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used
781				if (Math.abs(y - end) < 1) {
782					$sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide();
783					$sub.dataSM('scroll').step = 1;
784				} else if (!wheel) {
785					var self = this;
786					this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval);
787				}
788			},
789			menuScrollMousewheel: function($sub, e) {
790				var $closestSub = $(e.target).closest('ul');
791				while ($closestSub.dataSM('in-mega')) {
792					$closestSub = $closestSub.parent().closest('ul');
793				}
794				if ($closestSub[0] == $sub[0]) {
795					var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0;
796					if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) {
797						this.menuScroll($sub, up, true);
798					}
799				}
800				if ( ! $sub.hasClass('mega-menu-inner') ) {
801					e.preventDefault();
802				}
803			},
804			menuScrollOut: function($sub, e) {
805				var reClass = /^scroll-(up|down)/,
806					$closestSub = $(e.relatedTarget).closest('ul');
807				while ($closestSub.dataSM('in-mega')) {
808					$closestSub = $closestSub.parent().closest('ul');
809				}
810				if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) {
811					$sub.dataSM('scroll-arrows').css('visibility', 'hidden');
812				}
813			},
814			menuScrollOver: function($sub, e) {
815				var reClass = /^scroll-(up|down)/,
816					$closestSub = $(e.target).closest('ul');
817				while ($closestSub.dataSM('in-mega')) {
818					$closestSub = $closestSub.parent().closest('ul');
819				}
820				if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) {
821					$sub.dataSM('scroll-arrows').css('visibility', 'visible');
822				}
823			},
824			menuScrollStop: function($sub) {
825				if (this.scrollTimeout) {
826					clearTimeout(this.scrollTimeout);
827					this.scrollTimeout = 0;
828					$sub.dataSM('scroll').step = 1;
829				}
830			},
831			menuShow: function($sub) {
832				if (!$sub.dataSM('beforefirstshowfired')) {
833					$sub.dataSM('beforefirstshowfired', true);
834					if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) {
835						return;
836					}
837				}
838				if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) {
839					return;
840				}
841				this.menuFixLayout($sub);
842				$sub.stop(true, true);
843				if (!$sub.is(':visible')) {
844					$sub.css({
845						'visibility': 'visible',
846						'pointer-events': 'auto',
847					});
848					// set z-index - for IE < 9 set it to the parent LI
849					var zIndex = this.getStartZIndex() + (++this.zIndexInc);
850					if (IElt9) {
851						$sub.parent().css('z-index', zIndex);
852					} else {
853						$sub.css('z-index', zIndex);
854					}
855					// highlight parent item
856					if (this.opts.keepHighlighted || this.isCollapsible()) {
857						if ($sub.dataSM('parent-a').attr('data-type') != 'title')
858							$sub.dataSM('parent-a').addClass('highlighted');
859					}
860					// min/max-width fix - no way to rely purely on CSS as all UL's are nested
861					if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) {
862						if (!IElt8) {
863							$sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
864							if (this.opts.subMenusMinWidth) {
865							 	$sub.css('min-width', this.opts.subMenusMinWidth);
866							}
867							if (this.opts.subMenusMaxWidth) {
868							 	var noMaxWidth = this.getWidth($sub);
869							 	if ( ! $sub.hasClass('mega-menu-inner') ) {
870								 	$sub.css('max-width', this.opts.subMenusMaxWidth);
871							 	}
872								if (noMaxWidth > this.getWidth($sub)) {
873									$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
874								}
875							}
876						// IE6,7
877 						} else {
878							$sub.children().css('styleFloat', 'none');
879							if (IE6) {
880								$sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1)
881									.children().children('a').css('white-space', 'nowrap');
882							} else { // IE7
883								$sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
884								if (this.opts.subMenusMinWidth) {
885									$sub.css('min-width', this.opts.subMenusMinWidth);
886								}
887							}
888							if (this.opts.subMenusMaxWidth) {
889								var noMaxWidth = $sub.width();
890								if (IE6) {
891							 		var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width();
892									if (noMaxWidth > maxWidth) {
893										$sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', '');
894									} else {
895										$sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' });
896									}
897								} else { // IE7
898								 	if ( ! $sub.hasClass('mega-menu-inner') ) {
899									 	$sub.css('max-width', this.opts.subMenusMaxWidth);
900								 	}
901									if (noMaxWidth > $sub.width()) {
902										$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
903									} else {
904										$sub.width(noMaxWidth);
905									}
906								}
907							} else {
908							 	$sub.width($sub.width());
909							}
910							$sub.children().css('styleFloat', 'left');
911						}
912					}
913					if ( $sub.hasClass('mega-menu-inner') && $('body').hasClass('scrollable-megamenu') && UNCODE.wwidth > UNCODE.mediaQuery ) {
914						var $nav = $('.navbar-main'),
915							navH = 0,
916							navTop = 0,
917							$vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container, body.menu-offcanvas .vmenu-container');
918						if ( $nav.length && typeof $nav[0] !== 'undefined' ) {
919							var navRect = $nav[0].getBoundingClientRect();
920							navH = navRect.height;
921							navTop = navRect.top;
922						}
923						if ( ! $vmenu.length ) {
924							$sub.css({ maxHeight: UNCODE.wheight - navH });
925						}
926					}
927					this.menuPosition($sub);
928					// insert IE iframe shim
929					if ($sub.dataSM('ie-shim')) {
930						$sub.dataSM('ie-shim').insertBefore($sub);
931					}
932					var complete = function() {
933						// fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used
934						$sub.css('overflow', '');
935					};
936					// if sub is collapsible (mobile view)
937					if (this.isCollapsible()) {
938						if (this.opts.collapsibleShowFunction) {
939							this.opts.collapsibleShowFunction.call(this, $sub, complete);
940						} else {
941							$sub.show(this.opts.collapsibleShowDuration, complete);
942						}
943					} else {
944						if (this.opts.showFunction) {
945							this.opts.showFunction.call(this, $sub, complete);
946						} else {
947							$sub.show(this.opts.showDuration, complete);
948						}
949					}
950					// save new sub menu for this level
951					this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub;
952					this.$root.triggerHandler('show.smapi', $sub[0]);
953				}
954			},
955			popupHide: function(noHideTimeout) {
956				if (this.hideTimeout) {
957					clearTimeout(this.hideTimeout);
958					this.hideTimeout = 0;
959				}
960				var self = this;
961				this.hideTimeout = setTimeout(function() {
962					self.menuHideAll();
963				}, noHideTimeout ? 1 : this.opts.hideTimeout);
964			},
965			popupShow: function(left, top) {
966				if (!this.opts.isPopup) {
967					alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.');
968					return;
969				}
970				if (this.hideTimeout) {
971					clearTimeout(this.hideTimeout);
972					this.hideTimeout = 0;
973				}
974				this.menuFixLayout(this.$root);
975				this.$root.stop(true, true);
976				if (!this.$root.is(':visible')) {
977					this.$root.css({ left: left, top: top });
978					// IE iframe shim
979					this.menuIframeShim(this.$root);
980					if (this.$root.dataSM('ie-shim')) {
981						this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
981: left, top: top }).insertBefore(this.$root);
982					}
983					// show menu
984					if (this.opts.showFunction) {
985						this.opts.showFunction.call(this, this.$root);
986					} else {
987						this.$root.show(this.opts.showDuration);
988					}
989					this.visibleSubMenus[0] = this.$root;
990				}
991			},
992			refresh: function() {
993				this.menuHideAll();
994				this.$root.find('ul').each(function() {
995						var $this = $(this);
996						if ($this.dataSM('scroll-arrows')) {
997							$this.dataSM('scroll-arrows').remove();
998						}
999					})
1000					.removeDataSM('in-mega')
1001					.removeDataSM('shown-before')
1002					.removeDataSM('ie-shim')
1003					.removeDataSM('scroll-arrows')
1004					.removeDataSM('parent-a')
1005					.removeDataSM('level')
1006					.removeDataSM('beforefirstshowfired');
1007				this.$root.find('a.has-submenu').removeClass('has-submenu')
1008					.parent().removeDataSM('sub');
1009				if (this.opts.subIndicators) {
1010					this.$root.find('span.sub-arrow').remove();
1011				}
1012				if (this.opts.markCurrentItem) {
1013					this.$root.find('a.current').removeClass('current');
1014				}
1015				this.subMenus = [];
1016				this.init(true);
1017			},
1018			rootOut: function(e) {
1019				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
1020					return;
1021				}
1022				if (this.hideTimeout) {
1023					clearTimeout(this.hideTimeout);
1024					this.hideTimeout = 0;
1025				}
1026				if (!this.opts.showOnClick || !this.opts.hideOnClick) {
1027					var self = this;
1028					this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout);
1029				}
1030			},
1031			rootOver: function(e) {
1032				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
1033					return;
1034				}
1035				if (this.hideTimeout) {
1036					clearTimeout(this.hideTimeout);
1037					this.hideTimeout = 0;
1038				}
1039			},
1040			winResize: function(e) {
1041				if (!this.handleEvents()) {
1042					// we still need to resize the disable overlay if it's visible
1043					if (this.$disableOverlay) {
1044						var pos = this.$root.offset();
1045	 					this.$disableOverlay.css({
1046							top: pos.top,
1047							left: pos.left,
1048							width: this.$root.outerWidth(),
1049							height: this.$root.outerHeight()
1050						});
1051					}
1052					return;
1053				}
1054				// hide sub menus on resize - on mobile do it only on orientation change
1055				if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) {
1056					if (this.activatedItems.length) {
1057						this.activatedItems[this.activatedItems.length - 1][0].blur();
1058					}
1059					this.menuHideAll();
1060				}
1061			}
1062		}
1063	});
1064
1065	$.fn.dataSM = function(key, val) {
1066		if (val) {
1067			return this.data(key + '_smartmenus', val);
1068		}
1069		return this.data(key + '_smartmenus');
1070	}
1071
1072	$.fn.removeDataSM = function(key) {
1073		return this.removeData(key + '_smartmenus');
1074	}
1075
1076	$.fn.smartmenus = function(options) {
1077		if (typeof options == 'string') {
1078			var args = arguments,
1079				method = options;
1080			Array.prototype.shift.call(args);
1081			return this.each(function() {
1082				var smartmenus = $(this).data('smartmenus');
1083				if (smartmenus && smartmenus[method]) {
1084					smartmenus[method].apply(smartmenus, args);
1085				}
1086			});
1087		}
1088		var opts = $.extend({}, $.fn.smartmenus.defaults, options);
1089		return this.each(function() {
1090			new $.SmartMenus(this, opts);
1091		});
1092	}
1093
1094	// default settings
1095	$.fn.smartmenus.defaults = {
1096		isPopup:		false,		// is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar
1097		mainMenuSubOffsetX:	0,		// pixels offset from default position
1098		mainMenuSubOffsetY:	0,		// pixels offset from default position
1099		subMenusSubOffsetX:	0,		// pixels offset from default position
1100		subMenusSubOffsetY:	0,		// pixels offset from default position
1101		subMenusMinWidth:	false, //'10em',		// min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
1102		subMenusMaxWidth:	false, //'20em',		// max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
1103		subIndicators: 		true,		// create sub menu indicators - creates a SPAN and inserts it in the A
1104		subIndicatorsPos: 	'prepend',	// position of the SPAN relative to the menu item content ('prepend', 'append')
1105		subIndicatorsText:	'+',		// [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too)
1106		scrollStep: 		30,		// pixels step when scrolling long sub menus that do not fit in the viewport height
1107		scrollInterval:		30,		// interval between each scrolling step
1108		scrollAccelerate:	true,		// accelerate scrolling or use a fixed step
1109		showTimeout:		250,		// timeout before showing the sub menus
1110		hideTimeout:		500,		// timeout before hiding the sub menus
1111		showDuration:		0,		// duration for show animation - set to 0 for no animation - matters only if showFunction:null
1112		showFunction:		null,		// custom function to use when showing a sub menu (the default is the jQuery 'show')
1113							// don't forget to call complete() at the end of whatever you do
1114							// e.g.: function($ul, complete) { $ul.fadeIn(250, complete); }
1115		hideDuration:		0,		// duration for hide animation - set to 0 for no animation - matters only if hideFunction:null
1116		hideFunction:		function($ul, complete) { $ul.fadeOut(200, complete); },	// custom function to use when hiding a sub menu (the default is the jQuery 'hide')
1117							// don't forget to call complete() at the end of whatever you do
1118							// e.g.: function($ul, complete) { $ul.fadeOut(250, complete); }
1119		collapsibleShowDuration:0,		// duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null
1120		collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); },	// custom function to use when showing a collapsible sub menu
1121							// (i.e. when mobile styles are used to make the sub menus collapsible)
1122		collapsibleHideDuration:0,		// duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null
1123		collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); },	// custom function to use when hiding a collapsible sub menu
1124							// (i.e. when mobile styles are used to make the sub menus collapsible)
1125		showOnClick:		false,		// show the first-level sub menus onclick instead of onmouseover (matters only for mouse input)
1126		hideOnClick:		true,		// hide the sub menus on click/tap anywhere on the page
1127		keepInViewport:		true,		// reposition the sub menus if needed to make sure they always appear inside the viewport
1128		keepHighlighted:	true,		// keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's)
1129		markCurrentItem:	false,		// automatically add the 'current' class to the A element of the item linking to the current URL
1130		markCurrentTree:	true,		// add the 'current' class also to the A elements of all ancestor items of the current item
1131		rightToLeftSubMenus:	false,		// right to left display of the sub menus (check the CSS for the sub indicators' position)
1132		bottomToTopSubMenus:	false,		// bottom to top display of the sub menus
1133		overlapControlsInIE:	true		// make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.)
1134	};
1135
1136})(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.