Licensed under the Apache License, Version 2.0 (the “License”)\r\n *
Copyright © 2013 Adobe Systems Incorporated.\r\n *
Project page https://github.com/adobe-accessibility/Accessible-Mega-Menu\r\n * @version 0.1\r\n * @author Michael Jordan\r\n * @requires jquery\r\n */\n\n/*jslint browser: true, devel: true, plusplus: true, nomen: true */\n/*global jQuery */\n(function ($, window, document) {\n var pluginName = 'accessibleMegaMenu',\n defaults = {\n openOnClick: false,\n uuidPrefix: 'accessible-megamenu', // unique ID's are required to indicate aria-owns, aria-controls and aria-labelledby\n menuClass: 'accessible-megamenu', // default css class used to define the megamenu styling\n topNavItemClass: 'accessible-megamenu-top-nav-item', // default css class for a top-level navigation item in the megamenu\n panelClass: 'accessible-megamenu-panel', // default css class for a megamenu panel\n panelGroupClass: 'accessible-megamenu-panel-group', // default css class for a group of items within a megamenu panel\n hoverClass: 'hover', // default css class for the hover state\n focusClass: 'focus', // default css class for the focus state\n openClass: 'open' // default css class for the open state\n },\n Keyboard = {\n BACKSPACE: 8,\n COMMA: 188,\n DELETE: 46,\n DOWN: 40,\n END: 35,\n ENTER: 13,\n ESCAPE: 27,\n HOME: 36,\n LEFT: 37,\n PAGE_DOWN: 34,\n PAGE_UP: 33,\n PERIOD: 190,\n RIGHT: 39,\n SPACE: 32,\n TAB: 9,\n UP: 38,\n keyMap: {\n 48: '0',\n 49: '1',\n 50: '2',\n 51: '3',\n 52: '4',\n 53: '5',\n 54: '6',\n 55: '7',\n 56: '8',\n 57: '9',\n 59: '',\n 65: 'a',\n 66: 'b',\n 67: 'c',\n 68: 'd',\n 69: 'e',\n 70: 'f',\n 71: 'g',\n 72: 'h',\n 73: 'i',\n 74: 'j',\n 75: 'k',\n 76: 'l',\n 77: 'm',\n 78: 'n',\n 79: 'o',\n 80: 'p',\n 81: 'q',\n 82: 'r',\n 83: 's',\n 84: 't',\n 85: 'u',\n 86: 'v',\n 87: 'w',\n 88: 'x',\n 89: 'y',\n 90: 'z',\n 96: '0',\n 97: '1',\n 98: '2',\n 99: '3',\n 100: '4',\n 101: '5',\n 102: '6',\n 103: '7',\n 104: '8',\n 105: '9',\n 190: '.'\n }\n /**\r\n * @desc Creates a new accessible mega menu instance.\r\n * @param {jquery} element\r\n * @param {object} [options] Mega Menu options\r\n * @param {string} [options.uuidPrefix=accessible-megamenu] - Prefix for generated unique id attributes, which are required to indicate aria-owns, aria-controls and aria-labelledby\r\n * @param {string} [options.menuClass=accessible-megamenu] - CSS class used to define the megamenu styling\r\n * @param {string} [options.topNavItemClass=accessible-megamenu-top-nav-item] - CSS class for a top-level navigation item in the megamenu\r\n * @param {string} [options.panelClass=accessible-megamenu-panel] - CSS class for a megamenu panel\r\n * @param {string} [options.panelGroupClass=accessible-megamenu-panel-group] - CSS class for a group of items within a megamenu panel\r\n * @param {string} [options.hoverClass=hover] - CSS class for the hover state\r\n * @param {string} [options.focusClass=focus] - CSS class for the focus state\r\n * @param {string} [options.openClass=open] - CSS class for the open state\r\n * @constructor\r\n */\n };function AccessibleMegaMenu(element, options) {\n this.element = element;\n\n // merge optional settings and defaults into settings\n this.settings = $.extend({}, defaults, options);\n\n this._defaults = defaults;\n this._name = pluginName;\n\n this.mouseTimeoutID = null;\n this.focusTimeoutID = null;\n this.mouseFocused = false;\n this.justFocused = false;\n\n this.init();\n }\n\n AccessibleMegaMenu.prototype = function () {\n\n /* private attributes and methods ------------------------ */\n var uuid = 0,\n keydownTimeoutDuration = 1000,\n keydownSearchString = '',\n isTouch = typeof window.hasOwnProperty === 'function' && !!window.hasOwnProperty('ontouchstart'),\n _getPlugin,\n _addUniqueId,\n _togglePanel,\n _clickHandler,\n _clickOutsideHandler,\n _DOMAttrModifiedHandler,\n _focusInHandler,\n _focusOutHandler,\n _keyDownHandler,\n _mouseDownHandler,\n _mouseOverHandler,\n _mouseOutHandler,\n _toggleExpandedEventHandlers;\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_getPlugin\r\n * @desc Returns the parent accessibleMegaMenu instance for a given element\r\n * @param {jQuery} element\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _getPlugin = function _getPlugin(element) {\n return $(element).closest(':data(plugin_' + pluginName + ')').data('plugin_' + pluginName);\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_addUniqueId\r\n * @desc Adds a unique id and element.\r\n * The id string starts with the\r\n * string defined in settings.uuidPrefix.\r\n * @param {jQuery} element\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _addUniqueId = function _addUniqueId(element) {\n element = $(element);\n var settings = this.settings;\n if (!element.attr('id')) {\n element.attr('id', settings.uuidPrefix + '-' + new Date().getTime() + '-' + ++uuid);\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_togglePanel\r\n * @desc Toggle the display of mega menu panels in response to an event.\r\n * The optional boolean value 'hide' forces all panels to hide.\r\n * @param {event} event\r\n * @param {Boolean} [hide] Hide all mega menu panels when true\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _togglePanel = function _togglePanel(event, hide) {\n var target = $(event.target),\n that = this,\n settings = this.settings,\n menu = this.menu,\n topli = target.closest('.' + settings.topNavItemClass),\n panel = target.hasClass(settings.panelClass) ? target : target.closest('.' + settings.panelClass),\n newfocus;\n\n _toggleExpandedEventHandlers.call(this, true);\n\n if (hide) {\n topli = menu.find('.' + settings.topNavItemClass + ' .' + settings.openClass + ':first').closest('.' + settings.topNavItemClass);\n if (!(topli.is(event.relatedTarget) || topli.has(event.relatedTarget).length > 0)) {\n if ((event.type === 'mouseout' || event.type === 'focusout') && topli.has(document.activeElement).length > 0) {\n return;\n }\n topli.find('[aria-expanded]').attr('aria-expanded', 'false').removeClass(settings.openClass).filter('.' + settings.panelClass).attr('aria-hidden', 'true');\n if (event.type === 'keydown' && event.keyCode === Keyboard.ESCAPE || event.type === 'DOMAttrModified') {\n newfocus = topli.find(':tabbable:first');\n setTimeout(function () {\n menu.find('[aria-expanded].' + that.settings.panelClass).off('DOMAttrModified.accessible-megamenu');\n newfocus.focus();\n that.justFocused = false;\n }, 99);\n }\n } else if (topli.length === 0) {\n menu.find('[aria-expanded=true]').attr('aria-expanded', 'false').removeClass(settings.openClass).filter('.' + settings.panelClass).attr('aria-hidden', 'true');\n }\n } else {\n clearTimeout(that.focusTimeoutID);\n topli.siblings().find('[aria-expanded]').attr('aria-expanded', 'false').removeClass(settings.openClass).filter('.' + settings.panelClass).attr('aria-hidden', 'true');\n topli.find('[aria-expanded]').attr('aria-expanded', 'true').addClass(settings.openClass).filter('.' + settings.panelClass).attr('aria-hidden', 'false');\n if (event.type === 'mouseover' && target.is(':tabbable') && topli.length === 1 && panel.length === 0 && menu.has(document.activeElement).length > 0) {\n target.focus();\n that.justFocused = false;\n }\n\n _toggleExpandedEventHandlers.call(that);\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_clickHandler\r\n * @desc Handle click event on mega menu item\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _clickHandler = function _clickHandler(event) {\n var target = $(event.currentTarget),\n topli = target.closest('.' + this.settings.topNavItemClass),\n panel = target.closest('.' + this.settings.panelClass);\n if (topli.length === 1 && panel.length === 0 && topli.find('.' + this.settings.panelClass).length === 1) {\n if (!target.hasClass(this.settings.openClass)) {\n event.preventDefault();\n event.stopPropagation();\n _togglePanel.call(this, event);\n this.justFocused = false;\n } else {\n if (this.justFocused) {\n event.preventDefault();\n event.stopPropagation();\n this.justFocused = false;\n } else if (isTouch || this.mouseFocused) {\n event.preventDefault();\n event.stopPropagation();\n _togglePanel.call(this, event, target.hasClass(this.settings.openClass));\n }\n }\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_clickOutsideHandler\r\n * @desc Handle click event outside of a the megamenu\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _clickOutsideHandler = function _clickOutsideHandler(event) {\n if ($(event.target).closest(this.menu).length === 0) {\n event.preventDefault();\n event.stopPropagation();\n _togglePanel.call(this, event, true);\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_DOMAttrModifiedHandler\r\n * @desc Handle DOMAttrModified event on panel to respond to Windows 8 Narrator ExpandCollapse pattern\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _DOMAttrModifiedHandler = function _DOMAttrModifiedHandler(event) {\n if (event.originalEvent.attrName === 'aria-expanded' && event.originalEvent.newValue === 'false' && $(event.target).hasClass(this.settings.openClass)) {\n event.preventDefault();\n event.stopPropagation();\n _togglePanel.call(this, event, true);\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_focusInHandler\r\n * @desc Handle focusin event on mega menu item.\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _focusInHandler = function _focusInHandler(event) {\n clearTimeout(this.focusTimeoutID);\n var target = $(event.target),\n panel = target.closest('.' + this.settings.panelClass);\n target.addClass(this.settings.focusClass).on('click.accessible-megamenu', $.proxy(_clickHandler, this));\n this.justFocused = !this.mouseFocused;\n this.mouseFocused = false;\n if (this.panels.not(panel).filter('.' + this.settings.openClass).length) {\n _togglePanel.call(this, event);\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_focusOutHandler\r\n * @desc Handle focusout event on mega menu item.\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _focusOutHandler = function _focusOutHandler(event) {\n this.justFocused = false;\n var that = this,\n target = $(event.target),\n topli = target.closest('.' + this.settings.topNavItemClass);\n\n target\n // .removeClass(this.settings.focusClass)\n .off('click.accessible-megamenu');\n\n if (window.cvox) {\n // If ChromeVox is running...\n that.focusTimeoutID = setTimeout(function () {\n window.cvox.Api.getCurrentNode(function (node) {\n if (topli.has(node).length) {\n // and the current node being voiced is in\n // the mega menu, clearTimeout,\n // so the panel stays open.\n clearTimeout(that.focusTimeoutID);\n } else {\n that.focusTimeoutID = setTimeout(function (scope, _event, hide) {\n _togglePanel.call(scope, _event, hide);\n }, 275, that, event, true);\n }\n });\n }, 25);\n } else {\n that.focusTimeoutID = setTimeout(function () {\n _togglePanel.call(that, event, true);\n }, 300);\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_keyDownHandler\r\n * @desc Handle keydown event on mega menu.\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _keyDownHandler = function _keyDownHandler(event) {\n var that = this.constructor === AccessibleMegaMenu ? this : _getPlugin(this),\n // determine the AccessibleMegaMenu plugin instance\n settings = that.settings,\n target = $($(this).is('.' + settings.hoverClass + ':tabbable') ? this : event.target),\n // if the element is hovered the target is this, otherwise, its the focused element\n menu = that.menu,\n topnavitems = that.topnavitems,\n topli = target.closest('.' + settings.topNavItemClass),\n tabbables = menu.find(':tabbable'),\n panel = target.hasClass(settings.panelClass) ? target : target.closest('.' + settings.panelClass),\n panelGroups = panel.find('.' + settings.panelGroupClass),\n currentPanelGroup = target.closest('.' + settings.panelGroupClass),\n next,\n keycode = event.keyCode || event.which,\n start,\n i,\n o,\n label,\n found = false,\n newString = Keyboard.keyMap[event.keyCode] || '',\n regex,\n isTopNavItem = topli.length === 1 && panel.length === 0;\n\n if (target.is('input:focus, select:focus, textarea:focus, button:focus')) {\n // if the event target is a form element we should handle keydown normally\n return;\n }\n\n if (target.is('.' + settings.hoverClass + ':tabbable')) {\n $('html').off('keydown.accessible-megamenu');\n }\n\n switch (keycode) {\n case Keyboard.ESCAPE:\n _togglePanel.call(that, event, true);\n break;\n case Keyboard.DOWN:\n event.preventDefault();\n if (isTopNavItem) {\n _togglePanel.call(that, event);\n found = topli.find('.' + settings.panelClass + ' :tabbable:first').focus().length === 1;\n } else {\n found = tabbables.filter(':gt(' + tabbables.index(target) + '):first').focus().length === 1;\n }\n\n if (!found && window.opera && opera.toString() === '[object Opera]' && (event.ctrlKey || event.metaKey)) {\n tabbables = $(':tabbable');\n i = tabbables.index(target);\n found = $(':tabbable:gt(' + $(':tabbable').index(target) + '):first').focus().length === 1;\n }\n break;\n case Keyboard.UP:\n event.preventDefault();\n if (isTopNavItem && target.hasClass(settings.openClass)) {\n _togglePanel.call(that, event, true);\n next = topnavitems.filter(':lt(' + topnavitems.index(topli) + '):last');\n if (next.children('.' + settings.panelClass).length) {\n found = next.children().attr('aria-expanded', 'true').addClass(settings.openClass).filter('.' + settings.panelClass).attr('aria-hidden', 'false').find(':tabbable:last').focus() === 1;\n }\n } else if (!isTopNavItem) {\n found = tabbables.filter(':lt(' + tabbables.index(target) + '):last').focus().length === 1;\n }\n\n if (!found && window.opera && opera.toString() === '[object Opera]' && (event.ctrlKey || event.metaKey)) {\n tabbables = $(':tabbable');\n i = tabbables.index(target);\n found = $(':tabbable:lt(' + $(':tabbable').index(target) + '):first').focus().length === 1;\n }\n break;\n case Keyboard.RIGHT:\n event.preventDefault();\n if (isTopNavItem) {\n found = topnavitems.filter(':gt(' + topnavitems.index(topli) + '):first').find(':tabbable:first').focus().length === 1;\n } else {\n if (panelGroups.length && currentPanelGroup.length) {\n // if the current panel contains panel groups, and we are able to focus the first tabbable element of the next panel group\n found = panelGroups.filter(':gt(' + panelGroups.index(currentPanelGroup) + '):first').find(':tabbable:first').focus().length === 1;\n }\n\n if (!found) {\n found = topli.find(':tabbable:first').focus().length === 1;\n }\n }\n break;\n case Keyboard.LEFT:\n event.preventDefault();\n if (isTopNavItem) {\n found = topnavitems.filter(':lt(' + topnavitems.index(topli) + '):last').find(':tabbable:first').focus().length === 1;\n } else {\n if (panelGroups.length && currentPanelGroup.length) {\n // if the current panel contains panel groups, and we are able to focus the first tabbable element of the previous panel group\n found = panelGroups.filter(':lt(' + panelGroups.index(currentPanelGroup) + '):last').find(':tabbable:first').focus().length === 1;\n }\n\n if (!found) {\n found = topli.find(':tabbable:first').focus().length === 1;\n }\n }\n break;\n case Keyboard.TAB:\n i = tabbables.index(target);\n if (event.shiftKey && isTopNavItem && target.hasClass(settings.openClass)) {\n _togglePanel.call(that, event, true);\n next = topnavitems.filter(':lt(' + topnavitems.index(topli) + '):last');\n if (next.children('.' + settings.panelClass).length) {\n found = next.children().attr('aria-expanded', 'true').addClass(settings.openClass).filter('.' + settings.panelClass).attr('aria-hidden', 'false').find(':tabbable:last').focus();\n }\n } else if (event.shiftKey && i > 0) {\n found = tabbables.filter(':lt(' + i + '):last').focus().length === 1;\n } else if (!event.shiftKey && i < tabbables.length - 1) {\n found = tabbables.filter(':gt(' + i + '):first').focus().length === 1;\n } else if (window.opera && opera.toString() === '[object Opera]') {\n tabbables = $(':tabbable');\n i = tabbables.index(target);\n if (event.shiftKey) {\n found = $(':tabbable:lt(' + $(':tabbable').index(target) + '):last').focus().length === 1;\n } else {\n found = $(':tabbable:gt(' + $(':tabbable').index(target) + '):first').focus().length === 1;\n }\n }\n\n if (found) {\n event.preventDefault();\n }\n break;\n case Keyboard.SPACE:\n if (isTopNavItem) {\n event.preventDefault();\n _clickHandler.call(that, event);\n } else {\n return;\n }\n break;\n case Keyboard.ENTER:\n return;\n break;\n default:\n // alphanumeric filter\n clearTimeout(this.keydownTimeoutID);\n\n keydownSearchString += newString !== keydownSearchString ? newString : '';\n\n if (keydownSearchString.length === 0) {\n return;\n }\n\n this.keydownTimeoutID = setTimeout(function () {\n keydownSearchString = '';\n }, keydownTimeoutDuration);\n\n if (isTopNavItem && !target.hasClass(settings.openClass)) {\n tabbables = tabbables.filter(':not(.' + settings.panelClass + ' :tabbable)');\n } else {\n tabbables = topli.find(':tabbable');\n }\n\n if (event.shiftKey) {\n tabbables = $(tabbables.get().reverse());\n }\n\n for (i = 0; i < tabbables.length; i++) {\n o = tabbables.eq(i);\n if (o.is(target)) {\n start = keydownSearchString.length === 1 ? i + 1 : i;\n break;\n }\n }\n\n regex = new RegExp('^' + keydownSearchString.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&'), 'i');\n\n for (i = start; i < tabbables.length; i++) {\n o = tabbables.eq(i);\n label = $.trim(o.text());\n if (regex.test(label)) {\n found = true;\n o.focus();\n break;\n }\n }\n if (!found) {\n for (i = 0; i < start; i++) {\n o = tabbables.eq(i);\n label = $.trim(o.text());\n if (regex.test(label)) {\n o.focus();\n break;\n }\n }\n }\n break;\n }\n that.justFocused = false;\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_mouseDownHandler\r\n * @desc Handle mousedown event on mega menu.\r\n * @param {event} Event object\r\n * @memberof accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _mouseDownHandler = function _mouseDownHandler(event) {\n if ($(event.target).is(this.settings.panelClass) || $(event.target).closest(':focusable').length) {\n this.mouseFocused = true;\n }\n this.mouseTimeoutID = setTimeout(function () {\n clearTimeout(this.focusTimeoutID);\n }, 1);\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_mouseOverHandler\r\n * @desc Handle mouseover event on mega menu.\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _mouseOverHandler = function _mouseOverHandler(event) {\n clearTimeout(this.mouseTimeoutID);\n $(event.target).addClass(this.settings.hoverClass);\n _togglePanel.call(this, event);\n if ($(event.target).is(':tabbable')) {\n $('html').on('keydown.accessible-megamenu', $.proxy(_keyDownHandler, event.target));\n }\n };\n\n /**\r\n * @name jQuery.fn.accessibleMegaMenu~_mouseOutHandler\r\n * @desc Handle mouseout event on mega menu.\r\n * @param {event} Event object\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @inner\r\n * @private\r\n */\n _mouseOutHandler = function _mouseOutHandler(event) {\n var that = this;\n $(event.target).removeClass(that.settings.hoverClass);\n\n that.mouseTimeoutID = setTimeout(function () {\n _togglePanel.call(that, event, true);\n }, 250);\n if ($(event.target).is(':tabbable')) {\n $('html').off('keydown.accessible-megamenu');\n }\n };\n\n _toggleExpandedEventHandlers = function _toggleExpandedEventHandlers(hide) {\n var menu = this.menu;\n if (hide) {\n $('html').off('mouseup.outside-accessible-megamenu, touchend.outside-accessible-megamenu, mspointerup.outside-accessible-megamenu, pointerup.outside-accessible-megamenu');\n\n menu.find('[aria-expanded].' + this.settings.panelClass).off('DOMAttrModified.accessible-megamenu');\n } else {\n $('html').on('mouseup.outside-accessible-megamenu, touchend.outside-accessible-megamenu, mspointerup.outside-accessible-megamenu, pointerup.outside-accessible-megamenu', $.proxy(_clickOutsideHandler, this));\n\n /* Narrator in Windows 8 automatically toggles the aria-expanded property on double tap or click.\r\n To respond to the change to collapse the panel, we must add a listener for a DOMAttrModified event. */\n menu.find('[aria-expanded=true].' + this.settings.panelClass).on('DOMAttrModified.accessible-megamenu', $.proxy(_DOMAttrModifiedHandler, this));\n }\n };\n\n /* public attributes and methods ------------------------- */\n return {\n constructor: AccessibleMegaMenu,\n\n /**\r\n * @lends jQuery.fn.accessibleMegaMenu\r\n * @desc Initializes an instance of the accessibleMegaMenu plugins\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @instance\r\n */\n init: function init() {\n var settings = this.settings,\n nav = $(this.element),\n menu = nav.children().first(),\n\n // Only filter to those items with the selector class\n topnavitems = this.settings.topNavItems ? menu.children(this.settings.topNavItems) : menu.children();\n this.start(settings, nav, menu, topnavitems);\n },\n\n start: function start(settings, nav, menu, topnavitems) {\n var that = this;\n this.settings = settings;\n this.menu = menu;\n this.topnavitems = topnavitems;\n\n nav.attr('role', 'navigation');\n menu.addClass(settings.menuClass);\n topnavitems.each(function (i, topnavitem) {\n var topnavitemlink, topnavitempanel;\n topnavitem = $(topnavitem);\n // @FIXME: Add classed manually !!!\n // topnavitem.addClass(settings.topNavItemClass)\n topnavitemlink = topnavitem.find(':tabbable:first');\n topnavitempanel = topnavitem.children(':not(:tabbable):last');\n _addUniqueId.call(that, topnavitemlink);\n if (topnavitempanel.length) {\n _addUniqueId.call(that, topnavitempanel);\n topnavitemlink.attr({\n 'aria-haspopup': true,\n 'aria-controls': topnavitempanel.attr('id'),\n 'aria-expanded': false\n });\n\n topnavitempanel.attr({\n 'role': 'group',\n 'aria-expanded': false,\n 'aria-hidden': true\n }).addClass(settings.panelClass).not('[aria-labelledby]').attr('aria-labelledby', topnavitemlink.attr('id'));\n }\n });\n\n this.panels = menu.find('.' + settings.panelClass);\n\n menu.on('focusin.accessible-megamenu', ':focusable, .' + settings.panelClass, $.proxy(_focusInHandler, this)).on('focusout.accessible-megamenu', ':focusable, .' + settings.panelClass, $.proxy(_focusOutHandler, this)).on('keydown.accessible-megamenu', $.proxy(_keyDownHandler, this)).on('mousedown.accessible-megamenu', $.proxy(_mouseDownHandler, this));\n\n if (!settings.openOnClick) {\n menu.on('mouseover.accessible-megamenu', $.proxy(_mouseOverHandler, this)).on('mouseout.accessible-megamenu', $.proxy(_mouseOutHandler, this));\n } else {\n menu.on('click.accessible-megamenu', $.proxy(_mouseOverHandler, this));\n }\n\n if (isTouch) {\n menu.on('touchstart.accessible-megamenu', $.proxy(_clickHandler, this));\n }\n\n menu.find('hr').attr('role', 'separator');\n\n if ($(document.activeElement).closest(menu).length) {\n $(document.activeElement).trigger('focusin.accessible-megamenu');\n }\n },\n\n /**\r\n * @desc Get default values\r\n * @example $(selector).accessibleMegaMenu('getDefaults')\r\n * @return {object}\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @instance\r\n */\n getDefaults: function getDefaults() {\n return this._defaults;\n },\n\n /**\r\n * @desc Get any option set to plugin using its name (as string)\r\n * @example $(selector).accessibleMegaMenu('getOption', some_option)\r\n * @param {string} opt\r\n * @return {string}\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @instance\r\n */\n getOption: function getOption(opt) {\n return this.settings[opt];\n },\n\n /**\r\n * @desc Get all options\r\n * @example $(selector).accessibleMegaMenu('getAllOptions')\r\n * @return {object}\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @instance\r\n */\n getAllOptions: function getAllOptions() {\n return this.settings;\n },\n\n /**\r\n * @desc Set option\r\n * @example $(selector).accessibleMegaMenu('setOption', 'option_name', 'option_value', reinitialize)\r\n * @param {string} opt - Option name\r\n * @param {string} val - Option value\r\n * @param {boolean} [reinitialize] - boolean to re-initialize the menu.\r\n * @memberof jQuery.fn.accessibleMegaMenu\r\n * @instance\r\n */\n setOption: function setOption(opt, value, reinitialize) {\n this.settings[opt] = value;\n if (reinitialize) {\n this.init();\n }\n }\n };\n }();\n\n /*\r\n * @param {object} [options] Mega Menu options\r\n * @param {string} [options.uuidPrefix=accessible-megamenu] - Prefix for generated unique id attributes, which are required to indicate aria-owns, aria-controls and aria-labelledby\r\n * @param {string} [options.menuClass=accessible-megamenu] - CSS class used to define the megamenu styling\r\n * @param {string} [options.topNavItemClass=accessible-megamenu-top-nav-item] - CSS class for a top-level navigation item in the megamenu\r\n * @param {string} [options.panelClass=accessible-megamenu-panel] - CSS class for a megamenu panel\r\n * @param {string} [options.panelGroupClass=accessible-megamenu-panel-group] - CSS class for a group of items within a megamenu panel\r\n * @param {string} [options.hoverClass=hover] - CSS class for the hover state\r\n * @param {string} [options.focusClass=focus] - CSS class for the focus state\r\n * @param {string} [options.openClass=open] - CSS class for the open state\r\n */\n $.fn[pluginName] = function (options) {\n return this.each(function () {\n if (!$.data(this, 'plugin_' + pluginName)) {\n $.data(this, 'plugin_' + pluginName, new $.fn[pluginName].AccessibleMegaMenu(this, options));\n }\n });\n };\n\n $.fn[pluginName].AccessibleMegaMenu = AccessibleMegaMenu;\n\n /* :focusable and :tabbable selectors from\r\n https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.core.js */\n\n /**\r\n * @private\r\n */\n function visible(element) {\n return $.expr.filters.visible(element) && !$(element).parents().addBack().filter(function () {\n return $.css(this, 'visibility') === 'hidden';\n }).length;\n }\n\n /**\r\n * @private\r\n */\n function _focusable(element, isTabIndexNotNaN) {\n var map,\n mapName,\n img,\n nodeName = element.nodeName.toLowerCase();\n if ('area' === nodeName) {\n map = element.parentNode;\n mapName = map.name;\n if (!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {\n return false;\n }\n img = $('img[usemap=#' + mapName + ']')[0];\n return !!img && visible(img);\n }\n return (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled : 'a' === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) &&\n // the element and all of its ancestors must be visible\n visible(element);\n }\n\n $.extend($.expr[':'], {\n data: $.expr.createPseudo ? $.expr.createPseudo(function (dataName) {\n return function (elem) {\n return !!$.data(elem, dataName);\n };\n }) : // support: jQuery <1.8\n function (elem, i, match) {\n return !!$.data(elem, match[3]);\n },\n\n focusable: function focusable(element) {\n return _focusable(element, !isNaN($.attr(element, 'tabindex')));\n },\n\n tabbable: function tabbable(element) {\n var tabIndex = $.attr(element, 'tabindex'),\n isTabIndexNaN = isNaN(tabIndex);\n return (isTabIndexNaN || tabIndex >= 0) && _focusable(element, !isTabIndexNaN);\n }\n });\n})(jQuery, window, document);\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _jquery = __webpack_require__(0);\n\nvar _jquery2 = _interopRequireDefault(_jquery);\n\nvar _offcanvas = __webpack_require__(22);\n\nvar _offcanvas2 = _interopRequireDefault(_offcanvas);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar opts = {\n // String - panel\n panelSelector: '.Offcanvas',\n\n // String - content\n contentSelector: '.Offcanvas-content',\n\n // String - content\n modalSelector: '.Offcanvas--modal',\n\n // String - trigger\n jsSelector: '.js-fr-offcanvas-open',\n\n // String - Selector for the open button(s)\n openSelector: '.js-fr-offcanvas-open',\n\n // String - Selector for the close button\n closeSelector: '.js-fr-offcanvas-close',\n\n // String - Class name that will be added to the selector when the component has been initialised\n readyClass: 'is-ready',\n\n // String - Class name that will be added to the selector when the panel is visible\n activeClass: 'is-active'\n\n /*\r\n * Prevent scroll on body when offcanvas is visible\r\n * (the touchmove handler targets iOS devices)\r\n */\n};var _handleModalScroll = function _handleModalScroll() {\n (0, _jquery2['default'])(opts.contentSelector).on('transitionend', function () {\n if (!(0, _jquery2['default'])(opts.panelSelector).hasClass(opts.activeClass)) {\n (0, _jquery2['default'])(window).off('scroll.offcanvas');\n (0, _jquery2['default'])(document).off('touchmove.offcanvas');\n } else {\n var _scrollTop = (0, _jquery2['default'])(window).scrollTop();\n (0, _jquery2['default'])(window).on('scroll.offcanvas', function () {\n return (0, _jquery2['default'])(window).scrollTop(_scrollTop);\n });\n (0, _jquery2['default'])(document).on('touchmove.offcanvas', function () {\n return (0, _jquery2['default'])(window).scrollTop(_scrollTop);\n });\n }\n });\n};\n\n/*\r\n *\tFIXME: hack to show / hide the background panel\r\n */\nvar _handleModal = function _handleModal(e) {\n if (e && (0, _jquery2['default'])(opts.panelSelector).hasClass(opts.activeClass) && !(0, _jquery2['default'])(e.target).is(opts.contentSelector)) {\n // for some odd reason plain jquery click() does not work here\n // // so we add that get(0) call\n (0, _jquery2['default'])(e.target).find(opts.closeSelector).get(0).click();\n }\n // we're using \"one\" here instead of \"bind\" because\n // otherwise $(opts.closeSelector).click() would trigger\n // a click on modal again looping forever\n (0, _jquery2['default'])(opts.modalSelector).one('click', _handleModal);\n};\n\nvar _exports = {\n Froffcanvas: _offcanvas2['default'],\n opts: opts\n};\n\n(0, _jquery2['default'])(document).ready(function () {\n var _scrollTop = (0, _jquery2['default'])(window).scrollTop();\n\n (0, _jquery2['default'])(opts.openSelector).add((0, _jquery2['default'])(opts.closeSelector)).click(function (e) {\n _scrollTop = (0, _jquery2['default'])(window).scrollTop();\n e.preventDefault();\n });\n\n (0, _jquery2['default'])(opts.panelSelector).on('focus', function () {\n (0, _jquery2['default'])(window).scrollTop(_scrollTop);\n });\n\n _handleModal();\n _handleModalScroll();\n\n _exports.offcanvas = (0, _offcanvas2['default'])(opts);\n});\n\nexports['default'] = _exports;\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// Polyfill matches as per https://github.com/jonathantneal/closest\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nElement.prototype.matches = Element.prototype.matches || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;\n\n/**\n * @param {object} options Object containing configuration overrides\n */\nvar Froffcanvas = function Froffcanvas() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$selector = _ref.selector,\n selector = _ref$selector === undefined ? '.js-fr-offcanvas' : _ref$selector,\n _ref$openSelector = _ref.openSelector,\n openSelector = _ref$openSelector === undefined ? '.js-fr-offcanvas-open' : _ref$openSelector,\n _ref$closeSelector = _ref.closeSelector,\n closeSelector = _ref$closeSelector === undefined ? '.js-fr-offcanvas-close' : _ref$closeSelector,\n _ref$readyClass = _ref.readyClass,\n readyClass = _ref$readyClass === undefined ? 'fr-offcanvas--is-ready' : _ref$readyClass,\n _ref$activeClass = _ref.activeClass,\n activeClass = _ref$activeClass === undefined ? 'fr-offcanvas--is-active' : _ref$activeClass;\n\n // CONSTANTS\n var doc = document;\n var docEl = doc.documentElement;\n var _q = function _q(el) {\n var ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : doc;\n return [].slice.call(ctx.querySelectorAll(el));\n };\n\n // SUPPORTS\n if (!('querySelector' in doc) || !('addEventListener' in window) || !docEl.classList) return;\n\n // SETUP\n // set offcanvas element NodeLists\n var panels = _q(selector);\n\n // TEMP\n var currButtonOpen = null;\n var currPanel = null;\n\n // UTILS\n function _defer(fn) {\n // wrapped in setTimeout to delay binding until previous rendering has completed\n if (typeof fn === 'function') setTimeout(fn, 0);\n }\n function _closest(el, selector) {\n while (el) {\n if (el.matches(selector)) break;\n el = el.parentElement;\n }\n return el;\n }\n function _getPanelId(panel) {\n return panel.getAttribute('id');\n }\n\n // A11Y\n function _addA11y(panel) {\n // add aria-hidden attribute\n panel.setAttribute('aria-hidden', true);\n }\n function _removeA11y(panel) {\n // remove aria-hidden attribute\n panel.removeAttribute('aria-hidden');\n }\n\n // ACTIONS\n function _showPanel(panel) {\n // set visibility to override any previous set style\n panel.style.visibility = 'visible';\n // remove aria-hidden, add focus\n panel.setAttribute('aria-hidden', false);\n panel.setAttribute('tabindex', -1);\n panel.focus();\n // sort out events\n _defer(_unbindOpenPointer);\n _defer(_bindDocKey);\n _defer(_bindDocClick);\n _defer(_bindClosePointer);\n // reset scroll position\n panel.scrollTop = 0;\n // add active class\n panel.classList.add(activeClass);\n }\n function _hidePanel() {\n var panel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : currPanel;\n var returnfocus = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n // add aria-hidden, remove focus\n panel.setAttribute('aria-hidden', true);\n panel.removeAttribute('tabindex');\n panel.blur();\n // set visibility to override any previous set style\n panel.style.visibility = 'hidden';\n // sort out events\n _unbindClosePointer(panel);\n _unbindDocKey();\n _unbindDocClick();\n _bindOpenPointer(panel);\n // remove active class\n panel.classList.remove(activeClass);\n // return focus to button that opened the panel and reset the reference\n if (returnfocus) {\n currButtonOpen.focus();\n currButtonOpen = null;\n }\n }\n function destroy() {\n panels.forEach(function (panel) {\n // remove attributes\n _removeA11y(panel);\n // unbind local events\n _unbindOpenPointer(panel);\n _unbindClosePointer(panel);\n // remove class\n panel.classList.remove(readyClass);\n panel.classList.remove(activeClass);\n panel.style.visibility = '';\n });\n // unbind global events\n _unbindDocClick();\n _unbindDocKey();\n // reset temp references\n currButtonOpen = null;\n currPanel = null;\n }\n\n // EVENTS\n function _eventOpenPointer(e) {\n // get panel\n var panelId = e.currentTarget.getAttribute('aria-controls');\n var panel = doc.getElementById(panelId);\n // hide any open panels\n if (currPanel) _hidePanel(currPanel, false);\n // save temp panel/button\n currButtonOpen = e.currentTarget;\n currPanel = panel;\n // show\n _showPanel(panel);\n }\n function _eventClosePointer() {\n _hidePanel();\n }\n function _eventDocClick(e) {\n // check if target is panel or child of\n var isPanel = e.target === currPanel;\n var isPanelChild = _closest(e.target, selector);\n if (!isPanel && !isPanelChild) _hidePanel();\n }\n function _eventDocKey(e) {\n // esc key\n if (e.keyCode === 27) _hidePanel();\n }\n\n // BIND EVENTS\n function _bindOpenPointer(panel) {\n var openButtons = _q(openSelector + '[aria-controls=\"' + _getPanelId(panel) + '\"]'); // is this selector totally crazy?\n openButtons.forEach(function (button) {\n return button.addEventListener('click', _eventOpenPointer);\n });\n }\n function _bindClosePointer() {\n var panel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : currPanel;\n\n var closeButton = _q(closeSelector, panel)[0];\n closeButton.addEventListener('click', _eventClosePointer);\n }\n function _bindDocClick() {\n doc.addEventListener('click', _eventDocClick);\n }\n function _bindDocKey() {\n doc.addEventListener('keydown', _eventDocKey);\n }\n\n // UNBIND EVENTS\n function _unbindOpenPointer() {\n var panel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : currPanel;\n\n var openButtons = _q(openSelector + '[aria-controls=\"' + _getPanelId(panel) + '\"]'); // yep its totally crazy\n openButtons.forEach(function (button) {\n return button.removeEventListener('click', _eventOpenPointer);\n });\n }\n function _unbindClosePointer() {\n var panel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : currPanel;\n\n var closeButton = _q(closeSelector, panel)[0];\n closeButton.removeEventListener('click', _eventClosePointer);\n }\n function _unbindDocClick() {\n doc.removeEventListener('click', _eventDocClick);\n }\n function _unbindDocKey() {\n doc.removeEventListener('keydown', _eventDocKey);\n }\n\n // INIT\n function init() {\n if (!panels) return;\n // loop through each offcanvas element\n panels.forEach(function (panel) {\n _addA11y(panel);\n _bindOpenPointer(panel);\n panel.classList.add(readyClass);\n });\n }\n init();\n\n // REVEAL API\n return {\n init: init,\n destroy: destroy\n };\n};\n\n// module exports\nexports['default'] = Froffcanvas;\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _jquery = __webpack_require__(0);\n\nvar _jquery2 = _interopRequireDefault(_jquery);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/*\r\n * Randomize order of children in container (.js-randomize)\r\n */\n(0, _jquery2['default'])(function () {\n var CONTAINER_SELECTOR = '.js-randomize';\n var EXCLUDE_SELECTOR = '.js-randomize-exclude';\n\n function shuffle(o) {\n for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x) {}\n return o;\n }\n\n (0, _jquery2['default'])(CONTAINER_SELECTOR).each(function (i, container) {\n var $container = (0, _jquery2['default'])(container);\n $container.html(shuffle($container.children().not(EXCLUDE_SELECTOR).get()));\n });\n});\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _jquery = __webpack_require__(0);\n\nvar _jquery2 = _interopRequireDefault(_jquery);\n\nvar _throttle = __webpack_require__(3);\n\nvar _throttle2 = _interopRequireDefault(_throttle);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar threshold = 100;\n\nvar _toggleScrolltop = function _toggleScrolltop() {\n (0, _jquery2['default'])(window).scrollTop() > threshold ? (0, _jquery2['default'])('.js-scrollTop').show() : (0, _jquery2['default'])('.js-scrollTop').hide();\n};\n\n(0, _jquery2['default'])(window).scroll((0, _throttle2['default'])(500, _toggleScrolltop));\n(0, _jquery2['default'])(document).ready(_toggleScrolltop);\n\nexports['default'] = {\n threshold: threshold\n};\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _frBypasslinks = __webpack_require__(26);\n\nvar _frBypasslinks2 = _interopRequireDefault(_frBypasslinks);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar bypassLinks = (0, _frBypasslinks2['default'])({\n selector: '.js-fr-bypasslinks'\n});\n\nexports['default'] = { bypassLinks: bypassLinks, Frbypasslinks: _frBypasslinks2['default'] };\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/**\n * @param {object} options Object containing configuration overrides\n */\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nvar Frbypasslinks = function Frbypasslinks() {\n\tvar _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n\t _ref$selector = _ref.selector,\n\t selector = _ref$selector === undefined ? '.js-fr-bypasslinks' : _ref$selector;\n\n\t//\tCONSTANTS\n\tvar doc = document;\n\tvar _q = function _q(el) {\n\t\tvar ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : doc;\n\t\treturn [].slice.call(ctx.querySelectorAll(el));\n\t};\n\n\t//\tSUPPORTS\n\tif (!('querySelector' in doc) || !('addEventListener' in window)) return;\n\n\t//\tSETUP\n\t// get bypass links NodeList\n\tvar container = _q(selector)[0];\n\n\t//\tTEMP\n\tvar currTarget = null;\n\n\t//\tACTIONS\n\tfunction _addFocusability(link) {\n\t\t//\tget target element\n\t\tvar id = link.getAttribute('href').slice(1);\n\t\tvar target = doc.getElementById(id);\n\t\t//\tset tabindex to allow focus\n\t\tif (target) target.setAttribute('tabindex', -1);\n\t}\n\tfunction _removeFocusability(link) {\n\t\t//\tget target element\n\t\tvar id = link.getAttribute('href').slice(1);\n\t\tvar target = doc.getElementById(id);\n\t\t//\tremove ability to focus (stops user highlighting element on click)\n\t\tif (target) target.removeAttribute('tabindex');\n\t}\n\tfunction destroy() {\n\t\t//\tloop through each bypass link and remove event bindings\n\t\t_q('a', container).forEach(function (link) {\n\t\t\t_unbindPointerClick(link);\n\t\t\t_addFocusability(link);\n\t\t});\n\t\tif (currTarget) _unbindTargetBlur(currTarget);\n\t}\n\n\t//\tEVENTS\n\tfunction _eventPointerClick(e) {\n\t\t//\tget target element\n\t\tvar id = e.target.getAttribute('href').slice(1);\n\t\tvar target = doc.getElementById(id);\n\n\t\t// don't try to apply relevant atts/focus if target isn't present\n\t\tif (!target) return;\n\t\t//\tset tabindex to allow focus\n\t\ttarget.setAttribute('tabindex', -1);\n\t\ttarget.focus();\n\t\t//\tsave target reference\n\t\tcurrTarget = target;\n\t\t//\tbind blur event on target\n\t\t_bindTargetBlur(target);\n\t}\n\tfunction _eventTargetBlur(e) {\n\t\t//\tremove ability to focus (stops user highlighting element on click)\n\t\te.target.removeAttribute('tabindex');\n\t\t//\tremove target reference\n\t\tcurrTarget = null;\n\t\t//\tunbind blur event\n\t\t_unbindTargetBlur(e.target);\n\t}\n\n\t//\tBIND EVENTS\n\tfunction _bindPointerClick(link) {\n\t\t//\tbind interaction event\n\t\tlink.addEventListener('click', _eventPointerClick);\n\t}\n\tfunction _bindTargetBlur(target) {\n\t\t//\tbind blur event on target element\n\t\ttarget.addEventListener('blur', _eventTargetBlur);\n\t}\n\n\t//\tUNBIND EVENTS\n\tfunction _unbindPointerClick(link) {\n\t\t//\tunbind interaction event\n\t\tlink.removeEventListener('click', _eventPointerClick);\n\t}\n\tfunction _unbindTargetBlur(target) {\n\t\t//\tunbind blur event on target element\n\t\ttarget.removeEventListener('blur', _eventTargetBlur);\n\t}\n\n\t//\tINIT\n\tfunction init() {\n\t\t//\tdetect if bypass links exist in the document\n\t\tif (!container) return;\n\t\t//\tloop through each bypass link\n\t\t_q('a', container).forEach(function (link) {\n\t\t\t_bindPointerClick(link);\n\t\t\t_removeFocusability(link);\n\t\t});\n\t}\n\tinit();\n\n\t// REVEAL API\n\treturn {\n\t\tinit: init,\n\t\tdestroy: destroy\n\t};\n};\n\n// module exports\nexports['default'] = Frbypasslinks;\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _jquery = __webpack_require__(0);\n\nvar _jquery2 = _interopRequireDefault(_jquery);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar opts = {\n responsiveTableSelector: '.js-TableResponsive'\n};\n\n(0, _jquery2['default'])(document).ready(function () {\n if ((0, _jquery2['default'])(opts.responsiveTableSelector).length > 0) {\n __webpack_require__.e/* require */(2).then(function() { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(45), __webpack_require__(46)]; (function () {\n (0, _jquery2['default'])(document).trigger('enhance.tablesaw');\n }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));}).catch(__webpack_require__.oe);\n }\n});\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _jquery = __webpack_require__(0);\n\nvar _jquery2 = _interopRequireDefault(_jquery);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/*\r\n *\tTODO:\r\n *\t\t- repack as a frend _component and CSS\r\n *\t\t- refactor without jQuery\r\n */\n\n/*\r\n * Porting of http://www.oaa-accessibility.org/examplep/treeview1/\r\n */\nvar Treeview = function Treeview() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$selector = _ref.selector,\n selector = _ref$selector === undefined ? '.js-Treeview' : _ref$selector,\n _ref$classFocused = _ref.classFocused,\n classFocused = _ref$classFocused === undefined ? 'hasFocus' : _ref$classFocused,\n _ref$classParent = _ref.classParent,\n classParent = _ref$classParent === undefined ? 'Treeview-parent' : _ref$classParent,\n _ref$classMenuHandler = _ref.classMenuHandler,\n classMenuHandler = _ref$classMenuHandler === undefined ? 'js-Treeview-handler' : _ref$classMenuHandler,\n _ref$styleMenuHandler = _ref.styleMenuHandler,\n styleMenuHandler = _ref$styleMenuHandler === undefined ? 'Treeview-handler--default' : _ref$styleMenuHandler,\n _ref$styleMenuHandler2 = _ref.styleMenuHandlerStandalone,\n styleMenuHandlerStandalone = _ref$styleMenuHandler2 === undefined ? 'Treeview-handler--standalone' : _ref$styleMenuHandler2,\n _ref$ariaLabelHandler = _ref.ariaLabelHandler,\n ariaLabelHandler = _ref$ariaLabelHandler === undefined ? 'expand' : _ref$ariaLabelHandler,\n _ref$multiselectable = _ref.multiselectable,\n multiselectable = _ref$multiselectable === undefined ? true : _ref$multiselectable,\n _ref$animationMs = _ref.animationMs,\n animationMs = _ref$animationMs === undefined ? 100 : _ref$animationMs;\n\n var keys = {\n tab: 9,\n enter: 13,\n space: 32,\n pageup: 33,\n pagedown: 34,\n end: 35,\n home: 36,\n left: 37,\n up: 38,\n right: 39,\n down: 40,\n asterisk: 106\n };\n\n function _collapseAll(treeview) {\n treeview.$parents.each(function () {\n if ((0, _jquery2['default'])(this).attr('aria-expanded') == 'false') {\n (0, _jquery2['default'])(this).children('ul').attr('aria-hidden', 'true');\n }\n });\n treeview.$visibleItems = treeview.$el.find('li:visible');\n }\n\n function _expandGroup(treeview, $item) {\n var $group = $item.children('ul');\n $group.slideDown(animationMs, function () {\n $group.attr('aria-hidden', 'false');\n $item.attr('aria-expanded', 'true');\n treeview.$visibleItems = treeview.$el.find('li:visible');\n });\n }\n\n function _collapseGroup(treeview, $item) {\n var $group = $item.children('ul');\n $group.slideUp(animationMs, function () {\n $group.attr('aria-hidden', 'true');\n $item.attr('aria-expanded', 'false');\n treeview.$visibleItems = treeview.$el.find('li:visible');\n });\n }\n\n function _collapseSiblings(treeview, $item) {\n $item.closest('ul').find('> .' + classParent).not($item).each(function (i, el) {\n _collapseGroup(treeview, (0, _jquery2['default'])(el));\n });\n }\n\n function _toggleGroup(treeview, $item) {\n if (!multiselectable) {\n _collapseSiblings(treeview, $item);\n }\n if ($item.attr('aria-expanded') == 'true') {\n _collapseGroup(treeview, $item);\n } else {\n _expandGroup(treeview, $item);\n }\n }\n\n function _updateStyling(treeview, $item) {\n treeview.$items.removeClass(classFocused);\n $item.addClass(classFocused);\n }\n\n function _handleKeyDown(treeview, $item, e) {\n var curNdx = treeview.$visibleItems.index($item);\n\n if (e.altKey || e.ctrlKey || e.shiftKey && e.keyCode != keys.tab) {\n return true;\n }\n\n // if (!$(e.currentTarget).is('.' + classMenuHandler)) {\n // return true\n // }\n\n switch (e.keyCode) {\n case keys.tab:\n {\n treeview.$activeItem = null;\n $item.removeClass(classFocused);\n return true;\n }\n\n case keys.home:\n {\n treeview.$activeItem = treeview.$parents.first();\n treeview.$activeItem.find(':focusable:first').focus();\n e.stopPropagation();\n return false;\n }\n\n case keys.end:\n {\n treeview.$activeItem = treeview.$visibleItems.last();\n treeview.$activeItem.find(':focusable:first').focus();\n e.stopPropagation();\n return false;\n }\n\n case keys.enter:\n case keys.space:\n {\n if ((0, _jquery2['default'])(e.currentTarget).is('.' + classMenuHandler)) {\n _toggleGroup(treeview, $item);\n e.stopPropagation();\n return false;\n }\n return true;\n }\n\n case keys.left:\n {\n if ($item.is('.' + classParent) && $item.attr('aria-expanded') == 'true') {\n _collapseGroup(treeview, $item);\n } else {\n var $itemUL = $item.parent();\n var $itemParent = $itemUL.parent();\n treeview.$activeItem = $itemParent;\n treeview.$activeItem.find(':focusable:first').focus();\n }\n e.stopPropagation();\n return false;\n }\n\n case keys.right:\n {\n if (!$item.is('.' + classParent)) {\n // do nothing\n } else if ($item.attr('aria-expanded') == 'false') {\n _expandGroup(treeview, $item);\n } else {\n treeview.$activeItem = $item.children('ul').children('li').first();\n treeview.$activeItem.find(':focusable:first').focus();\n }\n e.stopPropagation();\n return false;\n }\n\n case keys.up:\n {\n if (curNdx > 0) {\n var $prev = treeview.$visibleItems.eq(curNdx - 1);\n treeview.$activeItem = $prev;\n $prev.find(':focusable:first').focus();\n }\n e.stopPropagation();\n return false;\n }\n\n case keys.down:\n {\n if (curNdx < treeview.$visibleItems.length - 1) {\n var $next = treeview.$visibleItems.eq(curNdx + 1);\n treeview.$activeItem = $next;\n $next.find(':focusable:first').focus();\n }\n e.stopPropagation();\n return false;\n }\n\n case keys.asterisk:\n {\n treeview.$parents.each(function () {\n _expandGroup(treeview, (0, _jquery2['default'])(this));\n });\n e.stopPropagation();\n return false;\n }\n\n }\n return true;\n }\n\n function _handleKeyPress(treeview, $item, e) {\n if (e.altKey || e.ctrlKey || e.shiftKey) {\n // do nothing\n return true;\n }\n\n switch (e.keyCode) {\n case keys.tab:\n {\n return true;\n }\n case keys.enter:\n case keys.home:\n case keys.end:\n case keys.left:\n case keys.right:\n case keys.up:\n case keys.down:\n {\n e.stopPropagation();\n return false;\n }\n default:\n {\n var chr = String.fromCharCode(e.which);\n var bMatch = false;\n var itemNdx = treeview.$visibleItems.index($item);\n var itemCnt = treeview.$visibleItems.length;\n var curNdx = itemNdx + 1;\n\n // check if the active item was the last one on the list\n if (curNdx == itemCnt) {\n curNdx = 0;\n }\n\n // Iterate through the menu items (starting from the current item and wrapping) until a match is found\n // or the loop returns to the current menu item\n while (curNdx != itemNdx) {\n\n var $curItem = treeview.$visibleItems.eq(curNdx);\n var titleChr = $curItem.text().charAt(0);\n\n if ($curItem.is('.' + classParent)) {\n titleChr = $curItem.find('span').text().charAt(0);\n }\n\n if (titleChr.toLowerCase() == chr) {\n bMatch = true;\n break;\n }\n\n curNdx = curNdx + 1;\n\n if (curNdx == itemCnt) {\n // reached the end of the list, start again at the beginning\n curNdx = 0;\n }\n }\n\n if (bMatch == true) {\n treeview.$activeItem = treeview.$visibleItems.eq(curNdx);\n treeview.$activeItem.find(':focusable:first').focus();\n }\n\n e.stopPropagation();\n return false;\n }\n }\n\n return true;\n }\n\n function _handleClick(treeview, $item, e) {\n if (e.altKey || e.ctrlKey || e.shiftKey) {\n // do nothing\n return true;\n }\n\n // closest('li')\n var $parent = $item.closest('li');\n\n treeview.$activeItem = $parent;\n _updateStyling(treeview, $parent);\n _toggleGroup(treeview, $parent);\n\n e.stopPropagation();\n return false;\n }\n\n function _bindEvents(treeview) {\n treeview.$handlers.click(function (e) {\n return _handleClick(treeview, (0, _jquery2['default'])(this), e);\n });\n\n treeview.$items.keydown(function (e) {\n return _handleKeyDown(treeview, (0, _jquery2['default'])(this), e);\n });\n\n treeview.$items.keypress(function (e) {\n return _handleKeyPress(treeview, (0, _jquery2['default'])(this), e);\n });\n\n treeview.$handlers.keydown(function (e) {\n return _handleKeyDown(treeview, (0, _jquery2['default'])(this).closest('li'), e);\n });\n\n treeview.$handlers.keypress(function (e) {\n return _handleKeyPress(treeview, (0, _jquery2['default'])(this).closest('li'), e);\n });\n\n (0, _jquery2['default'])(document).click(function () {\n if (treeview.$activeItem != null) {\n treeview.$activeItem.removeClass(classFocused);\n treeview.$activeItem = null;\n }\n return true;\n });\n }\n\n function destroy() {\n /* TODO */\n }\n\n function _addA11y($el) {\n $el.attr('role', 'tree');\n\n // Put role=\"treeitem\" on every LI\n // Put aria-expanded=\"false\" on every LI (if it has no aria-expanded attr)\n // Put tabindex=\"-1\" on every LI (if it's not the first one)\n // Put class=