text: /*!
   * tabbyjs v12.0.3
   * Lightweight, accessible vanilla JS toggle tabs.
   * (c) 2019 Chris Ferdinandi
   * MIT License
   * http://github.com/cferdinandi/tabby
   */
  
  /**
   * Element.matches() polyfill (simple version)
   * https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
   */
  if (!Element.prototype.matches) {
  	Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
  }
  (function (root, factory) {
  	if ( typeof define === 'function' && define.amd ) {
  		define([], (function () {
  			return factory(root);
  		}));
  	} else if ( typeof exports === 'object' ) {
  		module.exports = factory(root);
  	} else {
  		root.Tabby = factory(root);
  	}
  })(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) {
  
  	'use strict';
  
  	//
  	// Variables
  	//
  
  	var defaults = {
  		idPrefix: 'tabby-toggle_',
  		default: '[data-tabby-default]'
  	};
  
  
  	//
  	// Methods
  	//
  
  	/**
  	 * Merge two or more objects together.
  	 * @param   {Object}   objects  The objects to merge together
  	 * @returns {Object}            Merged values of defaults and options
  	 */
  	var extend = function () {
  		var merged = {};
  		Array.prototype.forEach.call(arguments, (function (obj) {
  			for (var key in obj) {
  				if (!obj.hasOwnProperty(key)) return;
  				merged[key] = obj[key];
  			}
  		}));
  		return merged;
  	};
  
  	/**
  	 * Emit a custom event
  	 * @param  {String} type    The event type
  	 * @param  {Node}   tab     The tab to attach the event to
  	 * @param  {Node}   details Details about the event
  	 */
  	var emitEvent = function (tab, details) {
  
  		// Create a new event
  		var event;
  		if (typeof window.CustomEvent === 'function') {
  			event = new CustomEvent('tabby', {
  				bubbles: true,
  				cancelable: true,
  				detail: details
  			});
  		} else {
  			event = document.createEvent('CustomEvent');
  			event.initCustomEvent('tabby', true, true, details);
  		}
  
  		// Dispatch the event
  		tab.dispatchEvent(event);
  
  	};
  
  	/**
  	 * Remove roles and attributes from a tab and its content
  	 * @param  {Node}   tab      The tab
  	 * @param  {Node}   content  The tab content
  	 * @param  {Object} settings User settings and options
  	 */
  	var destroyTab = function (tab, content, settings) {
  
  		// Remove the generated ID
  		if (tab.id.slice(0, settings.idPrefix.length) === settings.idPrefix) {
  			tab.id = '';
  		}
  
  		// Remove roles
  		tab.removeAttribute('role');
  		tab.removeAttribute('aria-controls');
  		tab.removeAttribute('aria-selected');
  		tab.removeAttribute('tabindex');
  		tab.closest('li').removeAttribute('role');
  		content.removeAttribute('role');
  		content.removeAttribute('aria-labelledby');
  		content.removeAttribute('hidden');
  
  	};
  
  	/**
  	 * Add the required roles and attributes to a tab and its content
  	 * @param  {Node}   tab      The tab
  	 * @param  {Node}   content  The tab content
  	 * @param  {Object} settings User settings and options
  	 */
  	var setupTab = function (tab, content, settings) {
  
  		// Give tab an ID if it doesn't already have one
  		if (!tab.id) {
  			tab.id = settings.idPrefix + content.id;
  		}
  
  		// Add roles
  		tab.setAttribute('role', 'tab');
  		tab.setAttribute('aria-controls', content.id);
  		tab.closest('li').setAttribute('role', 'presentation');
  		content.setAttribute('role', 'tabpanel');
  		content.setAttribute('aria-labelledby', tab.id);
  
  		// Add selected state
  		if (tab.matches(settings.default)) {
  			tab.setAttribute('aria-selected', 'true');
  		} else {
  			tab.setAttribute('aria-selected', 'false');
  			tab.setAttribute('tabindex', '-1');
  			content.setAttribute('hidden', 'hidden');
  		}
  
  	};
  
  	/**
  	 * Hide a tab and its content
  	 * @param  {Node} newTab The new tab that's replacing it
  	 */
  	var hide = function (newTab) {
  
  		// Variables
  		var tabGroup = newTab.closest('[role="tablist"]');
  		if (!tabGroup) return {};
  		var tab = tabGroup.querySelector('[role="tab"][aria-selected="true"]');
  		if (!tab) return {};
  		var content = document.querySelector(tab.hash);
  
  		// Hide the tab
  		tab.setAttribute('aria-selected', 'false');
  		tab.setAttribute('tabindex', '-1');
  
  		// Hide the content
  		if (!content) return {previousTab: tab};
  		content.setAttribute('hidden', 'hidden');
  
  		// Return the hidden tab and content
  		return {
  			previousTab: tab,
  			previousContent: content
  		};
  
  	};
  
  	/**
  	 * Show a tab and its content
  	 * @param  {Node} tab      The tab
  	 * @param  {Node} content  The tab content
  	 */
  	var show = function (tab, content) {
  		tab.setAttribute('aria-selected', 'true');
  		tab.setAttribute('tabindex', '0');
  		content.removeAttribute('hidden');
  		tab.focus();
  	};
  
  	/**
  	 * Toggle a new tab
  	 * @param  {Node} tab The tab to show
  	 */
  	var toggle = function (tab) {
  
  		// Make sure there's a tab to toggle and it's not already active
  		if (!tab || tab.getAttribute('aria-selected') == 'true') return;
  
  		// Variables
  		var content = document.querySelector(tab.hash);
  		if (!content) return;
  
  		// Hide active tab and content
  		var details = hide(tab);
  
  		// Show new tab and content
  		show(tab, content);
  
  		// Add event details
  		details.tab = tab;
  		details.content = content;
  
  		// Emit a custom event
  		emitEvent(tab, details);
  
  	};
  
  	/**
  	 * Get all of the tabs in a tablist
  	 * @param  {Node}   tab  A tab from the list
  	 * @return {Object}      The tabs and the index of the currently active one
  	 */
  	var getTabsMap = function (tab) {
  		var tabGroup = tab.closest('[role="tablist"]');
  		var tabs = tabGroup ? tabGroup.querySelectorAll('[role="tab"]') : null;
  		if (!tabs) return;
  		return {
  			tabs: tabs,
  			index: Array.prototype.indexOf.call(tabs, tab)
  		};
  	};
  
  	/**
  	 * Switch the active tab based on keyboard activity
  	 * @param  {Node} tab The currently active tab
  	 * @param  {Key}  key The key that was pressed
  	 */
  	var switchTabs = function (tab, key) {
  
  		// Get a map of tabs
  		var map = getTabsMap(tab);
  		if (!map) return;
  		var length = map.tabs.length - 1;
  		var index;
  
  		// Go to previous tab
  		if (['ArrowUp', 'ArrowLeft', 'Up', 'Left'].indexOf(key) > -1) {
  			index = map.index < 1 ? length : map.index - 1;
  		}
  
  		// Go to next tab
  		else if (['ArrowDown', 'ArrowRight', 'Down', 'Right'].indexOf(key) > -1) {
  			index = map.index === length ? 0 : map.index + 1;
  		}
  
  		// Go to home
  		else if (key === 'Home') {
  			index = 0;
  
  		}
  
  		// Go to end
  		else if (key === 'End') {
  			index = length;
  		}
  
  		// Toggle the tab
  		toggle(map.tabs[index]);
  
  	};
  
  	/**
  	 * Activate a tab based on the URL
  	 * @param  {String} selector The selector for this instantiation
  	 */
  	var loadFromURL = function (selector) {
  		if (window.location.hash.length < 1) return;
  		var tab = document.querySelector(selector + ' [role="tab"][href*="' + window.location.hash + '"]');
  		toggle(tab);
  	};
  
  	/**
  	 * Create the Constructor object
  	 */
  	var Constructor = function (selector, options) {
  
  		//
  		// Variables
  		//
  
  		var publicAPIs = {};
  		var settings, tabWrapper;
  
  
  		//
  		// Methods
  		//
  
  		publicAPIs.destroy = function () {
  
  			// Get all tabs
  			var tabs = tabWrapper.querySelectorAll('a');
  
  			// Add roles to tabs
  			Array.prototype.forEach.call(tabs, (function (tab) {
  
  				// Get the tab content
  				var content = document.querySelector(tab.hash);
  				if (!content) return;
  
  				// Setup the tab
  				destroyTab(tab, content, settings);
  
  			}));
  
  			// Remove role from wrapper
  			tabWrapper.removeAttribute('role');
  
  			// Remove event listeners
  			document.documentElement.removeEventListener('click', clickHandler, true);
  			tabWrapper.removeEventListener('keydown', keyHandler, true);
  
  			// Reset variables
  			settings = null;
  			tabWrapper = null;
  
  		};
  
  		/**
  		 * Setup the DOM with the proper attributes
  		 */
  		publicAPIs.setup = function () {
  
  			// Variables
  			tabWrapper = document.querySelector(selector);
  			if (!tabWrapper) return;
  			var tabs = tabWrapper.querySelectorAll('a');
  
  			// Add role to wrapper
  			tabWrapper.setAttribute('role', 'tablist');
  
  			// Add roles to tabs
  			Array.prototype.forEach.call(tabs, (function (tab) {
  
  				// Get the tab content
  				var content = document.querySelector(tab.hash);
  				if (!content) return;
  
  				// Setup the tab
  				setupTab(tab, content, settings);
  
  			}));
  
  		};
  
  		/**
  		 * Toggle a tab based on an ID
  		 * @param  {String|Node} id The tab to toggle
  		 */
  		publicAPIs.toggle = function (id) {
  
  			// Get the tab
  			var tab = id;
  			if (typeof id === 'string') {
  				tab = document.querySelector(selector + ' [role="tab"][href*="' + id + '"]');
  			}
  
  			// Toggle the tab
  			toggle(tab);
  
  		};
  
  		/**
  		 * Handle click events
  		 */
  		var clickHandler = function (event) {
  
  			// Only run on toggles
  			var tab = event.target.closest(selector + ' [role="tab"]');
  			if (!tab) return;
  
  			// Prevent link behavior
  			event.preventDefault();
  
  			// Toggle the tab
  			toggle(tab);
  
  		};
  
  		/**
  		 * Handle keydown events
  		 */
  		var keyHandler = function (event) {
  
  			// Only run if a tab is in focus
  			var tab = document.activeElement;
  			if (!tab.matches(selector + ' [role="tab"]')) return;
  
  			// Only run for specific keys
  			if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Up', 'Down', 'Left', 'Right', 'Home', 'End'].indexOf(event.key) < 0) return;
  
  			// Switch tabs
  			switchTabs(tab, event.key);
  
  		};
  
  		/**
  		 * Initialize the instance
  		 */
  		var init = function () {
  
  			// Merge user options with defaults
  			settings = extend(defaults, options || {});
  
  			// Setup the DOM
  			publicAPIs.setup();
  
  			// Load a tab from the URL
  			loadFromURL(selector);
  
  			// Add event listeners
  			document.documentElement.addEventListener('click', clickHandler, true);
  			tabWrapper.addEventListener('keydown', keyHandler, true);
  
  		};
  
  
  		//
  		// Initialize and return the Public APIs
  		//
  
  		init();
  		return publicAPIs;
  
  	};
  
  
  	//
  	// Return the Constructor
  	//
  
  	return Constructor;
  
  }));
  