PageSourceSearch

https://www.hs-anhalt.de/typo3temp/assets/compressed/merged-e63a92…4a36fa2e68a899ee7579208bccc4b.1789634932.js

js hs-anhalt.de collected 2026-09-24 17:33:51 UTC 259,324 bytes, 7,649 lines download raw bytes

1
2/**
3 * what-input - A global utility for tracking the current input method (mouse, keyboard or touch).
4 * @version v4.0.6
5 * @link https://github.com/ten1seven/what-input
6 * @license MIT
7 */
8!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("whatInput",[],t):"object"==typeof exports?exports.whatInput=t():e.whatInput=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t){e.exports=function(){var e=document.documentElement,t="initial",n=null,o=["input","select","textarea"],i=[16,17,18,91,93],r={keyup:"keyboard",mousedown:"mouse",mousemove:"mouse",MSPointerDown:"pointer",MSPointerMove:"pointer",pointerdown:"pointer",pointermove:"pointer",touchstart:"touch"},u=[],d=!1,a={2:"touch",3:"touch",4:"mouse"},p=null,s=function(){r[h()]="mouse",c(),m()},c=function(){window.PointerEvent?(e.addEventListener("pointerdown",f),e.addEventListener("pointermove",w)):window.MSPointerEvent?(e.addEventListener("MSPointerDown",f),e.addEventListener("MSPointerMove",w)):(e.addEventListener("mousedown",f),e.addEventListener("mousemove",w),"ontouchstart"in window&&e.addEventListener("touchstart",v)),e.addEventListener(h(),w),e.addEventListener("keydown",f),e.addEventListener("keyup",f)},f=function(e){if(!d){var u=e.which,a=r[e.type];if("pointer"===a&&(a=l(e)),t!==a||n!==a){var p=document.activeElement,s=!(!p||!p.nodeName||o.indexOf(p.nodeName.toLowerCase())!==-1);("touch"===a||"mouse"===a&&i.indexOf(u)===-1||"keyboard"===a&&s)&&(t=n=a,m())}}},m=function(){e.setAttribute("data-whatinput",t),e.setAttribute("data-whatintent",t),u.indexOf(t)===-1&&(u.push(t),e.className+=" whatinput-types-"+t)},w=function(t){if(!d){var o=r[t.type];"pointer"===o&&(o=l(t)),n!==o&&(n=o,e.setAttribute("data-whatintent",n))}},v=function(e){window.clearTimeout(p),f(e),d=!0,p=window.setTimeout(function(){d=!1},200)},l=function(e){return"number"==typeof e.pointerType?a[e.pointerType]:"pen"===e.pointerType?"touch":e.pointerType},h=function(){return"onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll"};return"addEventListener"in window&&Array.prototype.indexOf&&s(),{ask:function(e){return"loose"===e?n:t},types:function(){return u}}}()}])});
9!function ($) {
10
11  "use strict";
12
13  var FOUNDATION_VERSION = '6.3.1';
14
15  // Global Foundation object
16  // This is attached to the window, or used as a module for AMD/Browserify
17  var Foundation = {
18    version: FOUNDATION_VERSION,
19
20    /**
21     * Stores initialized plugins.
22     */
23    _plugins: {},
24
25    /**
26     * Stores generated unique ids for plugin instances
27     */
28    _uuids: [],
29
30    /**
31     * Returns a boolean for RTL support
32     */
33    rtl: function () {
34      return $('html').attr('dir') === 'rtl';
35    },
36    /**
37     * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing.
38     * @param {Object} plugin - The constructor of the plugin.
39     */
40    plugin: function (plugin, name) {
41      // Object key to use when adding to global Foundation object
42      // Examples: Foundation.Reveal, Foundation.OffCanvas
43      var className = name || functionName(plugin);
44      // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin
45      // Examples: data-reveal, data-off-canvas
46      var attrName = hyphenate(className);
47
48      // Add to the Foundation object and the plugins list (for reflowing)
49      this._plugins[attrName] = this[className] = plugin;
50    },
51    /**
52     * @function
53     * Populates the _uuids array with pointers to each individual plugin instance.
54     * Adds the `zfPlugin` data-attribute to programmatically created plugins to allow use of $(selector).foundation(method) calls.
55     * Also fires the initialization event for each plugin, consolidating repetitive code.
56     * @param {Object} plugin - an instance of a plugin, usually `this` in context.
57     * @param {String} name - the name of the plugin, passed as a camelCased string.
58     * @fires Plugin#init
59     */
60    registerPlugin: function (plugin, name) {
61      var pluginName = name ? hyphenate(name) : functionName(plugin.constructor).toLowerCase();
62      plugin.uuid = this.GetYoDigits(6, pluginName);
63
64      if (!plugin.$element.attr('data-' + pluginName)) {
65        plugin.$element.attr('data-' + pluginName, plugin.uuid);
66      }
67      if (!plugin.$element.data('zfPlugin')) {
68        plugin.$element.data('zfPlugin', plugin);
69      }
70      /**
71       * Fires when the plugin has initialized.
72       * @event Plugin#init
73       */
74      plugin.$element.trigger('init.zf.' + pluginName);
75
76      this._uuids.push(plugin.uuid);
77
78      return;
79    },
80    /**
81     * @function
82     * Removes the plugins uuid from the _uuids array.
83     * Removes the zfPlugin data attribute, as well as the data-plugin-name attribute.
84     * Also fires the destroyed event for the plugin, consolidating repetitive code.
85     * @param {Object} plugin - an instance of a plugin, usually `this` in context.
86     * @fires Plugin#destroyed
87     */
88    unregisterPlugin: function (plugin) {
89      var pluginName = hyphenate(functionName(plugin.$element.data('zfPlugin').constructor));
90
91      this._uuids.splice(this._uuids.indexOf(plugin.uuid), 1);
92      plugin.$element.removeAttr('data-' + pluginName).removeData('zfPlugin')
93      /**
94       * Fires when the plugin has been destroyed.
95       * @event Plugin#destroyed
96       */
97      .trigger('destroyed.zf.' + pluginName);
98      for (var prop in plugin) {
99        plugin[prop] = null; //clean up script to prep for garbage collection.
100      }
101      return;
102    },
103
104    /**
105     * @function
106     * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc.
107     * @param {String} plugins - optional string of an individual plugin key, attained by calling `$(element).data('pluginName')`, or string of a plugin class i.e. `'dropdown'`
108     * @default If no argument is passed, reflow all currently active plugins.
109     */
110    reInit: function (plugins) {
111      var isJQ = plugins instanceof $;
112      try {
113        if (isJQ) {
114          plugins.each(function () {
115            $(this).data('zfPlugin')._init();
116          });
117        } else {
118          var type = typeof plugins,
119              _this = this,
120              fns = {
121            'object': function (plgs) {
122              plgs.forEach(function (p) {
123                p = hyphenate(p);
124                $('[data-' + p + ']').foundation('_init');
125              });
126            },
127            'string': function () {
128              plugins = hyphenate(plugins);
129              $('[data-' + plugins + ']').foundation('_init');
130            },
131            'undefined': function () {
132              this['object'](Object.keys(_this._plugins));
133            }
134          };
135          fns[type](plugins);
136        }
137      } catch (err) {
138        console.error(err);
139      } finally {
140        return plugins;
141      }
142    },
143
144    /**
145     * returns a random base-36 uid with namespacing
146     * @function
147     * @param {Number} length - number of random base-36 digits desired. Increase for more random strings.
148     * @param {String} namespace - name of plugin to be incorporated in uid, optional.
149     * @default {String} '' - if no plugin name is provided, nothing is appended to the uid.
150     * @returns {String} - unique id
151     */
152    GetYoDigits: function (length, namespace) {
153      length = length || 6;
154      return Math.round(Math.pow(36, length + 1) - Math.random() * Math.pow(36, length)).toString(36).slice(1) + (namespace ? '-' + namespace : '');
155    },
156    /**
157     * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized.
158     * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object.
159     * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything.
160     */
161    reflow: function (elem, plugins) {
162
163      // If plugins is undefined, just grab everything
164      if (typeof plugins === 'undefined') {
165        plugins = Object.keys(this._plugins);
166      }
167      // If plugins is a string, convert it to an array with one item
168      else if (typeof plugins === 'string') {
169          plugins = [plugins];
170        }
171
172      var _this = this;
173
174      // Iterate through each plugin
175      $.each(plugins, function (i, name) {
176        // Get the current plugin
177        var plugin = _this._plugins[name];
178
179        // Localize the search to all elements inside elem, as well as elem itself, unless elem === document
180        var $elem = $(elem).find('[data-' + name + ']').addBack('[data-' + name + ']');
181
182        // For each plugin found, initialize it
183        $elem.each(function () {
184          var $el = $(this),
185              opts = {};
186          // Don't double-dip on plugins
187          if ($el.data('zfPlugin')) {
188            console.warn("Tried to initialize " + name + " on an element that already has a Foundation plugin.");
189            return;
190          }
191
192          if ($el.attr('data-options')) {
193            var thing = $el.attr('data-options').split(';').forEach(function (e, i) {
194              var opt = e.split(':').map(function (el) {
195                return el.trim();
196              });
197              if (opt[0]) opts[opt[0]] = parseValue(opt[1]);
198            });
199          }
200          try {
201            $el.data('zfPlugin', new plugin($(this), opts));
202          } catch (er) {
203            console.error(er);
204          } finally {
205            return;
206          }
207        });
208      });
209    },
210    getFnName: functionName,
211    transitionend: function ($elem) {
212      var transitions = {
213        'transition': 'transitionend',
214        'WebkitTransition': 'webkitTransitionEnd',
215        'MozTransition': 'transitionend',
216        'OTransition': 'otransitionend'
217      };
218      var elem = document.createElement('div'),
219          end;
220
221      for (var t in transitions) {
222        if (typeof elem.style[t] !== 'undefined') {
223          end = transitions[t];
224        }
225      }
226      if (end) {
227        return end;
228      } else {
229        end = setTimeout(function () {
230          $elem.triggerHandler('transitionend', [$elem]);
231        }, 1);
232        return 'transitionend';
233      }
234    }
235  };
236
237  Foundation.util = {
238    /**
239     * Function for applying a debounce effect to a function call.
240     * @function
241     * @param {Function} func - Function to be called at end of timeout.
242     * @param {Number} delay - Time in ms to delay the call of `func`.
243     * @returns function
244     */
245    throttle: function (func, delay) {
246      var timer = null;
247
248      return function () {
249        var context = this,
250            args = arguments;
251
252        if (timer === null) {
253          timer = setTimeout(function () {
254            func.apply(context, args);
255            timer = null;
256          }, delay);
257        }
258      };
259    }
260  };
261
262  // TODO: consider not making this a jQuery function
263  // TODO: need way to reflow vs. re-initialize
264  /**
265   * The Foundation jQuery method.
266   * @param {String|Array} method - An action to perform on the current jQuery object.
267   */
268  var foundation = function (method) {
269    var type = typeof method,
270        $meta = $('meta.foundation-mq'),
271        $noJS = $('.no-js');
272
273    if (!$meta.length) {
274      $('<meta class="foundation-mq">').appendTo(document.head);
275    }
276    if ($noJS.length) {
277      $noJS.removeClass('no-js');
278    }
279
280    if (type === 'undefined') {
281      //needs to initialize the Foundation object, or an individual plugin.
282      Foundation.MediaQuery._init();
283      Foundation.reflow(this);
284    } else if (type === 'string') {
285      //an individual method to invoke on a plugin or group of plugins
286      var args = Array.prototype.slice.call(arguments, 1); //collect all the arguments, if necessary
287      var plugClass = this.data('zfPlugin'); //determine the class of plugin
288
289      if (plugClass !== undefined && plugClass[method] !== undefined) {
290        //make sure both the class and method exist
291        if (this.length === 1) {
292          //if there's only one, call it directly.
293          plugClass[method].apply(plugClass, args);
294        } else {
295          this.each(function (i, el) {
296            //otherwise loop through the jQuery collection and invoke the method on each
297            plugClass[method].apply($(el).data('zfPlugin'), args);
298          });
299        }
300      } else {
301        //error for no class or no method
302        throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.');
303      }
304    } else {
305      //error for invalid argument type
306      throw new TypeError('We\'re sorry, ' + type + ' is not a valid parameter. You must use a string representing the method you wish to invoke.');
307    }
308    return this;
309  };
310
311  window.Foundation = Foundation;
312  $.fn.foundation = foundation;
313
314  // Polyfill for requestAnimationFrame
315  (function () {
316    if (!Date.now || !window.Date.now) window.Date.now = Date.now = function () {
317      return new Date().getTime();
318    };
319
320    var vendors = ['webkit', 'moz'];
321    for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
322      var vp = vendors[i];
323      window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
324      window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];
325    }
326    if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
327      var lastTime = 0;
328      window.requestAnimationFrame = function (callback) {
329        var now = Date.now();
330        var nextTime = Math.max(lastTime + 16, now);
331        return setTimeout(function () {
332          callback(lastTime = nextTime);
333        }, nextTime - now);
334      };
335      window.cancelAnimationFrame = clearTimeout;
336    }
337    /**
338     * Polyfill for performance.now, required by rAF
339     */
340    if (!window.performance || !window.performance.now) {
341      window.performance = {
342        start: Date.now(),
343        now: function () {
344          return Date.now() - this.start;
345        }
346      };
347    }
348  })();
349  if (!Function.prototype.bind) {
350    Function.prototype.bind = function (oThis) {
351      if (typeof this !== 'function') {
352        // closest thing possible to the ECMAScript 5
353        // internal IsCallable function
354        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
355      }
356
357      var aArgs = Array.prototype.slice.call(arguments, 1),
358          fToBind = this,
359          fNOP = function () {},
360          fBound = function () {
361        return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
362      };
363
364      if (this.prototype) {
365        // native functions don't have a prototype
366        fNOP.prototype = this.prototype;
367      }
368      fBound.prototype = new fNOP();
369
370      return fBound;
371    };
372  }
373  // Polyfill to get the name of a function in IE9
374  function functionName(fn) {
375    if (Function.prototype.name === undefined) {
376      var funcNameRegex = /function\s([^(]{1,})\(/;
377      var results = funcNameRegex.exec(fn.toString());
378      return results && results.length > 1 ? results[1].trim() : "";
379    } else if (fn.prototype === undefined) {
380      return fn.constructor.name;
381    } else {
382      return fn.prototype.constructor.name;
383    }
384  }
385  function parseValue(str) {
386    if ('true' === str) return true;else if ('false' === str) return false;else if (!isNaN(str * 1)) return parseFloat(str);
387    return str;
388  }
389  // Convert PascalCase to kebab-case
390  // Thank you: http://stackoverflow.com/a/8955580
391  function hyphenate(str) {
392    return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
393  }
394}(jQuery);
395'use strict';
396
397!function ($) {
398
399  // Default set of media queries
400  var defaultQueries = {
401    'default': 'only screen',
402    landscape: 'only screen and (orientation: landscape)',
403    portrait: 'only screen and (orientation: portrait)',
404    retina: 'only screen and (-webkit-min-device-pixel-ratio: 2),' + 'only screen and (min--moz-device-pixel-ratio: 2),' + 'only screen and (-o-min-device-pixel-ratio: 2/1),' + 'only screen and (min-device-pixel-ratio: 2),' + 'only screen and (min-resolution: 192dpi),' + 'only screen and (min-resolution: 2dppx)'
405  };
406
407  var MediaQuery = {
408    queries: [],
409
410    current: '',
411
412    /**
413     * Initializes the media query helper, by extracting the breakpoint list from the CSS and activating the breakpoint watcher.
414     * @function
415     * @private
416     */
417    _init: function () {
418      var self = this;
419      var extractedStyles = $('.foundation-mq').css('font-family');
420      var namedQueries;
421
422      namedQueries = parseStyleToObject(extractedStyles);
423
424      for (var key in namedQueries) {
425        if (namedQueries.hasOwnProperty(key)) {
426          self.queries.push({
427            name: key,
428            value: 'only screen and (min-width: ' + namedQueries[key] + ')'
429          });
430        }
431      }
432
433      this.current = this._getCurrentSize();
434
435      this._watcher();
436    },
437
438
439    /**
440     * Checks if the screen is at least as wide as a breakpoint.
441     * @function
442     * @param {String} size - Name of the breakpoint to check.
443     * @returns {Boolean} `true` if the breakpoint matches, `false` if it's smaller.
444     */
445    atLeast: function (size) {
446      var query = this.get(size);
447
448      if (query) {
449        return window.matchMedia(query).matches;
450      }
451
452      return false;
453    },
454
455
456    /**
457     * Checks if the screen matches to a breakpoint.
458     * @function
459     * @param {String} size - Name of the breakpoint to check, either 'small only' or 'small'. Omitting 'only' falls back to using atLeast() method.
460     * @returns {Boolean} `true` if the breakpoint matches, `false` if it does not.
461     */
462    is: function (size) {
463      size = size.trim().split(' ');
464      if (size.length > 1 && size[1] === 'only') {
465        if (size[0] === this._getCurrentSize()) return true;
466      } else {
467        return this.atLeast(size[0]);
468      }
469      return false;
470    },
471
472
473    /**
474     * Gets the media query of a breakpoint.
475     * @function
476     * @param {String} size - Name of the breakpoint to get.
477     * @returns {String|null} - The media query of the breakpoint, or `null` if the breakpoint doesn't exist.
478     */
479    get: function (size) {
480      for (var i in this.queries) {
481        if (this.queries.hasOwnProperty(i)) {
482          var query = this.queries[i];
483          if (size === query.name) return query.value;
484        }
485      }
486
487      return null;
488    },
489
490
491    /**
492     * Gets the current breakpoint name by testing every breakpoint and returning the last one to match (the biggest one).
493     * @function
494     * @private
495     * @returns {String} Name of the current breakpoint.
496     */
497    _getCurrentSize: function () {
498      var matched;
499
500      for (var i = 0; i < this.queries.length; i++) {
501        var query = this.queries[i];
502
503        if (window.matchMedia(query.value).matches) {
504          matched = query;
505        }
506      }
507
508      if (typeof matched === 'object') {
509        return matched.name;
510      } else {
511        return matched;
512      }
513    },
514
515
516    /**
517     * Activates the breakpoint watcher, which fires an event on the window whenever the breakpoint changes.
518     * @function
519     * @private
520     */
521    _watcher: function () {
522      var _this = this;
523
524      $(window).on('resize.zf.mediaquery', function () {
525        var newSize = _this._getCurrentSize(),
526            currentSize = _this.current;
527
528        if (newSize !== currentSize) {
529          // Change the current media query
530          _this.current = newSize;
531
532          // Broadcast the media query change on the window
533          $(window).trigger('changed.zf.mediaquery', [newSize, currentSize]);
534        }
535      });
536    }
537  };
538
539  Foundation.MediaQuery = MediaQuery;
540
541  // matchMedia() polyfill - Test a CSS media type/query in JS.
542  // Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license
543  window.matchMedia || (window.matchMedia = function () {
544    'use strict';
545
546    // For browsers that support matchMedium api such as IE 9 and webkit
547
548    var styleMedia = window.styleMedia || window.media;
549
550    // For those that don't support matchMedium
551    if (!styleMedia) {
552      var style = document.createElement('style'),
553          script = document.getElementsByTagName('script')[0],
554          info = null;
555
556      style.type = 'text/css';
557      style.id = 'matchmediajs-test';
558
559      script && script.parentNode && script.parentNode.insertBefore(style, script);
560
561      // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
562      info = 'getComputedStyle' in window && window.getComputedStyle(style, null) || style.currentStyle;
563
564      styleMedia = {
565        matchMedium: function (media) {
566          var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
567
568          // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
569          if (style.styleSheet) {
570            style.styleSheet.cssText = text;
571          } else {
572            style.textContent = text;
573          }
574
575          // Test if media query is true or false
576          return info.width === '1px';
577        }
578      };
579    }
580
581    return function (media) {
582      return {
583        matches: styleMedia.matchMedium(media || 'all'),
584        media: media || 'all'
585      };
586    };
587  }());
588
589  // Thank you: https://github.com/sindresorhus/query-string
590  function parseStyleToObject(str) {
591    var styleObject = {};
592
593    if (typeof str !== 'string') {
594      return styleObject;
595    }
596
597    str = str.trim().slice(1, -1);
597 // browsers re-quote string style values
598
599    if (!str) {
600      return styleObject;
601    }
602
603    styleObject = str.split('&').reduce(function (ret, param) {
604      var parts = param.replace(/\+/g, ' ').split('=');
605      var key = parts[0];
606      var val = parts[1];
607      key = decodeURIComponent(key);
608
609      // missing `=` should be `null`:
610      // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
611      val = val === undefined ? null : decodeURIComponent(val);
612
613      if (!ret.hasOwnProperty(key)) {
614        ret[key] = val;
615      } else if (Array.isArray(ret[key])) {
616        ret[key].push(val);
617      } else {
618        ret[key] = [ret[key], val];
619      }
620      return ret;
621    }, {});
622
623    return styleObject;
624  }
625
626  Foundation.MediaQuery = MediaQuery;
627}(jQuery);
628/*
629 *   This content is licensed according to the W3C Software License at
630 *   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
631 *
632 *   File:   tabs-manual.js
633 *
634 *   Desc:   Tablist widget that implements ARIA Authoring Practices
635 */
636
637'use strict';
638
639class TabsManual {
640    constructor(groupNode) {
641        this.tablistNode = groupNode;
642
643        this.tabs = [];
644
645        this.firstTab = null;
646        this.lastTab = null;
647
648        this.tabs = Array.from(this.tablistNode.querySelectorAll('[role=tab]'));
649        this.tabpanels = [];
650
651        for (var i = 0; i < this.tabs.length; i += 1) {
652            var tab = this.tabs[i];
653            var tabpanel = document.getElementById(tab.getAttribute('aria-controls'));
654
655            tab.tabIndex = -1;
656            tab.setAttribute('aria-selected', 'false');
657            this.tabpanels.push(tabpanel);
658
659            tab.addEventListener('keydown', this.onKeydown.bind(this));
660            tab.addEventListener('click', this.onClick.bind(this));
661
662            if (!this.firstTab) {
663                this.firstTab = tab;
664            }
665            this.lastTab = tab;
666        }
667
668        this.setSelectedTab(this.firstTab);
669    }
670
671    setSelectedTab(currentTab) {
672        for (var i = 0; i < this.tabs.length; i += 1) {
673            var tab = this.tabs[i];
674            if (currentTab === tab) {
675                tab.setAttribute('aria-selected', 'true');
676                tab.removeAttribute('tabindex');
677                this.tabpanels[i].classList.remove('is-hidden');
678            } else {
679                tab.setAttribute('aria-selected', 'false');
680                tab.tabIndex = -1;
681                this.tabpanels[i].classList.add('is-hidden');
682            }
683        }
684    }
685
686    moveFocusToTab(currentTab) {
687        currentTab.focus();
688    }
689
690    moveFocusToPreviousTab(currentTab) {
691        var index;
692
693        if (currentTab === this.firstTab) {
694            this.moveFocusToTab(this.lastTab);
695        } else {
696            index = this.tabs.indexOf(currentTab);
697            this.moveFocusToTab(this.tabs[index - 1]);
698        }
699    }
700
701    moveFocusToNextTab(currentTab) {
702        var index;
703
704        if (currentTab === this.lastTab) {
705            this.moveFocusToTab(this.firstTab);
706        } else {
707            index = this.tabs.indexOf(currentTab);
708            this.moveFocusToTab(this.tabs[index + 1]);
709        }
710    }
711
712    /* EVENT HANDLERS */
713
714    onKeydown(event) {
715        var tgt = event.currentTarget,
716            flag = false;
717
718        switch (event.key) {
719            case 'ArrowLeft':
720                this.moveFocusToPreviousTab(tgt);
721                flag = true;
722                break;
723
724            case 'ArrowRight':
725                this.moveFocusToNextTab(tgt);
726                flag = true;
727                break;
728
729            case 'Home':
730                this.moveFocusToTab(this.firstTab);
731                flag = true;
732                break;
733
734            case 'End':
735                this.moveFocusToTab(this.lastTab);
736                flag = true;
737                break;
738
739            default:
740                break;
741        }
742
743        if (flag) {
744            event.stopPropagation();
745            event.preventDefault();
746        }
747    }
748
749    // Since this example uses buttons for the tabs, the click onr also is activated
750    // with the space and enter keys
751    onClick(event) {
752        this.setSelectedTab(event.currentTarget);
753    }
754}
755
756// Initialize tablist
757
758window.addEventListener('load', function () {
759    var tablists = document.querySelectorAll('[role=tablist].manual');
760    for (var i = 0; i < tablists.length; i++) {
761        new TabsManual(tablists[i]);
762    }
763});
764
765'use strict';
766
767var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
768
769function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
770
771!function ($) {
772
773  /**
774   * Orbit module.
775   * @module foundation.orbit
776   * @requires foundation.util.keyboard
777   * @requires foundation.util.motion
778   * @requires foundation.util.timerAndImageLoader
779   * @requires foundation.util.touch
780   */
781
782  var Orbit = function () {
783    /**
784    * Creates a new instance of an orbit carousel.
785    * @class
786    * @param {jQuery} element - jQuery object to make into an Orbit Carousel.
787    * @param {Object} options - Overrides to the default plugin settings.
788    */
789    function Orbit(element, options) {
790      _classCallCheck(this, Orbit);
791
792      this.$element = element;
793      this.options = $.extend({}, Orbit.defaults, this.$element.data(), options);
794
795      this._init();
796
797      Foundation.registerPlugin(this, 'Orbit');
798      Foundation.Keyboard.register('Orbit', {
799        'ltr': {
800          'ARROW_RIGHT': 'next',
801          'ARROW_LEFT': 'previous'
802        },
803        'rtl': {
804          'ARROW_LEFT': 'next',
805          'ARROW_RIGHT': 'previous'
806        }
807      });
808    }
809
810    /**
811    * Initializes the plugin by creating jQuery collections, setting attributes, and starting the animation.
812    * @function
813    * @private
814    */
815
816
817    _createClass(Orbit, [{
818      key: '_init',
819      value: function _init() {
820        // @TODO: consider discussion on PR #9278 about DOM pollution by changeSlide
821        this._reset();
822
823        this.$wrapper = this.$element.find('.' + this.options.containerClass);
824        this.$slides = this.$element.find('.' + this.options.slideClass);
825
826        var $images = this.$element.find('img'),
827            initActive = this.$slides.filter('.is-active'),
828            id = this.$element[0].id || Foundation.GetYoDigits(6, 'orbit');
829
830        this.$element.attr({
831          'data-resize': id,
832          'id': id
833        });
834
835        if (!initActive.length) {
836          this.$slides.eq(0).addClass('is-active');
837        }
838
839        if (!this.options.useMUI) {
840          this.$slides.addClass('no-motionui');
841        }
842
843        if ($images.length) {
844          Foundation.onImagesLoaded($images, this._prepareForOrbit.bind(this));
845        } else {
846          this._prepareForOrbit(); //hehe
847        }
848
849        if (this.options.bullets) {
850          this._loadBullets();
851        }
852
853        this._events();
854
855        if (this.options.autoPlay && this.$slides.length > 1) {
856          this.geoSync();
857        }
858
859        if (this.options.accessible) {
860          // allow wrapper to be focusable to enable arrow navigation
861          this.$wrapper.attr('tabindex', 0);
862        }
863      }
864
865      /**
866      * Creates a jQuery collection of bullets, if they are being used.
867      * @function
868      * @private
869      */
870
871    }, {
872      key: '_loadBullets',
873      value: function _loadBullets() {
874        this.$bullets = this.$element.find('.' + this.options.boxOfBullets).find('button');
875      }
876
877      /**
878      * Sets a `timer` object on the orbit, and starts the counter for the next slide.
879      * @function
880      */
881
882    }, {
883      key: 'geoSync',
884      value: function geoSync() {
885        var _this = this;
886        this.timer = new Foundation.Timer(this.$element, {
887          duration: this.options.timerDelay,
888          infinite: false
889        }, function () {
890          _this.changeSlide(true);
891        });
892        this.timer.start();
893      }
894
895      /**
896      * Sets wrapper and slide heights for the orbit.
897      * @function
898      * @private
899      */
900
901    }, {
902      key: '_prepareForOrbit',
903      value: function _prepareForOrbit() {
904        var _this = this;
905        this._setWrapperHeight();
906      }
907
908      /**
909      * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height.
910      * @function
911      * @private
912      * @param {Function} cb - a callback function to fire when complete.
913      */
914
915    }, {
916      key: '_setWrapperHeight',
917      value: function _setWrapperHeight(cb) {
918        //rewrite this to `for` loop
919        var max = 0,
920            temp,
921            counter = 0,
922            _this = this;
923
924        this.$slides.each(function () {
925          temp = this.getBoundingClientRect().height;
926          $(this).attr('data-slide', counter);
927
928          if (_this.$slides.filter('.is-active')[0] !== _this.$slides.eq(counter)[0]) {
929            //if not the active slide, set css position and display property
930            $(this).css({ 'position': 'relative', 'display': 'none' });
931          }
932          max = temp > max ? temp : max;
933          counter++;
934        });
935
936        if (counter === this.$slides.length) {
937          this.$wrapper.css({ 'height': max }); //only change the wrapper height property once.
938          if (cb) {
939            cb(max);
940          } //fire callback with max height dimension.
941        }
942      }
943
944      /**
945      * Sets the max-height of each slide.
946      * @function
947      * @private
948      */
949
950    }, {
vendor: 5,174 bytes, lines 951-1100
951      key: '_setSlideHeight',
952      value: function _setSlideHeight(height) {
953        this.$slides.each(function () {
954          $(this).css('max-height', height);
955        });
956      }
957
958      /**
959      * Adds event listeners to basically everything within the element.
960      * @function
961      * @private
962      */
963
964    }, {
965      key: '_events',
966      value: function _events() {
967        var _this = this;
968
969        //***************************************
970        //**Now using custom event - thanks to:**
971        //**      Yohai Ararat of Toronto      **
972        //***************************************
973        //
974        this.$element.off('.resizeme.zf.trigger').on({
975          'resizeme.zf.trigger': this._prepareForOrbit.bind(this)
976        });
977        if (this.$slides.length > 1) {
978
979          if (this.options.swipe) {
980            this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit').on('swipeleft.zf.orbit', function (e) {
981              e.preventDefault();
982              _this.changeSlide(true);
983            }).on('swiperight.zf.orbit', function (e) {
984              e.preventDefault();
985              _this.changeSlide(false);
986            });
987          }
988          //***************************************
989
990          if (this.options.autoPlay) {
991            this.$slides.on('click.zf.orbit', function () {
992              _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true);
993              _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start']();
994            });
995
996            if (this.options.pauseOnHover) {
997              this.$element.on('mouseenter.zf.orbit', function () {
998                _this.timer.pause();
999              }).on('mouseleave.zf.orbit', function () {
1000                if (!_this.$element.data('clickedOn')) {
1001                  _this.timer.start();
1002                }
1003              });
1004            }
1005          }
1006
1007          if (this.options.navButtons) {
1008            var $controls = this.$element.find('.' + this.options.nextClass + ', .' + this.options.prevClass);
1009            $controls.attr('tabindex', 0)
1010            //also need to handle enter/return and spacebar key presses
1011            .on('click.zf.orbit touchend.zf.orbit', function (e) {
1012              e.preventDefault();
1013              _this.changeSlide($(this).hasClass(_this.options.nextClass));
1014            });
1015          }
1016
1017          if (this.options.bullets) {
1018            this.$bullets.on('click.zf.orbit touchend.zf.orbit', function () {
1019              if (/is-active/g.test(this.className)) {
1020                return false;
1021              } //if this is active, kick out of function.
1022              var idx = $(this).data('slide'),
1023                  ltr = idx > _this.$slides.filter('.is-active').data('slide'),
1024                  $slide = _this.$slides.eq(idx);
1025
1026              _this.changeSlide(ltr, $slide, idx);
1027            });
1028          }
1029
1030          if (this.options.accessible) {
1031            this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function (e) {
1032              // handle keyboard event with keyboard util
1033              Foundation.Keyboard.handleKey(e, 'Orbit', {
1034                next: function () {
1035                  _this.changeSlide(true);
1036                },
1037                previous: function () {
1038                  _this.changeSlide(false);
1039                },
1040                handled: function () {
1041                  // if bullet is focused, make sure focus moves
1042                  if ($(e.target).is(_this.$bullets)) {
1043                    _this.$bullets.filter('.is-active').focus();
1044                  }
1045                }
1046              });
1047            });
1048          }
1049        }
1050      }
1051
1052      /**
1053       * Resets Orbit so it can be reinitialized
1054       */
1055
1056    }, {
1057      key: '_reset',
1058      value: function _reset() {
1059        // Don't do anything if there are no slides (first run)
1060        if (typeof this.$slides == 'undefined') {
1061          return;
1062        }
1063
1064        if (this.$slides.length > 1) {
1065          // Remove old events
1066          this.$element.off('.zf.orbit').find('*').off('.zf.orbit');
1067
1068          // Restart timer if autoPlay is enabled
1069          if (this.options.autoPlay) {
1070            this.timer.restart();
1071          }
1072
1073          // Reset all sliddes
1074          this.$slides.each(function (el) {
1075            $(el).removeClass('is-active is-active is-in').removeAttr('aria-live').hide();
1076          });
1077
1078          // Show the first slide
1079          this.$slides.first().addClass('is-active').show();
1080
1081          // Triggers when the slide has finished animating
1082          this.$element.trigger('slidechange.zf.orbit', [this.$slides.first()]);
1083
1084          // Select first bullet if bullets are present
1085          if (this.options.bullets) {
1086            this._updateBullets(0);
1087          }
1088        }
1089      }
1090
1091      /**
1092      * Changes the current slide to a new one.
1093      * @function
1094      * @param {Boolean} isLTR - flag if the slide should move left to right.
1095      * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected.
1096      * @param {Number} idx - the index of the new slide in its collection, if one chosen.
1097      * @fires Orbit#slidechange
1098      */
1099
1100    }, {
1101      key: 'changeSlide',
1102      value: function changeSlide(isLTR, chosenSlide, idx) {
1103        if (!this.$slides) {
1104          return;
1105        } // Don't freak out if we're in the middle of cleanup
1106        var $curSlide = this.$slides.filter('.is-active').eq(0);
1107
1108        if (/mui/g.test($curSlide[0].className)) {
1109          return false;
1110        } //if the slide is currently animating, kick out of the function
1111
1112        var $firstSlide = this.$slides.first(),
1113            $lastSlide = this.$slides.last(),
1114            dirIn = isLTR ? 'Right' : 'Left',
1115            dirOut = isLTR ? 'Left' : 'Right',
1116            _this = this,
1117            $newSlide;
1118
1119        if (!chosenSlide) {
1120          //most of the time, this will be auto played or clicked from the navButtons.
1121          $newSlide = isLTR ? //if wrapping enabled, check to see if there is a `next` or `prev` sibling, if not, select the first or last slide to fill in. if wrapping not enabled, attempt to select `next` or `prev`, if there's nothing there, the function will kick out on next step. CRAZY NESTED TERNARIES!!!!!
1122          this.options.infiniteWrap ? $curSlide.next('.' + this.options.slideClass).length ? $curSlide.next('.' + this.options.slideClass) : $firstSlide : $curSlide.next('.' + this.options.slideClass) : //pick next slide if moving left to right
1123          this.options.infiniteWrap ? $curSlide.prev('.' + this.options.slideClass).length ? $curSlide.prev('.' + this.options.slideClass) : $lastSlide : $curSlide.prev('.' + this.options.slideClass); //pick prev slide if moving right to left
1124        } else {
1125          $newSlide = chosenSlide;
1126        }
1127
1128        if ($newSlide.length) {
1129          /**
1130          * Triggers before the next slide starts animating in and only if a next slide has been found.
1131          * @event Orbit#beforeslidechange
1132          */
1133          this.$element.trigger('beforeslidechange.zf.orbit', [$curSlide, $newSlide]);
1134
1135          if (this.options.bullets) {
1136            idx = idx || this.$slides.index($newSlide); //grab index to update bullets
1137            this._updateBullets(idx);
1138          }
1139
1140          if (this.options.useMUI && !this.$element.is(':hidden')) {
1141            Foundation.Motion.animateIn($newSlide.addClass('is-active').css({ 'position': 'absolute', 'top': 0 }), this.options['animInFrom' + dirIn], function () {
1142              $newSlide.css({ 'position': 'relative', 'display': 'block' }).attr('aria-live', 'polite');
1143            });
1144
1145            Foundation.Motion.animateOut($curSlide.removeClass('is-active'), this.options['animOutTo' + dirOut], function () {
1146              $curSlide.removeAttr('aria-live');
1147              if (_this.options.autoPlay && !_this.timer.isPaused) {
1148                _this.timer.restart();
1149              }
1150              //do stuff?
1151            });
1152          } else {
1153            $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide();
1154            $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show();
1155            if (this.options.autoPlay && !this.timer.isPaused) {
1156              this.timer.restart();
1157            }
1158          }
1159          /**
1160          * Triggers when the slide has finished animating in.
1161          * @event Orbit#slidechange
1162          */
1163          this.$element.trigger('slidechange.zf.orbit', [$newSlide]);
1164        }
1165      }
1166
1167      /**
1168      * Updates the active state of the bullets, if displayed.
1169      * @function
1170      * @private
1171      * @param {Number} idx - the index of the current slide.
1172      */
1173
1174    }, {
1175      key: '_updateBullets',
1176      value: function _updateBullets(idx) {
1177        var $oldBullet = this.$element.find('.' + this.options.boxOfBullets).find('.is-active').removeClass('is-active').blur(),
1178            span = $oldBullet.find('span:last').detach(),
1179            $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span);
1180      }
1181
1182      /**
1183      * Destroys the carousel and hides the element.
1184      * @function
1185      */
1186
1187    }, {
1188      key: 'destroy',
1189      value: function destroy() {
1190        this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide();
1191        Foundation.unregisterPlugin(this);
1192      }
1193    }]);
1194
1195    return Orbit;
1196  }();
1197
1198  Orbit.defaults = {
1199    /**
1200    * Tells the JS to look for and loadBullets.
1201    * @option
1202     * @type {boolean}
1203    * @default true
1204    */
1205    bullets: true,
1206    /**
1207    * Tells the JS to apply event listeners to nav buttons
1208    * @option
1209     * @type {boolean}
1210    * @default true
1211    */
1212    navButtons: true,
1213    /**
1214    * motion-ui animation class to apply
1215    * @option
1216     * @type {string}
1217    * @default 'slide-in-right'
1218    */
1219    animInFromRight: 'slide-in-right',
1220    /**
1221    * motion-ui animation class to apply
1222    * @option
1223     * @type {string}
1224    * @default 'slide-out-right'
1225    */
1226    animOutToRight: 'slide-out-right',
1227    /**
1228    * motion-ui animation class to apply
1229    * @option
1230     * @type {string}
1231    * @default 'slide-in-left'
1232    *
1233    */
1234    animInFromLeft: 'slide-in-left',
1235    /**
1236    * motion-ui animation class to apply
1237    * @option
1238     * @type {string}
1239    * @default 'slide-out-left'
1240    */
1241    animOutToLeft: 'slide-out-left',
1242    /**
1243    * Allows Orbit to automatically animate on page load.
1244    * @option
1245     * @type {boolean}
1246    * @default true
1247    */
1248    autoPlay: true,
1249    /**
1250    * Amount of time, in ms, between slide transitions
1251    * @option
1252     * @type {number}
1253    * @default 5000
1254    */
1255    timerDelay: 5000,
1256    /**
1257    * Allows Orbit to infinitely loop through the slides
1258    * @option
1259     * @type {boolean}
1260    * @default true
1261    */
1262    infiniteWrap: true,
1263    /**
1264    * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library
1265    * @option
1266     * @type {boolean}
1267    * @default true
1268    */
1269    swipe: true,
1270    /**
1271    * Allows the timing function to pause animation on hover.
1272    * @option
1273     * @type {boolean}
1274    * @default true
1275    */
1276    pauseOnHover: true,
1277    /**
1278    * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys
1279    * @option
1280     * @type {boolean}
1281    * @default true
1282    */
1283    accessible: true,
1284    /**
1285    * Class applied to the container of Orbit
1286    * @option
1287     * @type {string}
1288    * @default 'orbit-container'
1289    */
1290    containerClass: 'orbit-container',
1291    /**
1292    * Class applied to individual slides.
1293    * @option
1294     * @type {string}
1295    * @default 'orbit-slide'
1296    */
1297    slideClass: 'orbit-slide',
1298    /**
1299    * Class applied to the bullet container. You're welcome.
1300    * @option
1301     * @type {string}
1302    * @default 'orbit-bullets'
1303    */
1304    boxOfBullets: 'orbit-bullets',
1305    /**
1306    * Class applied to the `next` navigation button.
1307    * @option
1308     * @type {string}
1309    * @default 'orbit-next'
1310    */
1311    nextClass: 'orbit-next',
1312    /**
1313    * Class applied to the `previous` navigation button.
1314    * @option
1315     * @type {string}
1316    * @default 'orbit-previous'
1317    */
1318    prevClass: 'orbit-previous',
1319    /**
1320    * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatability.
1321    * @option
1322     * @type {boolean}
1323    * @default true
1324    */
1325    useMUI: true
1326  };
1327
1328  // Window exports
1329  Foundation.plugin(Orbit, 'Orbit');
1330}(jQuery);
1331'use strict';
1332
1333var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
1334
1335function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1336
1337!function ($) {
1338
1339  /**
1340   * Reveal module.
1341   * @module foundation.reveal
1342   * @requires foundation.util.keyboard
1343   * @requires foundation.util.box
1344   * @requires foundation.util.triggers
1345   * @requires foundation.util.mediaQuery
1346   * @requires foundation.util.motion if using animations
1347   */
1348
1349  var Reveal = function () {
1350    /**
1351     * Creates a new instance of Reveal.
1352     * @class
1353     * @param {jQuery} element - jQuery object to use for the modal.
1354     * @param {Object} options - optional parameters.
1355     */
1356    function Reveal(element, options) {
1357      _classCallCheck(this, Reveal);
1358
1359      this.$element = element;
1360      this.options = $.extend({}, Reveal.defaults, this.$element.data(), options);
1361      this._init();
1362
1363      Foundation.registerPlugin(this, 'Reveal');
1364      Foundation.Keyboard.register('Reveal', {
1365        'ENTER': 'open',
1366        'SPACE': 'open',
1367        'ESCAPE': 'close'
1368      });
1369    }
1370
1371    /**
1372     * Initializes the modal by adding the overlay and close buttons, (if selected).
1373     * @private
1374     */
1375
1376
1377    _createClass(Reveal, [{
1378      key: '_init',
1379      value: function _init() {
1380        this.id = this.$element.attr('id');
1381        this.isActive = false;
1382        this.cached = { mq: Foundation.MediaQuery.current };
1383        this.isMobile = mobileSniff();
1384
1385        this.$anchor = $('[data-open="' + this.id + '"]').length ? $('[data-open="' + this.id + '"]') : $('[data-toggle="' + this.id + '"]');
1386        this.$anchor.attr({
1387          'aria-controls': this.id,
1388          'aria-haspopup': true,
1389          'tabindex': 0
1390        });
1391
1392        if (this.options.fullScreen || this.$element.hasClass('full')) {
1393          this.options.fullScreen = true;
1394          this.options.overlay = false;
1395        }
1396        if (this.options.overlay && !this.$overlay) {
1397          this.$overlay = this._makeOverlay(this.id);
1398        }
1399
1400        this.$element.attr({
1401          'role': 'dialog',
1402          'aria-hidden': true,
1403          'data-yeti-box': this.id,
1404          'data-resize': this.id
1405        });
1406
1407        if (this.$overlay) {
1408          this.$element.detach().appendTo(this.$overlay);
1409        } else {
1410          this.$element.detach().appendTo($(this.options.appendTo));
1411          this.$element.addClass('without-overlay');
1412        }
1413        this._events();
1414        if (this.options.deepLink && window.location.hash === '#' + this.id) {
1415          $(window).one('load.zf.reveal', this.open.bind(this));
1416        }
1417      }
1418
1419      /**
1420       * Creates an overlay div to display behind the modal.
1421       * @private
1422       */
1423
1424    }, {
1425      key: '_makeOverlay',
1426      value: function _makeOverlay() {
1427        return $('<div></div>').addClass('reveal-overlay').appendTo(this.options.appendTo);
1428      }
1429
1430      /**
1431       * Updates position of modal
1432       * TODO:  Figure out if we actually need to cache these values or if it doesn't matter
1433       * @private
1434       */
1435
1436    }, {
1437      key: '_updatePosition',
1438      value: function _updatePosition() {
1439        var width = this.$element.outerWidth();
1440        var outerWidth = $(window).width();
1441        var height = this.$element.outerHeight();
1442        var outerHeight = $(window).height();
1443        var left, top;
1444        if (this.options.hOffset === 'auto') {
1445          left = parseInt((outerWidth - width) / 2, 10);
1446        } else {
1447          left = parseInt(this.options.hOffset, 10);
1448        }
1449        if (this.options.vOffset === 'auto') {
1450          if (height > outerHeight) {
1451            top = parseInt(Math.min(100, outerHeight / 10), 10);
1452          } else {
1453            top = parseInt((outerHeight - height) / 4, 10);
1454          }
1455        } else {
1456          top = parseInt(this.options.vOffset, 10);
1457        }
1458        this.$element.css({ top: top + 'px' });
1459        // only worry about left if we don't have an overlay or we havea  horizontal offset,
1460        // otherwise we're perfectly in the middle
1461        if (!this.$overlay || this.options.hOffset !== 'auto') {
1462          this.$element.css({ left: left + 'px' });
1463          this.$element.css({ margin: '0px' });
1464        }
1465      }
1466
1467      /**
1468       * Adds event handlers for the modal.
1469       * @private
1470       */
1471
1472    }, {
1473      key: '_events',
1474      value: function _events() {
1475        var _this2 = this;
1476
1477        var _this = this;
1478
1479        this.$element.on({
1480          'open.zf.trigger': this.open.bind(this),
1481          'close.zf.trigger': function (event, $element) {
1482            if (event.target === _this.$element[0] || $(event.target).parents('[data-closable]')[0] === $element) {
1483              // only close reveal when it's explicitly called
1484              return _this2.close.apply(_this2);
1485            }
1486          },
1487          'toggle.zf.trigger': this.toggle.bind(this),
1488          'resizeme.zf.trigger': function () {
1489            _this._updatePosition();
1490          }
1491        });
1492
1493        if (this.$anchor.length) {
1494          this.$anchor.on('keydown.zf.reveal', function (e) {
1495            if (e.which === 13 || e.which === 32) {
1496              e.stopPropagation();
1497              e.preventDefault();
1498              _this.open();
1499            }
1500          });
1501        }
1502
1503        if (this.options.closeOnClick && this.options.overlay) {
1504          this.$overlay.off('.zf.reveal').on('click.zf.reveal', function (e) {
1505            if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target) || !$.contains(document, e.target)) {
1506              return;
1507            }
1508            _this.close();
1509          });
1510        }
1511        if (this.options.deepLink) {
1512          $(window).on('popstate.zf.reveal:' + this.id, this._handleState.bind(this));
1513        }
1514      }
1515
1516      /**
1517       * Handles modal methods on back/forward button clicks or any other event that triggers popstate.
1518       * @private
1519       */
1520
1521    }, {
1522      key: '_handleState',
1523      value: function _handleState(e) {
1524        if (window.location.hash === '#' + this.id && !this.isActive) {
1525          this.open();
1526        } else {
1527          this.close();
1528        }
1529      }
1530
1531      /**
1532       * Opens the modal controlled by `this.$anchor`, and closes all others by default.
1533       * @function
1534       * @fires Reveal#closeme
1535       * @fires Reveal#open
1536       */
1537
1538    }, {
1539      key: 'open',
1540      value: function open() {
1541        var _this3 = this;
1542
1543        if (this.options.deepLink) {
1544          var hash = '#' + this.id;
1545
1546          if (window.history.pushState) {
1547            window.history.pushState(null, null, hash);
1548          } else {
1549            window.location.hash = hash;
1550          }
1551        }
1552
1553        this.isActive = true;
1554
1555        // Make elements invisible, but remove display: none so we can get size and positioning
1556        this.$element.css({ 'visibility': 'hidden' }).show().scrollTop(0);
1557        if (this.options.overlay) {
1558          this.$overlay.css({ 'visibility': 'hidden' }).show();
1559        }
1560
1561        this._updatePosition();
1562
1563        this.$element.hide().css({ 'visibility': '' });
1564
1565        if (this.$overlay) {
1566          this.$overlay.css({ 'visibility': '' }).hide();
1567          if (this.$element.hasClass('fast')) {
1568            this.$overlay.addClass('fast');
1569          } else if (this.$element.hasClass('slow')) {
1570            this.$overlay.addClass('slow');
1571          }
1572        }
1573
1574        if (!this.options.multipleOpened) {
1575          /**
1576           * Fires immediately before the modal opens.
1577           * Closes any other modals that are currently open
1578           * @event Reveal#closeme
1579           */
1580          this.$element.trigger('closeme.zf.reveal', this.id);
1581        }
1582
1583        var _this = this;
1584
1585        function addRevealOpenClasses() {
1586          if (_this.isMobile) {
1587            if (!_this.originalScrollPos) {
1588              _this.originalScrollPos = window.pageYOffset;
1589            }
1590            $('html, body').addClass('is-reveal-open');
1591          } else {
1592            $('body').addClass('is-reveal-open');
1593          }
1594        }
1595        // Motion UI method of reveal
1596        if (this.options.animationIn) {
1597          (function () {
1598            var afterAnimation = function () {
1599              _this.$element.attr({
1600                'aria-hidden': false,
1601                'tabindex': -1
1602              }).focus();
1603              addRevealOpenClasses();
1604              Foundation.Keyboard.trapFocus(_this.$element);
1605            };
1606
1607            if (_this3.options.overlay) {
1608              Foundation.Motion.animateIn(_this3.$overlay, 'fade-in');
1609            }
1610            Foundation.Motion.animateIn(_this3.$element, _this3.options.animationIn, function () {
1611              if (_this3.$element) {
1612                // protect against object having been removed
1613                _this3.focusableElements = Foundation.Keyboard.findFocusable(_this3.$element);
1614                afterAnimation();
1615              }
1616            });
1617          })();
1618        }
1619        // jQuery method of reveal
1620        else {
1621            if (this.options.overlay) {
1622              this.$overlay.show(0);
1623            }
1624            this.$element.show(this.options.showDelay);
1625          }
1626
1627        // handle accessibility
1628        this.$element.attr({
1629          'aria-hidden': false,
1630          'tabindex': -1
1631        }).focus();
1632        Foundation.Keyboard.trapFocus(this.$element);
1633
1634        /**
1635         * Fires when the modal has successfully opened.
1636         * @event Reveal#open
1637         */
1638        this.$element.trigger('open.zf.reveal');
1639
1640        addRevealOpenClasses();
1641
1642        setTimeout(function () {
1643          _this3._extraHandlers();
1644        }, 0);
1645      }
1646
1647      /**
1648       * Adds extra event handlers for the body and window if necessary.
1649       * @private
1650       */
1651
1652    }, {
1653      key: '_extraHandlers',
1654      value: function _extraHandlers() {
1655        var _this = this;
1656        if (!this.$element) {
1657          return;
1658        } // If we're in the middle of cleanup, don't freak out
1659        this.focusableElements = Foundation.Keyboard.findFocusable(this.$element);
1660
1661        if (!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen) {
1662          $('body').on('click.zf.reveal', function (e) {
1663            if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target) || !$.contains(document, e.target)) {
1664              return;
1665            }
1666            _this.close();
1667          });
1668        }
1669
1670        if (this.options.closeOnEsc) {
1671          $(window).on('keydown.zf.reveal', function (e) {
1672            Foundation.Keyboard.handleKey(e, 'Reveal', {
1673              close: function () {
1674                if (_this.options.closeOnEsc) {
1675                  _this.close();
1676                  _this.$anchor.focus();
1677                }
1678              }
1679            });
1680          });
1681        }
1682
1683        // lock focus within modal while tabbing
1684        this.$element.on('keydown.zf.reveal', function (e) {
1685          var $target = $(this);
1686          // handle keyboard event with keyboard util
1687          Foundation.Keyboard.handleKey(e, 'Reveal', {
1688            open: function () {
1689              if (_this.$element.find(':focus').is(_this.$element.find('[data-close]'))) {
1690                setTimeout(function () {
1691                  // set focus back to anchor if close button has been activated
1692                  _this.$anchor.focus();
1693                }, 1);
1694              } else if ($target.is(_this.focusableElements)) {
1695                // dont't trigger if acual element has focus (i.e. inputs, links, ...)
1696                _this.open();
1697              }
1698            },
1699            close: function () {
1700              if (_this.options.closeOnEsc) {
1701                _this.close();
1702                _this.$anchor.focus();
1703              }
1704            },
1705            handled: function (preventDefault) {
1706              if (preventDefault) {
1707                e.preventDefault();
1708              }
1709            }
1710          });
1711        });
1712      }
1713
1714      /**
1715       * Closes the modal.
1716       * @function
1717       * @fires Reveal#closed
1718       */
1719
1720    }, {
1721      key: 'close',
1722      value: function close() {
1723        if (!this.isActive || !this.$element.is(':visible')) {
1724          return false;
1725        }
1726        var _this = this;
1727
1728        // Motion UI method of hiding
1729        if (this.options.animationOut) {
1730          if (this.options.overlay) {
1731            Foundation.Motion.animateOut(this.$overlay, 'fade-out', finishUp);
1732          } else {
1733            finishUp();
1734          }
1735
1736          Foundation.Motion.animateOut(this.$element, this.options.animationOut);
1737        }
1738        // jQuery method of hiding
1739        else {
1740            if (this.options.overlay) {
1741              this.$overlay.hide(0, finishUp);
1742            } else {
1743              finishUp();
1744            }
1745
1746            this.$element.hide(this.options.hideDelay);
1747          }
1748
1749        // Conditionals to remove extra event listeners added on open
1750        if (this.options.closeOnEsc) {
1751          $(window).off('keydown.zf.reveal');
1752        }
1753
1754        if (!this.options.overlay && this.options.closeOnClick) {
1755          $('body').off('click.zf.reveal');
1756        }
1757
1758        this.$element.off('keydown.zf.reveal');
1759
1760        function finishUp() {
1761          if (_this.isMobile) {
1762            $('html, body').removeClass('is-reveal-open');
1763            if (_this.originalScrollPos) {
1764              $('body').scrollTop(_this.originalScrollPos);
1765              _this.originalScrollPos = null;
1766            }
1767          } else {
1768            $('body').removeClass('is-reveal-open');
1769          }
1770
1771          Foundation.Keyboard.releaseFocus(_this.$element);
1772
1773          _this.$element.attr('aria-hidden', true);
1774
1775          /**
1776          * Fires when the modal is done closing.
1777          * @event Reveal#closed
1778          */
1779          _this.$element.trigger('closed.zf.reveal');
1780        }
1781
1782        /**
1783        * Resets the modal content
1784        * This prevents a running video to keep going in the background
1785        */
1786        if (this.options.resetOnClose) {
1787          this.$element.html(this.$element.html());
1788        }
1789
1790        this.isActive = false;
1791        if (_this.options.deepLink) {
1792          if (window.history.replaceState) {
1793            window.history.replaceState('', document.title, window.location.href.replace('#' + this.id, ''));
1794          } else {
1795            window.location.hash = '';
1796          }
1797        }
1798      }
1799
1800      /**
1801       * Toggles the open/closed state of a modal.
1802       * @function
1803       */
1804
1805    }, {
1806      key: 'toggle',
1807      value: function toggle() {
1808        if (this.isActive) {
1809          this.close();
1810        } else {
1811          this.open();
1812        }
1813      }
1814    }, {
1815      key: 'destroy',
1816
1817
1818      /**
1819       * Destroys an instance of a modal.
1820       * @function
1821       */
1822      value: function destroy() {
1823        if (this.options.overlay) {
1824          this.$element.appendTo($(this.options.appendTo)); // move $element outside of $overlay to prevent error unregisterPlugin()
1825          this.$overlay.hide().off().remove();
1826        }
1827        this.$element.hide().off();
1828        this.$anchor.off('.zf');
1829        $(window).off('.zf.reveal:' + this.id);
1830
1831        Foundation.unregisterPlugin(this);
1832      }
1833    }]);
1834
1835    return Reveal;
1836  }();
1837
1838  Reveal.defaults = {
1839    /**
1840     * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
1841     * @option
1842     * @type {string}
1843     * @default ''
1844     */
1845    animationIn: '',
1846    /**
1847     * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
1848     * @option
1849     * @type {string}
1850     * @default ''
1851     */
1852    animationOut: '',
1853    /**
1854     * Time, in ms, to delay the opening of a modal after a click if no animation used.
1855     * @option
1856     * @type {number}
1857     * @default 0
1858     */
1859    showDelay: 0,
1860    /**
1861     * Time, in ms, to delay the closing of a modal after a click if no animation used.
1862     * @option
1863     * @type {number}
1864     * @default 0
1865     */
1866    hideDelay: 0,
1867    /**
1868     * Allows a click on the body/overlay to close the modal.
1869     * @option
1870     * @type {boolean}
1871     * @default true
1872     */
1873    closeOnClick: true,
1874    /**
1875     * Allows the modal to close if the user presses the `ESCAPE` key.
1876     * @option
1877     * @type {boolean}
1878     * @default true
1879     */
1880    closeOnEsc: true,
1881    /**
1882     * If true, allows multiple modals to be displayed at once.
1883     * @option
1884     * @type {boolean}
1885     * @default false
1886     */
1887    multipleOpened: false,
1888    /**
1889     * Distance, in pixels, the modal should push down from the top of the screen.
1890     * @option
1891     * @type {number|string}
1892     * @default auto
1893     */
1894    vOffset: 'auto',
1895    /**
1896     * Distance, in pixels, the modal should push in from the side of the screen.
1897     * @option
1898     * @type {number|string}
1899     * @default auto
1900     */
1901    hOffset: 'auto',
1902    /**
1903     * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well.
1904     * @option
1905     * @type {boolean}
1906     * @default false
1907     */
1908    fullScreen: false,
1909    /**
1910     * Percentage of screen height the modal should push up from the bottom of the view.
1911     * @option
1912     * @type {number}
1913     * @default 10
1914     */
1915    btmOffsetPct: 10,
1916    /**
1917     * Allows the modal to generate an overlay div, which will cover the view when modal opens.
1918     * @option
1919     * @type {boolean}
1920     * @default true
1921     */
1922    overlay: true,
1923    /**
1924     * Allows the modal to remove and reinject markup on close. Should be true if using video elements w/o using provider's api, otherwise, videos will continue to play in the background.
1925     * @option
1926     * @type {boolean}
1927     * @default false
1928     */
1929    resetOnClose: false,
1930    /**
1931     * Allows the modal to alter the url on open/close, and allows the use of the `back` button to close modals. ALSO, allows a modal to auto-maniacally open on page load IF the hash === the modal'
1931s user-set id.
1932     * @option
1933     * @type {boolean}
1934     * @default false
1935     */
1936    deepLink: false,
1937    /**
1938    * Allows the modal to append to custom div.
1939    * @option
1940    * @type {string}
1941    * @default "body"
1942    */
1943    appendTo: "body"
1944
1945  };
1946
1947  // Window exports
1948  Foundation.plugin(Reveal, 'Reveal');
1949
1950  function iPhoneSniff() {
1951    return (/iP(ad|hone|od).*OS/.test(window.navigator.userAgent)
1952    );
1953  }
1954
1955  function androidSniff() {
1956    return (/Android/.test(window.navigator.userAgent)
1957    );
1958  }
1959
1960  function mobileSniff() {
1961    return iPhoneSniff() || androidSniff();
1962  }
1963}(jQuery);
1964'use strict';
1965
1966var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
1967
1968function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1969
1970!function ($) {
1971
1972  /**
1973   * Drilldown module.
1974   * @module foundation.drilldown
1975   * @requires foundation.util.keyboard
1976   * @requires foundation.util.motion
1977   * @requires foundation.util.nest
1978   */
1979
1980  var Drilldown = function () {
1981    /**
1982     * Creates a new instance of a drilldown menu.
1983     * @class
1984     * @param {jQuery} element - jQuery object to make into an accordion menu.
1985     * @param {Object} options - Overrides to the default plugin settings.
1986     */
1987    function Drilldown(element, options) {
1988      _classCallCheck(this, Drilldown);
1989
1990      this.$element = element;
1991      this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);
1992
1993      Foundation.Nest.Feather(this.$element, 'drilldown');
1994
1995      this._init();
1996
1997      Foundation.registerPlugin(this, 'Drilldown');
1998      Foundation.Keyboard.register('Drilldown', {
1999        'ENTER': 'open',
2000        'SPACE': 'open',
2001        'ARROW_RIGHT': 'next',
2002        'ARROW_UP': 'up',
2003        'ARROW_DOWN': 'down',
2004        'ARROW_LEFT': 'previous',
2005        'ESCAPE': 'close',
2006        'TAB': 'down',
2007        'SHIFT_TAB': 'up'
2008      });
2009    }
2010
2011    /**
2012     * Initializes the drilldown by creating jQuery collections of elements
2013     * @private
2014     */
2015
2016
2017    _createClass(Drilldown, [{
2018      key: '_init',
2019      value: function _init() {
2020        this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
2021        this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]');
2022        this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem').find('a');
2023        this.$element.attr('data-mutate', this.$element.attr('data-drilldown') || Foundation.GetYoDigits(6, 'drilldown'));
2024
2025        this._prepareMenu();
2026        this._registerEvents();
2027
2028        this._keyboardEvents();
2029      }
2030
2031      /**
2032       * prepares drilldown menu by setting attributes to links and elements
2033       * sets a min height to prevent content jumping
2034       * wraps the element if not already wrapped
2035       * @private
2036       * @function
2037       */
2038
2039    }, {
2040      key: '_prepareMenu',
2041      value: function _prepareMenu() {
2042        var _this = this;
2043        // if(!this.options.holdOpen){
2044        //   this._menuLinkEvents();
2045        // }
2046        this.$submenuAnchors.each(function () {
2047          var $link = $(this);
2048          var $sub = $link.parent();
2049          if (_this.options.parentLink) {
2050            $link.clone().prependTo($sub.children('[data-submenu]')).wrap('<li class="is-submenu-parent-item is-submenu-item is-drilldown-submenu-item" role="menu-item"></li>');
2051          }
2052          $link.data('savedHref', $link.attr('href')).removeAttr('href').attr('tabindex', 0);
2053          $link.children('[data-submenu]').attr({
2054            'aria-hidden': true,
2055            'tabindex': 0,
2056            'role': 'menu'
2057          });
2058          _this._events($link);
2059        });
2060        this.$submenus.each(function () {
2061          var $menu = $(this),
2062              $back = $menu.find('.js-drilldown-back');
2063          if (!$back.length) {
2064            switch (_this.options.backButtonPosition) {
2065              case "bottom":
2066                $menu.append(_this.options.backButton);
2067                break;
2068              case "top":
2069                $menu.prepend(_this.options.backButton);
2070                break;
2071              default:
2072                console.error("Unsupported backButtonPosition value '" + _this.options.backButtonPosition + "'");
2073            }
2074          }
2075          _this._back($menu);
2076        });
2077
2078        this.$submenus.addClass('invisible');
2079        if (!this.options.autoHeight) {
2080          this.$submenus.addClass('drilldown-submenu-cover-previous');
2081        }
2082
2083        // create a wrapper on element if it doesn't exist.
2084        if (!this.$element.parent().hasClass('is-drilldown')) {
2085          this.$wrapper = $(this.options.wrapper).addClass('is-drilldown');
2086          if (this.options.animateHeight) this.$wrapper.addClass('animate-height');
2087          this.$element.wrap(this.$wrapper);
2088        }
2089        // set wrapper
2090        this.$wrapper = this.$element.parent();
2091        this.$wrapper.css(this._getMaxDims());
2092      }
2093    }, {
2094      key: '_resize',
2095      value: function _resize() {
2096        this.$wrapper.css({ 'max-width': 'none', 'min-height': 'none' });
2097        // _getMaxDims has side effects (boo) but calling it should update all other necessary heights & widths
2098        this.$wrapper.css(this._getMaxDims());
2099      }
2100
2101      /**
2102       * Adds event handlers to elements in the menu.
2103       * @function
2104       * @private
2105       * @param {jQuery} $elem - the current menu item to add handlers to.
2106       */
2107
2108    }, {
2109      key: '_events',
2110      value: function _events($elem) {
2111        var _this = this;
2112
2113        $elem.off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
2114          if ($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')) {
2115            e.stopImmediatePropagation();
2116            e.preventDefault();
2117          }
2118
2119          // if(e.target !== e.currentTarget.firstElementChild){
2120          //   return false;
2121          // }
2122          _this._show($elem.parent('li'));
2123
2124          if (_this.options.closeOnClick) {
2125            var $body = $('body');
2126            $body.off('.zf.drilldown').on('click.zf.drilldown', function (e) {
2127              if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
2128                return;
2129              }
2130              e.preventDefault();
2131              _this._hideAll();
2132              $body.off('.zf.drilldown');
2133            });
2134          }
2135        });
2136        this.$element.on('mutateme.zf.trigger', this._resize.bind(this));
2137      }
2138
2139      /**
2140       * Adds event handlers to the menu element.
2141       * @function
2142       * @private
2143       */
2144
2145    }, {
2146      key: '_registerEvents',
2147      value: function _registerEvents() {
2148        if (this.options.scrollTop) {
2149          this._bindHandler = this._scrollTop.bind(this);
2150          this.$element.on('open.zf.drilldown hide.zf.drilldown closed.zf.drilldown', this._bindHandler);
2151        }
2152      }
2153
2154      /**
2155       * Scroll to Top of Element or data-scroll-top-element
2156       * @function
2157       * @fires Drilldown#scrollme
2158       */
2159
2160    }, {
2161      key: '_scrollTop',
2162      value: function _scrollTop() {
2163        var _this = this;
2164        var $scrollTopElement = _this.options.scrollTopElement != '' ? $(_this.options.scrollTopElement) : _this.$element,
2165            scrollPos = parseInt($scrollTopElement.offset().top + _this.options.scrollTopOffset);
2166        $('html, body').stop(true).animate({ scrollTop: scrollPos }, _this.options.animationDuration, _this.options.animationEasing, function () {
2167          /**
2168            * Fires after the menu has scrolled
2169            * @event Drilldown#scrollme
2170            */
2171          if (this === $('html')[0]) _this.$element.trigger('scrollme.zf.drilldown');
2172        });
2173      }
2174
2175      /**
2176       * Adds keydown event listener to `li`'s in the menu.
2177       * @private
2178       */
2179
2180    }, {
2181      key: '_keyboardEvents',
2182      value: function _keyboardEvents() {
2183        var _this = this;
2184
2185        this.$menuItems.add(this.$element.find('.js-drilldown-back > a, .is-submenu-parent-item > a')).on('keydown.zf.drilldown', function (e) {
2186          var $element = $(this),
2187              $elements = $element.parent('li').parent('ul').children('li').children('a'),
2188              $prevElement,
2189              $nextElement;
2190
2191          $elements.each(function (i) {
2192            if ($(this).is($element)) {
2193              $prevElement = $elements.eq(Math.max(0, i - 1));
2194              $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1));
2195              return;
2196            }
2197          });
2198
2199          Foundation.Keyboard.handleKey(e, 'Drilldown', {
2200            next: function () {
2201              if ($element.is(_this.$submenuAnchors)) {
2202                _this._show($element.parent('li'));
2203                $element.parent('li').one(Foundation.transitionend($element), function () {
2204                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
2205                });
2206                return true;
2207              }
2208            },
2209            previous: function () {
2210              _this._hide($element.parent('li').parent('ul'));
2211              $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
2212                setTimeout(function () {
2213                  $element.parent('li').parent('ul').parent('li').children('a').first().focus();
2214                }, 1);
2215              });
2216              return true;
2217            },
2218            up: function () {
2219              $prevElement.focus();
2220              // Don't tap focus on first element in root ul
2221              return !$element.is(_this.$element.find('> li:first-child > a'));
2222            },
2223            down: function () {
2224              $nextElement.focus();
2225              // Don't tap focus on last element in root ul
2226              return !$element.is(_this.$element.find('> li:last-child > a'));
2227            },
2228            close: function () {
2229              // Don't close on element in root ul
2230              if (!$element.is(_this.$element.find('> li > a'))) {
2231                _this._hide($element.parent().parent());
2232                $element.parent().parent().siblings('a').focus();
2233              }
2234            },
2235            open: function () {
2236              if (!$element.is(_this.$menuItems)) {
2237                // not menu item means back button
2238                _this._hide($element.parent('li').parent('ul'));
2239                $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
2240                  setTimeout(function () {
2241                    $element.parent('li').parent('ul').parent('li').children('a').first().focus();
2242                  }, 1);
2243                });
2244                return true;
2245              } else if ($element.is(_this.$submenuAnchors)) {
2246                _this._show($element.parent('li'));
2247                $element.parent('li').one(Foundation.transitionend($element), function () {
2248                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
2249                });
2250                return true;
2251              }
2252            },
2253            handled: function (preventDefault) {
2254              if (preventDefault) {
2255                e.preventDefault();
2256              }
2257              e.stopImmediatePropagation();
2258            }
2259          });
2260        }); // end keyboardAccess
2261      }
2262
2263      /**
2264       * Closes all open elements, and returns to root menu.
2265       * @function
2266       * @fires Drilldown#closed
2267       */
2268
2269    }, {
2270      key: '_hideAll',
2271      value: function _hideAll() {
2272        var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing');
2273        if (this.options.autoHeight) this.$wrapper.css({ height: $elem.parent().closest('ul').data('calcHeight') });
2274        $elem.one(Foundation.transitionend($elem), function (e) {
2275          $elem.removeClass('is-active is-closing');
2276        });
2277        /**
2278         * Fires when the menu is fully closed.
2279         * @event Drilldown#closed
2280         */
2281        this.$element.trigger('closed.zf.drilldown');
2282      }
2283
2284      /**
2285       * Adds event listener for each `back` button, and closes open menus.
2286       * @function
2287       * @fires Drilldown#back
2288       * @param {jQuery} $elem - the current sub-menu to add `back` event.
2289       */
2290
2291    }, {
2292      key: '_back',
2293      value: function _back($elem) {
2294        var _this = this;
2295        $elem.off('click.zf.drilldown');
2296        $elem.children('.js-drilldown-back').on('click.zf.drilldown', function (e) {
2297          e.stopImmediatePropagation();
2298          // console.log('mouseup on back');
2299          _this._hide($elem);
2300
2301          // If there is a parent submenu, call show
2302          var parentSubMenu = $elem.parent('li').parent('ul').parent('li');
2303          if (parentSubMenu.length) {
2304            _this._show(parentSubMenu);
2305          }
2306        });
2307      }
2308
2309      /**
2310       * Adds event listener to menu items w/o submenus to close open menus on click.
2311       * @function
2312       * @private
2313       */
2314
2315    }, {
2316      key: '_menuLinkEvents',
2317      value: function _menuLinkEvents() {
2318        var _this = this;
2319        this.$menuItems.not('.is-drilldown-submenu-parent').off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
2320          // e.stopImmediatePropagation();
2321          setTimeout(function () {
2322            _this._hideAll();
2323          }, 0);
2324        });
2325      }
2326
2327      /**
2328       * Opens a submenu.
2329       * @function
2330       * @fires Drilldown#open
2331       * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
2332       */
2333
2334    }, {
2335      key: '_show',
2336      value: function _show($elem) {
2337        if (this.options.autoHeight) this.$wrapper.css({ height: $elem.children('[data-submenu]').data('calcHeight') });
2338        $elem.attr('aria-expanded', true);
2339        $elem.children('[data-submenu]').addClass('is-active').removeClass('invisible').attr('aria-hidden', false);
2340        /**
2341         * Fires when the submenu has opened.
2342         * @event Drilldown#open
2343         */
2344        this.$element.trigger('open.zf.drilldown', [$elem]);
2345      }
2346    }, {
2347      key: '_hide',
2348
2349
2350      /**
2351       * Hides a submenu
2352       * @function
2353       * @fires Drilldown#hide
2354       * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
2355       */
2356      value: function _hide($elem) {
2357        if (this.options.autoHeight) this.$wrapper.css({ height: $elem.parent().closest('ul').data('calcHeight') });
2358        var _this = this;
2359        $elem.parent('li').attr('aria-expanded', false);
2360        $elem.attr('aria-hidden', true).addClass('is-closing');
2361        $elem.addClass('is-closing').one(Foundation.transitionend($elem), function () {
2362          $elem.removeClass('is-active is-closing');
2363          $elem.blur().addClass('invisible');
2364        });
2365        /**
2366         * Fires when the submenu has closed.
2367         * @event Drilldown#hide
2368         */
2369        $elem.trigger('hide.zf.drilldown', [$elem]);
2370      }
2371
2372      /**
2373       * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
2374       * Prevents content jumping.
2375       * @function
2376       * @private
2377       */
2378
2379    }, {
2380      key: '_getMaxDims',
2381      value: function _getMaxDims() {
2382        var maxHeight = 0,
2383            result = {},
2384            _this = this;
2385        this.$submenus.add(this.$element).each(function () {
2386          var numOfElems = $(this).children('li').length;
2387          var height = Foundation.Box.GetDimensions(this).height;
2388          maxHeight = height > maxHeight ? height : maxHeight;
2389          if (_this.options.autoHeight) {
2390            $(this).data('calcHeight', height);
2391            if (!$(this).hasClass('is-drilldown-submenu')) result['height'] = height;
2392          }
2393        });
2394
2395        if (!this.options.autoHeight) result['min-height'] = maxHeight + 'px';
2396
2397        result['max-width'] = this.$element[0].getBoundingClientRect().width + 'px';
2398
2399        return result;
2400      }
2401
2402      /**
2403       * Destroys the Drilldown Menu
2404       * @function
2405       */
2406
2407    }, {
2408      key: 'destroy',
2409      value: function destroy() {
2410        if (this.options.scrollTop) this.$element.off('.zf.drilldown', this._bindHandler);
2411        this._hideAll();
2412        this.$element.off('mutateme.zf.trigger');
2413        Foundation.Nest.Burn(this.$element, 'drilldown');
2414        this.$element.unwrap().find('.js-drilldown-back, .is-submenu-parent-item').remove().end().find('.is-active, .is-closing, .is-drilldown-submenu').removeClass('is-active is-closing is-drilldown-submenu').end().find('[data-submenu]').removeAttr('aria-hidden tabindex role');
2415        this.$submenuAnchors.each(function () {
2416          $(this).off('.zf.drilldown');
2417        });
2418
2419        this.$submenus.removeClass('drilldown-submenu-cover-previous');
2420
2421        this.$element.find('a').each(function () {
2422          var $link = $(this);
2423          $link.removeAttr('tabindex');
2424          if ($link.data('savedHref')) {
2425            $link.attr('href', $link.data('savedHref')).removeData('savedHref');
2426          } else {
2427            return;
2428          }
2429        });
2430        Foundation.unregisterPlugin(this);
2431      }
2432    }]);
2433
2434    return Drilldown;
2435  }();
2436
2437  Drilldown.defaults = {
2438    /**
2439     * Markup used for JS generated back button. Prepended  or appended (see backButtonPosition) to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
2440     * @option
2441     * @type {string}
2442     * @default '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>'
2443     */
2444    backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
2445    /**
2446     * Position the back button either at the top or bottom of drilldown submenus. Can be `'left'` or `'bottom'`.
2447     * @option
2448     * @type {string}
2449     * @default top
2450     */
2451    backButtonPosition: 'top',
2452    /**
2453     * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
2454     * @option
2455     * @type {string}
2456     * @default '<div></div>'
2457     */
2458    wrapper: '<div></div>',
2459    /**
2460     * Adds the parent link to the submenu.
2461     * @option
2462     * @type {boolean}
2463     * @default false
2464     */
2465    parentLink: false,
2466    /**
2467     * Allow the menu to return to root list on body click.
2468     * @option
2469     * @type {boolean}
2470     * @default false
2471     */
2472    closeOnClick: false,
2473    /**
2474     * Allow the menu to auto adjust height.
2475     * @option
2476     * @type {boolean}
2477     * @default false
2478     */
2479    autoHeight: false,
2480    /**
2481     * Animate the auto adjust height.
2482     * @option
2483     * @type {boolean}
2484     * @default false
2485     */
2486    animateHeight: false,
2487    /**
2488     * Scroll to the top of the menu after opening a submenu or navigating back using the menu back button
2489     * @option
2490     * @type {boolean}
2491     * @default false
2492     */
2493    scrollTop: false,
2494    /**
2495     * String jquery selector (for example 'body') of element to take offset().top from, if empty string the drilldown menu offset().top is taken
2496     * @option
2497     * @type {string}
2498     * @default ''
2499     */
2500    scrollTopElement: '',
2501    /**
2502     * ScrollTop offset
2503     * @option
2504     * @type {number}
2505     * @default 0
2506     */
2507    scrollTopOffset: 0,
2508    /**
2509     * Scroll animation duration
2510     * @option
2511     * @type {number}
2512     * @default 500
2513     */
2514    animationDuration: 500,
2515    /**
2516     * Scroll animation easing. Can be `'swing'` or `'linear'`.
2517     * @option
2518     * @type {string}
2519     * @see {@link https://api.jquery.com/animate|JQuery animate}
2520     * @default 'swing'
2521     */
2522    animationEasing: 'swing'
2523    // holdOpen: false
2524  };
2525
2526  // Window exports
2527  Foundation.plugin(Drilldown, 'Drilldown');
2528}(jQuery);
2529/*
2530 *   This content is licensed according to the W3C Software License at
2531 *   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
2532 *
2533 *   Simple accordion pattern example
2534 */
2535
2536'use strict';
2537
2538class Accordion {
2539    constructor(domNode) {
2540        this.rootEl = domNode;
2541        this.buttonEl = this.rootEl.querySelector('button[aria-expanded]');
2542
2543        const controlsId = this.buttonEl.getAttribute('aria-controls');
2544        this.contentEl = document.getElementById(controlsId);
2545
2546        this.open = this.buttonEl.getAttribute('aria-expanded') === 'true';
2547
2548        // add event listeners
2549        this.buttonEl.addEventListener('click', this.onButtonClick.bind(this));
2550    }
2551
2552    onButtonClick() {
2553        this.toggle(!this.open);
2554    }
2555
2556    toggle(open) {
2557        // don't do anything if the open state doesn't change
2558        if (open === this.open) {
2559            return;
2560        }
2561
2562        // update the internal state
2563        this.open = open;
2564
2565        // handle DOM updates
2566        this.buttonEl.setAttribute('aria-expanded', `${open}`);
2567        if (open) {
2568            this.contentEl.removeAttribute('hidden');
2569        } else {
2570            this.contentEl.setAttribute('hidden', '');
2571        }
2572    }
2573
2574    // Add public open and close methods for convenience
2575    open() {
2576        this.toggle(true);
2577    }
2578
2579    close() {
2580        this.toggle(false);
2581    }
2582}
2583
2584// init accordions
2585const accordions = document.querySelectorAll('.accordion .no-style');
2586accordions.forEach((accordionEl) => {
2587    new Accordion(accordionEl);
2588});
2589
2590'use strict';
2591
2592var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2593
2594function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2595
2596!function ($) {
2597
2598  /**
2599   * DropdownMenu module.
2600   * @module foundation.dropdown-menu
2601   * @requires foundation.util.keyboard
2602   * @requires foundation.util.box
2603   * @requires foundation.util.nest
2604   */
2605
2606  var DropdownMenu = function () {
2607    /**
2608     * Creates a new instance of DropdownMenu.
2609     * @class
2610     * @fires DropdownMenu#init
2611     * @param {jQuery} element - jQuery object to make into a dropdown menu.
2612     * @param {Object} options - Overrides to the default plugin settings.
2613     */
2614    function DropdownMenu(element, options) {
2615      _classCallCheck(this, DropdownMenu);
2616
2617      this.$element = element;
2618      this.options = $.extend({}, DropdownMenu.defaults, this.$element.data(), options);
2619
2620      Foundation.Nest.Feather(this.$element, 'dropdown');
2621      this._init();
2622
2623      Foundation.registerPlugin(this, 'DropdownMenu');
2624      Foundation.Keyboard.register('DropdownMenu', {
2625        'ENTER': 'open',
2626        'SPACE': 'open',
2627        'ARROW_RIGHT': 'next',
2628        'ARROW_UP': 'up',
2629        'ARROW_DOWN': 'down',
2630        'ARROW_LEFT': 'previous',
2631        'ESCAPE': 'close'
2632      });
2633    }
2634
2635    /**
2636     * Initializes the plugin, and calls _prepareMenu
2637     * @private
2638     * @function
2639     */
2640
2641
2642    _createClass(DropdownMenu, [{
2643      key: '_init',
2644      value: function _init() {
2645        var subs = this.$element.find('li.is-dropdown-submenu-parent');
2646        this.$element.children('.is-dropdown-submenu-parent').children('.is-dropdown-submenu').addClass('first-sub');
2647
2648        this.$menuItems = this.$element.find('[role="menuitem"]');
2649        this.$tabs = this.$element.children('[role="menuitem"]');
2650        this.$tabs.find('ul.is-dropdown-submenu').addClass(this.options.verticalClass);
2651
2652        if (this.$element.hasClass(this.options.rightClass) || this.options.alignment === 'right' || Foundation.rtl() || this.$element.parents('.top-bar-right').is('*')) {
2653          this.options.alignment = 'right';
2654          subs.addClass('opens-left');
2655        } else {
2656          subs.addClass('opens-right');
2657        }
2658        this.changed = false;
2659        this._events();
2660      }
2661    }, {
2662      key: '_isVertical',
2663      value: function _isVertical() {
2664        return this.$tabs.css('display') === 'block';
2665      }
2666
2667      /**
2668       * Adds event listeners to elements within the menu
2669       * @private
2670       * @function
2671       */
2672
2673    }, {
2674      key: '_events',
2675      value: function _events() {
2676        var _this = this,
2677            hasTouch = 'ontouchstart' in window || typeof window.ontouchstart !== 'undefined',
2678            parClass = 'is-dropdown-submenu-parent';
2679
2680        // used for onClick and in the keyboard handlers
2681        var handleClickFn = function (e) {
2682          var $elem = $(e.target).parentsUntil('ul', '.' + parClass),
2683              hasSub = $elem.hasClass(parClass),
2684              hasClicked = $elem.attr('data-is-click') === 'true',
2685              $sub = $elem.children('.is-dropdown-submenu');
2686
2687          if (hasSub) {
2688            if (hasClicked) {
2689              if (!_this.options.closeOnClick || !_this.options.clickOpen && !hasTouch || _this.options.forceFollow && hasTouch) {
2690                return;
2691              } else {
2692                e.stopImmediatePropagation();
2693                e.preventDefault();
2694                _this._hide($elem);
2695              }
2696            } else {
2697              e.preventDefault();
2698              e.stopImmediatePropagation();
2699              _this._show($sub);
2700              $elem.add($elem.parentsUntil(_this.$element, '.' + parClass)).attr('data-is-click', true);
2701            }
2702          }
2703        };
2704
2705        if (this.options.clickOpen || hasTouch) {
2706          this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', handleClickFn);
2707        }
2708
2709        // Handle Leaf element Clicks
2710        if (_this.options.closeOnClickInside) {
2711          this.$menuItems.on('click.zf.dropdownmenu', function (e) {
2712            var $elem = $(this),
2713                hasSub = $elem.hasClass(parClass);
2714            if (!hasSub) {
2715              _this._hide();
2716            }
2717          });
2718        }
2719
2720        if (!this.options.disableHover) {
2721          this.$menuItems.on('mouseenter.zf.dropdownmenu', function (e) {
2722            var $elem = $(this),
2723                hasSub = $elem.hasClass(parClass);
2724
2725            if (hasSub) {
2726              clearTimeout($elem.data('_delay'));
2727              $elem.data('_delay', setTimeout(function () {
2728                _this._show($elem.children('.is-dropdown-submenu'));
2729              }, _this.options.hoverDelay));
2730            }
2731          }).on('mouseleave.zf.dropdownmenu', function (e) {
2732            var $elem = $(this),
2733                hasSub = $elem.hasClass(parClass);
2734            if (hasSub && _this.options.autoclose) {
2735              if ($elem.attr('data-is-click') === 'true' && _this.options.clickOpen) {
2736                return false;
2737              }
2738
2739              clearTimeout($elem.data('_delay'));
2740              $elem.data('_delay', setTimeout(function () {
2741                _this._hide($elem);
2742              }, _this.options.closingTime));
2743            }
2744          });
2745        }
2746        this.$menuItems.on('keydown.zf.dropdownmenu', function (e) {
2747          var $element = $(e.target).parentsUntil('ul', '[role="menuitem"]'),
2748              isTab = _this.$tabs.index($element) > -1,
2749              $elements = isTab ? _this.$tabs : $element.siblings('li').add($element),
2750              $prevElement,
2751              $nextElement;
2752
2753          $elements.each(function (i) {
2754            if ($(this).is($element)) {
2755              $prevElement = $elements.eq(i - 1);
2756              $nextElement = $elements.eq(i + 1);
2757              return;
2758            }
2759          });
2760
2761          var nextSibling = function () {
2762            if (!$element.is(':last-child')) {
2763              $nextElement.children('a:first').focus();
2764              e.preventDefault();
2765            }
2766          },
2767              prevSibling = function () {
2768            $prevElement.children('a:first').focus();
2769            e.preventDefault();
2770          },
2771              openSub = function () {
2772            var $sub = $element.children('ul.is-dropdown-submenu');
2773            if ($sub.length) {
2774              _this._show($sub);
2775              $element.find('li > a:first').focus();
2776              e.preventDefault();
2777            } else {
2778              return;
2779            }
2780          },
2781              closeSub = function () {
2782            //if ($element.is(':first-child')) {
2783            var close = $element.parent('ul').parent('li');
2784            close.children('a:first').focus();
2785            _this._hide(close);
2786            e.preventDefault();
2787            //}
2788          };
2789          var functions = {
2790            open: openSub,
2791            close: function () {
2792              _this._hide(_this.$element);
2793              _this.$menuItems.find('a:first').focus(); // focus to first element
2794              e.preventDefault();
2795            },
2796            handled: function () {
2797              e.stopImmediatePropagation();
2798            }
2799          };
2800
2801          if (isTab) {
2802            if (_this._isVertical()) {
2803              // vertical menu
2804              if (Foundation.rtl()) {
2805                // right aligned
2806                $.extend(functions, {
2807                  down: nextSibling,
2808                  up: prevSibling,
2809                  next: closeSub,
2810                  previous: openSub
2811                });
2812              } else {
2813                // left aligned
2814                $.extend(functions, {
2815                  down: nextSibling,
2816                  up: prevSibling,
2817                  next: openSub,
2818                  previous: closeSub
2819                });
2820              }
2821            } else {
2822              // horizontal menu
2823              if (Foundation.rtl()) {
2824                // right aligned
2825                $.extend(functions, {
2826                  next: prevSibling,
2827                  previous: nextSibling,
2828                  down: openSub,
2829                  up: closeSub
2830                });
2831              } else {
2832                // left aligned
2833                $.extend(functions, {
2834                  next: nextSibling,
2835                  previous: prevSibling,
2836                  down: openSub,
2837                  up: closeSub
2838                });
2839              }
2840            }
2841          } else {
2842            // not tabs -> one sub
2843            if (Foundation.rtl()) {
2844              // right aligned
2845              $.extend(functions, {
2846                next: closeSub,
2847                previous: openSub,
2848                down: nextSibling,
2849                up: prevSibling
2850              });
2851            } else {
2852              // left aligned
2853              $.extend(functions, {
2854                next: openSub,
2855                previous: closeSub,
2856                down: nextSibling,
2857                up: prevSibling
2858              });
2859            }
2860          }
2861          Foundation.Keyboard.handleKey(e, 'DropdownMenu', functions);
2862        });
2863      }
2864
2865      /**
2866       * Adds an event handler to the body to close any dropdowns on a click.
2867       * @function
2868       * @private
2869       */
2870
2871    }, {
2872      key: '_addBodyHandler',
2873      value: function _addBodyHandler() {
2874        var $body = $(document.body),
2875            _this = this;
2876        $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu').on('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu', function (e) {
2877          var $link = _this.$element.find(e.target);
2878          if ($link.length) {
2879            return;
2880          }
2881
2882          _this._hide();
2883          $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu');
2884        });
2885      }
2886
2887      /**
2888       * Opens a dropdown pane, and checks for collisions first.
2889       * @param {jQuery} $sub - ul element that is a submenu to show
2890       * @function
2891       * @private
2892       * @fires DropdownMenu#show
2893       */
2894
2895    }, {
2896      key: '_show',
2897      value: function _show($sub) {
2898        var idx = this.$tabs.index(this.$tabs.filter(function (i, el) {
2899          return $(el).find($sub).length > 0;
2900        }));
2901        var $sibs = $sub.parent('li.is-dropdown-submenu-parent').siblings('li.is-dropdown-submenu-parent');
2902        this._hide($sibs, idx);
2903        $sub.css('visibility', 'hidden').addClass('js-dropdown-active').parent('li.is-dropdown-submenu-parent').addClass('is-active');
2904        var clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
2905        if (!clear) {
2906          var oldClass = this.options.alignment === 'left' ? '-right' : '-left',
2907              $parentLi = $sub.parent('.is-dropdown-submenu-parent');
2908          $parentLi.removeClass('opens' + oldClass).addClass('opens-' + this.options.alignment);
2909          clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
2910          if (!clear) {
2911            $parentLi.removeClass('opens-' + this.options.alignment).addClass('opens-inner');
2912          }
2913          this.changed = true;
2914        }
2915        $sub.css('visibility', '');
2916        if (this.options.closeOnClick) {
2917          this._addBodyHandler();
2918        }
2919        /**
2920         * Fires when the new dropdown pane is visible.
2921         * @event DropdownMenu#show
2922         */
2923        this.$element.trigger('show.zf.dropdownmenu', [$sub]);
2924      }
2925
2926      /**
2927       * Hides a single, currently open dropdown pane, if passed a parameter, otherwise, hides everything.
2928       * @function
2929       * @param {jQuery} $elem - element with a submenu to hide
2930       * @param {Number} idx - index of the $tabs collection to hide
2931       * @private
2932       */
2933
2934    }, {
2935      key: '_hide',
2936      value: function _hide($elem, idx) {
2937        var $toClose;
2938        if ($elem && $elem.length) {
2939          $toClose = $elem;
2940        } else if (idx !== undefined) {
2941          $toClose = this.$tabs.not(function (i, el) {
2942            return i === idx;
2943          });
2944        } else {
2945          $toClose = this.$element;
2946        }
2947        var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0;
2948
2949        if (somethingToClose) {
2950          $toClose.find('li.is-active').add($toClose).attr({
2951            'data-is-click': false
2952          }).removeClass('is-active');
2953
2954          $toClose.find('ul.js-dropdown-active').removeClass('js-dropdown-active');
2955
2956          if (this.changed || $toClose.find('opens-inner').length) {
2957            var oldClass = this.options.alignment === 'left' ? 'right' : 'left';
2958            $toClose.find('li.is-dropdown-submenu-parent').add($toClose).removeClass('opens-inner opens-' + this.options.alignment).addClass('opens-' + oldClass);
2959            this.changed = false;
2960          }
2961          /**
2962           * Fires when the open menus are closed.
2963           * @event DropdownMenu#hide
2964           */
2965          this.$element.trigger('hide.zf.dropdownmenu', [$toClose]);
2966        }
2967      }
2968
2969      /**
2970       * Destroys the plugin.
2971       * @function
2972       */
2973
2974    }, {
2975      key: 'destroy',
2976      value: function destroy() {
2977        this.$menuItems.off('.zf.dropdownmenu').removeAttr('data-is-click').removeClass('is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner');
2978        $(document.body).off('.zf.dropdownmenu');
2979        Foundation.Nest.Burn(this.$element, 'dropdown');
2980        Foundation.unregisterPlugin(this);
2981      }
2982    }]);
2983
2984    return DropdownMenu;
2985  }();
2986
2987  /**
2988   * Default settings for plugin
2989   */
2990
2991
2992  DropdownMenu.defaults = {
2993    /**
2994     * Disallows hover events from opening submenus
2995     * @option
2996     * @type {boolean}
2997     * @default false
2998     */
2999    disableHover: false,
3000    /**
3001     * Allow a submenu to automatically close on a mouseleave event, if not clicked open.
3002     * @option
3003     * @type {boolean}
3004     * @default true
3005     */
3006    autoclose: true,
3007    /**
3008     * Amount of time to delay opening a submenu on hover event.
3009     * @option
3010     * @type {number}
3011     * @default 50
3012     */
3013    hoverDelay: 50,
3014    /**
3015     * Allow a submenu to open/remain open on parent click event. Allows cursor to move away from menu.
3016     * @option
3017     * @type {boolean}
3018     * @default false
3019     */
3020    clickOpen: false,
3021    /**
3022     * Amount of time to delay closing a submenu on a mouseleave event.
3023     * @option
3024     * @type {number}
3025     * @default 500
3026     */
3027
3028    closingTime: 500,
3029    /**
3030     * Position of the menu relative to what direction the submenus should open. Handled by JS. Can be `'left'` or `'right'`.
3031     * @option
3032     * @type {string}
3033     * @default 'left'
3034     */
3035    alignment: 'left',
3036    /**
3037     * Allow clicks on the body to close any open submenus.
3038     * @option
3039     * @type {boolean}
3040     * @default true
3041     */
3042    closeOnClick: true,
3043    /**
3044     * Allow clicks on leaf anchor links to close any open submenus.
3045     * @option
3046     * @type {boolean}
3047     * @default true
3048     */
3049    closeOnClickInside: true,
3050    /**
3051     * Class applied to vertical oriented menus, Foundation default is `vertical`. Update this if using your own class.
3052     * @option
3053     * @type {string}
3054     * @default 'vertical'
3055     */
3056    verticalClass: 'vertical',
3057    /**
3058     * Class applied to right-side oriented menus, Foundation default is `align-right`. Update this if using your own class.
3059     * @option
3060     * @type {string}
3061     * @default 'align-right'
3062     */
3063    rightClass: 'align-right',
3064    /**
3065     * Boolean to force overide the clicking of links to perform default action, on second touch event for mobile.
3066     * @option
3067     * @type {boolean}
3068     * @default true
3069     */
3070    forceFollow: true
3071  };
3072
3073  // Window exports
3074  Foundation.plugin(DropdownMenu, 'DropdownMenu');
3075}(jQuery);
3076'use strict';
3077
3078var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3079
3080function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3081
3082!function ($) {
3083
3084  /**
3085   * ResponsiveMenu module.
3086   * @module foundation.responsiveMenu
3087   * @requires foundation.util.triggers
3088   * @requires foundation.util.mediaQuery
3089   */
3090
3091  var ResponsiveMenu = function () {
3092    /**
3093     * Creates a new instance of a responsive menu.
3094     * @class
3095     * @fires ResponsiveMenu#init
3096     * @param {jQuery} element - jQuery object to make into a dropdown menu.
3097     * @param {Object} options - Overrides to the default plugin settings.
3098     */
3099    function ResponsiveMenu(element, options) {
3100      _classCallCheck(this, ResponsiveMenu);
3101
3102      this.$element = $(element);
3103      this.rules = this.$element.data('responsive-menu');
3104      this.currentMq = null;
3105      this.currentPlugin = null;
3106
3107      this._init();
3108      this._events();
3109
3110      Foundation.registerPlugin(this, 'ResponsiveMenu');
3111    }
3112
3113    /**
3114     * Initializes the Menu by parsing the classes from the 'data-ResponsiveMenu' attribute on the element.
3115     * @function
3116     * @private
3117     */
3118
3119
3120    _createClass(ResponsiveMenu, [{
3121      key: '_init',
3122      value: function _init() {
3123        // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules
3124        if (typeof this.rules === 'string') {
3125          var rulesTree = {};
3126
3127          // Parse rules from "classes" pulled from data attribute
3128          var rules = this.rules.split(' ');
3129
3130          // Iterate through every rule found
3131          for (var i = 0; i < rules.length; i++) {
3132            var rule = rules[i].split('-');
3133            var ruleSize = rule.length > 1 ? rule[0] : 'small';
3134            var rulePlugin = rule.length > 1 ? rule[1] : rule[0];
3135
3136            if (MenuPlugins[rulePlugin] !== null) {
3137              rulesTree[ruleSize] = MenuPlugins[rulePlugin];
3138            }
3139          }
3140
3141          this.rules = rulesTree;
3142        }
3143
3144        if (!$.isEmptyObject(this.rules)) {
3145          this._checkMediaQueries();
3146        }
3147        // Add data-mutate since children may need it.
3148        this.$element.attr('data-mutate', this.$element.attr('data-mutate') || Foundation.GetYoDigits(6, 'responsive-menu'));
3149      }
3150
3151      /**
3152       * Initializes events for the Menu.
3153       * @function
3154       * @private
3155       */
3156
3157    }, {
3158      key: '_events',
3159      value: function _events() {
3160        var _this = this;
3161
3162        $(window).on('changed.zf.mediaquery', function () {
3163          _this._checkMediaQueries();
3164        });
3165        // $(window).on('resize.zf.ResponsiveMenu', function() {
3166        //   _this._checkMediaQueries();
3167        // });
3168      }
3169
3170      /**
3171       * Checks the current screen width against available media queries. If the media query has changed, and the plugin needed has changed, the plugins will swap out.
3172       * @function
3173       * @private
3174       */
3175
3176    }, {
3177      key: '_checkMediaQueries',
3178      value: function _checkMediaQueries() {
3179        var matchedMq,
3180            _this = this;
3181        // Iterate through each rule and find the last matching rule
3182        $.each(this.rules, function (key) {
3183          if (Foundation.MediaQuery.atLeast(key)) {
3184            matchedMq = key;
3185          }
3186        });
3187
3188        // No match? No dice
3189        if (!matchedMq) return;
3190
3191        // Plugin already initialized? We good
3192        if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return;
3193
3194        // Remove existing plugin-specific CSS classes
3195        $.each(MenuPlugins, function (key, value) {
3196          _this.$element.removeClass(value.cssClass);
3197        });
3198
3199        // Add the CSS class for the new plugin
3200        this.$element.addClass(this.rules[matchedMq].cssClass);
3201
3202        // Create an instance of the new plugin
3203        if (this.currentPlugin) this.currentPlugin.destroy();
3204        this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {});
3205      }
3206
3207      /**
3208       * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out.
3209       * @function
3210       */
3211
3212    }, {
3213      key: 'destroy',
3214      value: function destroy() {
3215        this.currentPlugin.destroy();
3216        $(window).off('.zf.ResponsiveMenu');
3217        Foundation.unregisterPlugin(this);
3218      }
3219    }]);
3220
3221    return ResponsiveMenu;
3222  }();
3223
3224  ResponsiveMenu.defaults = {};
3225
3226  // The plugin matches the plugin classes with these plugin instances.
3227  var MenuPlugins = {
3228    dropdown: {
3229      cssClass: 'dropdown',
3230      plugin: Foundation._plugins['dropdown-menu'] || null
3231    },
3232    drilldown: {
3233      cssClass: 'drilldown',
3234      plugin: Foundation._plugins['drilldown'] || null
3235    },
3236    accordion: {
3237      cssClass: 'accordion-menu',
3238      plugin: Foundation._plugins['accordion-menu'] || null
3239    },
3240    simple: {
3241      cssClass: '',
3242      plugin: function(){
3243        this.destroy = function(){}
3244      }
3245    }
3246  };
3247
3248  // Window exports
3249  Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu');
3250}(jQuery);
3251'use strict';
3252
3253!function ($) {
3254
3255  /**
3256   * Motion module.
3257   * @module foundation.motion
3258   */
3259
3260  var initClasses = ['mui-enter', 'mui-leave'];
3261  var activeClasses = ['mui-enter-active', 'mui-leave-active'];
3262
3263  var Motion = {
3264    animateIn: function (element, animation, cb) {
3265      animate(true, element, animation, cb);
3266    },
3267
3268    animateOut: function (element, animation, cb) {
3269      animate(false, element, animation, cb);
3270    }
3271  };
3272
3273  function Move(duration, elem, fn) {
3274    var anim,
3275        prog,
3276        start = null;
3277    // console.log('called');
3278
3279    if (duration === 0) {
3280      fn.apply(elem);
3281      elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
3282      return;
3283    }
3284
3285    function move(ts) {
3286      if (!start) start = ts;
3287      // console.log(start, ts);
3288      prog = ts - start;
3289      fn.apply(elem);
3290
3291      if (prog < duration) {
3292        anim = window.requestAnimationFrame(move, elem);
3293      } else {
3294        window.cancelAnimationFrame(anim);
3295        elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
3296      }
3297    }
3298    anim = window.requestAnimationFrame(move);
3299  }
3300
3301  /**
3302   * Animates an element in or out using a CSS transition class.
3303   * @function
3304   * @private
3305   * @param {Boolean} isIn - Defines if the animation is in or out.
3306   * @param {Object} element - jQuery or HTML object to animate.
3307   * @param {String} animation - CSS class to use.
3308   * @param {Function} cb - Callback to run when animation is finished.
3309   */
3310  function animate(isIn, element, animation, cb) {
3311    element = $(element).eq(0);
3312
3313    if (!element.length) return;
3314
3315    var initClass = isIn ? initClasses[0] : initClasses[1];
3316    var activeClass = isIn ? activeClasses[0] : activeClasses[1];
3317
3318    // Set up the animation
3319    reset();
3320
3321    element.addClass(animation).css('transition', 'none');
3322
3323    requestAnimationFrame(function () {
3324      element.addClass(initClass);
3325      if (isIn) element.show();
3326    });
3327
3328    // Start the animation
3329    requestAnimationFrame(function () {
3330      element[0].offsetWidth;
3331      element.css('transition', '').addClass(activeClass);
3332    });
3333
3334    // Clean up the animation when it finishes
3335    element.one(Foundation.transitionend(element), finish);
3336
3337    // Hides the element (for out animations), resets the element, and runs a callback
3338    function finish() {
3339      if (!isIn) element.hide();
3340      reset();
3341      if (cb) cb.apply(element);
3342    }
3343
3344    // Resets transitions and removes motion-specific classes
3345    function reset() {
3346      element[0].style.transitionDuration = 0;
3347      element.removeClass(initClass + ' ' + activeClass + ' ' + animation);
3348    }
3349  }
3350
3351  Foundation.Move = Move;
3352  Foundation.Motion = Motion;
3353}(jQuery);
3354/*******************************************
3355 *                                         *
3356 * This util was created by Marius Olbertz *
3357 * Please thank Marius on GitHub /owlbertz *
3358 * or the web http://www.mariusolbertz.de/ *
3359 *                                         *
3360 ******************************************/
3361
3362'use strict';
3363
3364!function ($) {
3365
3366  var keyCodes = {
3367    9: 'TAB',
3368    13: 'ENTER',
3369    27: 'ESCAPE',
3370    32: 'SPACE',
3371    37: 'ARROW_LEFT',
3372    38: 'ARROW_UP',
3373    39: 'ARROW_RIGHT',
3374    40: 'ARROW_DOWN'
3375  };
3376
3377  var commands = {};
3378
3379  var Keyboard = {
3380    keys: getKeyCodes(keyCodes),
3381
3382    /**
3383     * Parses the (keyboard) event and returns a String that represents its key
3384     * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
3385     * @param {Event} event - the event generated by the event handler
3386     * @return String key - String that represents the key pressed
3387     */
3388    parseKey: function (event) {
3389      var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase();
3390
3391      // Remove un-printable characters, e.g. for `fromCharCode` calls for CTRL only events
3392      key = key.replace(/\W+/, '');
3393
3394      if (event.shiftKey) key = 'SHIFT_' + key;
3395      if (event.ctrlKey) key = 'CTRL_' + key;
3396      if (event.altKey) key = 'ALT_' + key;
3397
3398      // Remove trailing underscore, in case only modifiers were used (e.g. only `CTRL_ALT`)
3399      key = key.replace(/_$/, '');
3400
3401      return key;
3402    },
3403
3404
3405    /**
3406     * Handles the given (keyboard) event
3407     * @param {Event} event - the event generated by the event handler
3408     * @param {String} component - Foundation component's name, e.g. Slider or Reveal
3409     * @param {Objects} functions - collection of functions that are to be executed
3410     */
3411    handleKey: function (event, component, functions) {
3412      var commandList = commands[component],
3413          keyCode = this.parseKey(event),
3414          cmds,
3415          command,
3416          fn;
3417
3418      if (!commandList) return console.warn('Component not defined!');
3419
3420      if (typeof commandList.ltr === 'undefined') {
3421        // this component does not differentiate between ltr and rtl
3422        cmds = commandList; // use plain list
3423      } else {
3424        // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa
3425        if (Foundation.rtl()) cmds = $.extend({}, commandList.ltr, commandList.rtl);else cmds = $.extend({}, commandList.rtl, commandList.ltr);
3426      }
3427      command = cmds[keyCode];
3428
3429      fn = functions[command];
3430      if (fn && typeof fn === 'function') {
3431        // execute function  if exists
3432        var returnValue = fn.apply();
3433        if (functions.handled || typeof functions.handled === 'function') {
3434          // execute function when event was handled
3435          functions.handled(returnValue);
3436        }
3437      } else {
3438        if (functions.unhandled || typeof functions.unhandled === 'function') {
3439          // execute function when event was not handled
3440          functions.unhandled();
3441        }
3442      }
3443    },
3444
3445
3446    /**
3447     * Finds all focusable elements within the given `$element`
3448     * @param {jQuery} $element - jQuery object to search within
3449     * @return {jQuery} $focusable - all focusable elements within `$element`
3450     */
3451    findFocusable: function ($element) {
3452      if (!$element) {
3453        return false;
3454      }
3455      return $element.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]').filter(function () {
3456        if (!$(this).is(':visible') || $(this).attr('tabindex') < 0) {
3457          return false;
3458        } //only have visible elements and those that have a tabindex greater or equal 0
3459        return true;
3460      });
3461    },
3462
3463
3464    /**
3465     * Returns the component name name
3466     * @param {Object} component - Foundation component, e.g. Slider or Reveal
3467     * @return String componentName
3468     */
3469
3470    register: function (componentName, cmds) {
3471      commands[componentName] = cmds;
3472    },
3473
3474
3475    /**
3476     * Traps the focus in the given element.
3477     * @param  {jQuery} $element  jQuery object to trap the foucs into.
3478     */
3479    trapFocus: function ($element) {
3480      var $focusable = Foundation.Keyboard.findFocusable($element),
3481          $firstFocusable = $focusable.eq(0),
3482          $lastFocusable = $focusable.eq(-1);
3483
3484      $element.on('keydown.zf.trapfocus', function (event) {
3485        if (event.target === $lastFocusable[0] && Foundation.Keyboard.parseKey(event) === 'TAB') {
3486          event.preventDefault();
3487          $firstFocusable.focus();
3488        } else if (event.target === $firstFocusable[0] && Foundation.Keyboard.parseKey(event) === 'SHIFT_TAB') {
3489          event.preventDefault();
3490          $lastFocusable.focus();
3491        }
3492      });
3493    },
3494
3495    /**
3496     * Releases the trapped focus from the given element.
3497     * @param  {jQuery} $element  jQuery object to release the focus for.
3498     */
3499    releaseFocus: function ($element) {
3500      $element.off('keydown.zf.trapfocus');
3501    }
3502  };
3503
3504  /*
3505   * Constants for easier comparing.
3506   * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
3507   */
3508  function getKeyCodes(kcs) {
3509    var k = {};
3510    for (var kc in kcs) {
3511      k[kcs[kc]] = kcs[kc];
3512    }return k;
3513  }
3514
3515  Foundation.Keyboard = Keyboard;
3516}(jQuery);
3517'use strict';
3518
3519var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3520
3521function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3522
3523!function ($) {
3524
3525  /**
3526   * Sticky module.
3527   * @module foundation.sticky
3528   * @requires foundation.util.triggers
3529   * @requires foundation.util.mediaQuery
3530   */
3531
3532  var Sticky = function () {
3533    /**
3534     * Creates a new instance of a sticky thing.
3535     * @class
3536     * @param {jQuery} element - jQuery object to make sticky.
3537     * @param {Object} options - options object passed when creating the element programmatically.
3538     */
3539    function Sticky(element, options) {
3540      _classCallCheck(this, Sticky);
3541
3542      this.$element = element;
3543      this.options = $.extend({}, Sticky.defaults, this.$element.data(), options);
3544
3545      this._init();
3546
3547      Foundation.registerPlugin(this, 'Sticky');
3548    }
3549
3550    /**
3551     * Initializes the sticky element by adding classes, getting/setting dimensions, breakpoints and attributes
3552     * @function
3553     * @private
3554     */
3555
3556
3557    _createClass(Sticky, [{
3558      key: '_init',
3559      value: function _init() {
3560        var $parent = this.$element.parent('[data-sticky-container]'),
3561            id = this.$element[0].id || Foundation.GetYoDigits(6, 'sticky'),
3562            _this = this;
3563
3564        if (!$parent.length) {
3565          this.wasWrapped = true;
3566        }
3567        this.$container = $parent.length ? $parent : $(this.options.container).wrapInner(this.$element);
3568        this.$container.addClass(this.options.containerClass);
3569
3570        this.$element.addClass(this.options.stickyClass).attr({ 'data-resize': id });
3571
3572        this.scrollCount = this.options.checkEvery;
3573        this.isStuck = false;
3574        $(window).one('load.zf.sticky', function () {
3575          //We calculate the container height to have correct values for anchor points offset calculation.
3576          _this.containerHeight = _this.$element.css("display") == "none" ? 0 : _this.$element[0].getBoundingClientRect().height;
3577          _this.$container.css('height', _this.containerHeight);
3578          _this.elemHeight = _this.containerHeight;
3579          if (_this.options.anchor !== '') {
3580            _this.$anchor = $('#' + _this.options.anchor);
3581          } else {
3582            _this._parsePoints();
3583          }
3584
3585          _this._setSizes(function () {
3586            var scroll = window.pageYOffset;
3587            _this._calc(false, scroll);
3588            //Unstick the element will ensure that proper classes are set.
3589            if (!_this.isStuck) {
3590              _this._removeSticky(scroll >= _this.topPoint ? false : true);
3591            }
3592          });
3593          _this._events(id.split('-').reverse().join('-'));
3594        });
3595      }
3596
3597      /**
3598       * If using multiple elements as anchors, calculates the top and bottom pixel values the sticky thing should stick and unstick on.
3599       * @function
3600       * @private
3601       */
3602
3603    }, {
3604      key: '_parsePoints',
3605      value: function _parsePoints() {
3606        var top = this.options.topAnchor == "" ? 1 : this.options.topAnchor,
3607            btm = this.options.btmAnchor == "" ? document.documentElement.scrollHeight : this.options.btmAnchor,
3608            pts = [top, btm],
3609            breaks = {};
3610        for (var i = 0, len = pts.length; i < len && pts[i]; i++) {
3611          var pt;
3612          if (typeof pts[i] === 'number') {
3613            pt = pts[i];
3614          } else {
3615            var place = pts[i].split(':'),
3616                anchor = $('#' + place[0]);
3617
3618            pt = anchor.offset().top;
3619            if (place[1] && place[1].toLowerCase() === 'bottom') {
3620              pt += anchor[0].getBoundingClientRect().height;
3621            }
3622          }
3623          breaks[i] = pt;
3624        }
3625
3626        this.points = breaks;
3627        return;
3628      }
3629
3630      /**
3631       * Adds event handlers for the scrolling element.
3632       * @private
3633       * @param {String} id - psuedo-random id for unique scroll event listener.
3634       */
3635
3636    }, {
3637      key: '_events',
3638      value: function _events(id) {
3639        var _this = this,
3640            scrollListener = this.scrollListener = 'scroll.zf.' + id;
3641        if (this.isOn) {
3642          return;
3643        }
3644        if (this.canStick) {
3645          this.isOn = true;
3646          $(window).off(scrollListener).on(scrollListener, function (e) {
3647            if (_this.scrollCount === 0) {
3648              _this.scrollCount = _this.options.checkEvery;
3649              _this._setSizes(function () {
3650                _this._calc(false, window.pageYOffset);
3651              });
3652            } else {
3653              _this.scrollCount--;
3654              _this._calc(false, window.pageYOffset);
3655            }
3656          });
3657        }
3658
3659        this.$element.off('resizeme.zf.trigger').on('resizeme.zf.trigger', function (e, el) {
3660          _this._setSizes(function () {
3661            _this._calc(false);
3662            if (_this.canStick) {
3663              if (!_this.isOn) {
3664                _this._events(id);
3665              }
3666            } else if (_this.isOn) {
3667              _this._pauseListeners(scrollListener);
3668            }
3669          });
3670        });
3671      }
3672
3673      /**
3674       * Removes event handlers for scroll and change events on anchor.
3675       * @fires Sticky#pause
3676       * @param {String} scrollListener - unique, namespaced scroll listener attached to `window`
3677       */
3678
3679    }, {
3680      key: '_pauseListeners',
3681      value: function _pauseListeners(scrollListener) {
3682        this.isOn = false;
3683        $(window).off(scrollListener);
3684
3685        /**
3686         * Fires when the plugin is paused due to resize event shrinking the view.
3687         * @event Sticky#pause
3688         * @private
3689         */
3690        this.$element.trigger('pause.zf.sticky');
3691      }
3692
3693      /**
3694       * Called on every `scroll` event and on `_init`
3695       * fires functions based on booleans and cached values
3696       * @param {Boolean} checkSizes - true if plugin should recalculate sizes and breakpoints.
3697       * @param {Number} scroll - current scroll position passed from scroll event cb function. If not passed, defaults to `window.pageYOffset`.
3698       */
3699
3700    }, {
3701      key: '_calc',
3702      value: function _calc(checkSizes, scroll) {
3703        if (checkSizes) {
3704          this._setSizes();
3705        }
3706
3707        if (!this.canStick) {
3708          if (this.isStuck) {
3709            this._removeSticky(true);
3710          }
3711          return false;
3712        }
3713
3714        if (!scroll) {
3715          scroll = window.pageYOffset;
3716        }
3717
3718        if (scroll >= this.topPoint) {
3719          if (scroll <= this.bottomPoint) {
3720            if (!this.isStuck) {
3721              this._setSticky();
3722            }
3723          } else {
3724            if (this.isStuck) {
3725              this._removeSticky(false);
3726            }
3727          }
3728        } else {
3729          if (this.isStuck) {
3730            this._removeSticky(true);
3731          }
3732        }
3733      }
3734
3735      /**
3736       * Causes the $element to become stuck.
3737       * Adds `position: fixed;`, and helper classes.
3738       * @fires Sticky#stuckto
3739       * @function
3740       * @private
3741       */
3742
3743    }, {
3744      key: '_setSticky',
3745      value: function _setSticky() {
3746        var _this = this,
3747            stickTo = this.options.stickTo,
3748            mrgn = stickTo === 'top' ? 'marginTop' : 'marginBottom',
3749            notStuckTo = stickTo === 'top' ? 'bottom' : 'top',
3750            css = {};
3751
3752        css[mrgn] = this.options[mrgn] + 'em';
3753        css[stickTo] = 0;
3754        css[notStuckTo] = 'auto';
3755        this.isStuck = true;
3756        this.$element.removeClass('is-anchored is-at-' + notStuckTo).addClass('is-stuck is-at-' + stickTo).css(css)
3757        /**
3758         * Fires when the $element has become `position: fixed;`
3759         * Namespaced to `top` or `bottom`, e.g. `sticky.zf.stuckto:top`
3760         * @event Sticky#stuckto
3761         */
3762        .trigger('sticky.zf.stuckto:' + stickTo);
3763        this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () {
3764          _this._setSizes();
3765        });
3766      }
3767
3768      /**
3769       * Causes the $element to become unstuck.
3770       * Removes `position: fixed;`, and helper classes.
3771       * Adds other helper classes.
3772       * @param {Boolean} isTop - tells the function if the $element should anchor to the top or bottom of its $anchor element.
3773       * @fires Sticky#unstuckfrom
3774       * @private
3775       */
3776
3777    }, {
3778      key: '_removeSticky',
3779      value: function _removeSticky(isTop) {
3780        var stickTo = this.options.stickTo,
3781            stickToTop = stickTo === 'top',
3782            css = {},
3783            anchorPt = (this.points ? this.points[1] - this.points[0] : this.anchorHeight) - this.elemHeight,
3784            mrgn = stickToTop ? 'marginTop' : 'marginBottom',
3785            notStuckTo = stickToTop ? 'bottom' : 'top',
3786            topOrBottom = isTop ? 'top' : 'bottom';
3787
3788        css[mrgn] = 0;
3789
3790        css['bottom'] = 'auto';
3791        if (isTop) {
3792          css['top'] = 0;
3793        } else {
3794          css['top'] = anchorPt;
3795        }
3796
3797        this.isStuck = false;
3798        this.$element.removeClass('is-stuck is-at-' + stickTo).addClass('is-anchored is-at-' + topOrBottom).css(css)
3799        /**
3800         * Fires when the $element has become anchored.
3801         * Namespaced to `top` or `bottom`, e.g. `sticky.zf.unstuckfrom:bottom`
3802         * @event Sticky#unstuckfrom
3803         */
3804        .trigger('sticky.zf.unstuckfrom:' + topOrBottom);
3805      }
3806
3807      /**
3808       * Sets the $element and $container sizes for plugin.
3809       * Calls `_setBreakPoints`.
3810       * @param {Function} cb - optional callback function to fire on completion of `_setBreakPoints`.
3811       * @private
3812       */
3813
3814    }, {
3815      key: '_setSizes',
3816      value: function _setSizes(cb) {
3817        this.canStick = Foundation.MediaQuery.is(this.options.stickyOn);
3818        if (!this.canStick) {
3819          if (cb && typeof cb === 'function') {
3820            cb();
3821          }
3822        }
3823        var _this = this,
3824            newElemWidth = this.$container[0].getBoundingClientRect().width,
3825            comp = window.getComputedStyle(this.$container[0]),
3826            pdngl = parseInt(comp['padding-left'], 10),
3827            pdngr = parseInt(comp['padding-right'], 10);
3828
3829        if (this.$anchor && this.$anchor.length) {
3830          this.anchorHeight = this.$anchor[0].getBoundingClientRect().height;
3831        } else {
3832          this._parsePoints();
3833        }
3834
3835        this.$element.css({
3836          'max-width': newElemWidth - pdngl - pdngr + 'px'
3837        });
3838
3839        var newContainerHeight = this.$element[0].getBoundingClientRect().height || this.containerHeight;
3840        if (this.$element.css("display") == "none") {
3841          newContainerHeight = 0;
3842        }
3843        this.containerHeight = newContainerHeight;
3844        this.$container.css({
3845          height: newContainerHeight
3846        });
3847        this.elemHeight = newContainerHeight;
3848
3849        if (!this.isStuck) {
3850          if (this.$element.hasClass('is-at-bottom')) {
3851            var anchorPt = (this.points ? this.points[1] - this.$container.offset().top : this.anchorHeight) - this.elemHeight;
3852            this.$element.css('top', anchorPt);
3853          }
3854        }
3855
3856        this._setBreakPoints(newContainerHeight, function () {
3857          if (cb && typeof cb === 'function') {
3858            cb();
3859          }
3860        });
3861      }
3862
3863      /**
3864       * Sets the upper and lower breakpoints for the element to become sticky/unsticky.
3865       * @param {Number} elemHeight - px value for sticky.$element height, calculated by `_setSizes`.
3866       * @param {Function} cb - optional callback function to be called on completion.
3867       * @private
3868       */
3869
3870    }, {
3871      key: '_setBreakPoints',
3872      value: function _setBreakPoints(elemHeight, cb) {
3873        if (!this.canStick) {
3874          if (cb && typeof cb === 'function') {
3875            cb();
3876          } else {
3877            return false;
3878          }
3879        }
3880        var mTop = emCalc(this.options.marginTop),
3881            mBtm = emCalc(this.options.marginBottom),
3882            topPoint = this.points ? this.points[0] : this.$anchor.offset().top,
3883            bottomPoint = this.points ? this.points[1] : topPoint + this.anchorHeight,
3884
3885        // topPoint = this.$anchor.offset().top || this.points[0],
3886        // bottomPoint = topPoint + this.anchorHeight || this.points[1],
3887        winHeight = window.innerHeight;
3888
3889        if (this.options.stickTo === 'top') {
3890          topPoint -= mTop;
3891          bottomPoint -= elemHeight + mTop;
3892        } else if (this.options.stickTo === 'bottom') {
3893          topPoint -= winHeight - (elemHeight + mBtm);
3894          bottomPoint -= winHeight - mBtm;
3895        } else {
3896          //this would be the stickTo: both option... tricky
3897        }
3898
3899        this.topPoint = topPoint;
3900        this.bottomPoint = bottomPoint;
3901
3902        if (cb && typeof cb === 'function') {
3903          cb();
3904        }
3905      }
3906
3907      /**
3908       * Destroys the current sticky element.
3909       * Resets the element to the top position first.
3910       * Removes event listeners, JS-added css properties and classes, and unwraps the $element if the JS added the $container.
3911       * @function
3912       */
3913
3914    }, {
3915      key: 'destroy',
3916      value: function destroy() {
3917        this._removeSticky(true);
3918
3919        this.$element.removeClass(this.options.stickyClass + ' is-anchored is-at-top').css({
3920          height: '',
3921          top: '',
3922          bottom: '',
3923          'max-width': ''
3924        }).off('resizeme.zf.trigger');
3925        if (this.$anchor && this.$anchor.length) {
3926          this.$anchor.off('change.zf.sticky');
3927        }
3928        $(window).off(this.scrollListener);
3929
3930        if (this.wasWrapped) {
3931          this.$element.unwrap();
3932        } else {
3933          this.$container.removeClass(this.options.containerClass).css({
3934            height: ''
3935          });
3936        }
3937        Foundation.unregisterPlugin(this);
3938      }
3939    }]);
3940
3941    return Sticky;
3942  }();
3943
3944  Sticky.defaults = {
3945    /**
3946     * Customizable container template. Add your own classes for styling and sizing.
3947     * @option
3948     * @type {string}
3949     * @default '&lt;div data-sticky-container&gt;&lt;/div&gt;'
3950     */
3951    container: '<div data-sticky-container></div>',
3952    /**
3953     * Location in the view the element sticks to. Can be `'top'` or `'bottom'`.
3954     * @option
3955     * @type {string}
3956     * @default 'top'
3957     */
3958    stickTo: 'top',
3959    /**
3960     * If anchored to a single element, the id of that element.
3961     * @option
3962     * @type {string}
3963     * @default ''
3964     */
3965    anchor: '',
3966    /**
3967     * If using more than one element as anchor points, the id of the top anchor.
3968     * @option
3969     * @type {string}
3970     * @default ''
3971     */
3972    topAnchor: '',
3973    /**
3974     * If using more than one element as anchor points, the id of the bottom anchor.
3975     * @option
3976     * @type {string}
3977     * @default ''
3978     */
3979    btmAnchor: '',
3980    /**
3981     * Margin, in `em`'s to apply to the top of the element when it becomes sticky.
3982     * @option
3983     * @type {number}
3984     * @default 1
3985     */
3986    marginTop: 1,
3987    /**
3988     * Margin, in `em`'s to apply to the bottom of the element when it becomes sticky.
3989     * @option
3990     * @type {number}
3991     * @default 1
3992     */
3993    marginBottom: 1,
3994    /**
3995     * Breakpoint string that is the minimum screen size an element should become sticky.
3996     * @option
3997     * @type {string}
3998     * @default 'medium'
3999     */
4000    stickyOn: 'medium',
4001    /**
4002     * Class applied to sticky element, and removed on destruction. Foundation defaults to `sticky`.
4003     * @option
4004     * @type {string}
4005     * @default 'sticky'
4006     */
4007    stickyClass: 'sticky',
4008    /**
4009     * Class applied to sticky container. Foundation defaults to `sticky-container`.
4010     * @option
4011     * @type {string}
4012     * @default 'sticky-container'
4013     */
4014    containerClass: 'sticky-container',
4015    /**
4016     * Number of scroll events between the plugin's recalculating sticky points. Setting it to `0` will cause it to recalc every scroll event, setting it to `-1` will prevent recalc on scroll.
4017     * @option
4018     * @type {number}
4019     * @default -1
4020     */
4021    checkEvery: -1
4022  };
4023
4024  /**
4025   * Helper function to calculate em values
4026   * @param Number {em} - number of em's to calculate into pixels
4027   */
4028  function emCalc(em) {
4029    return parseInt(window.getComputedStyle(document.body, null).fontSize, 10) * em;
4030  }
4031
4032  // Window exports
4033  Foundation.plugin(Sticky, 'Sticky');
4034}(jQuery);
4035'use strict';
4036
4037var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4038
4039function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4040
4041!function ($) {
4042
4043  /**
4044   * OffCanvas module.
4045   * @module foundation.offcanvas
4046   * @requires foundation.util.keyboard
4047   * @requires foundation.util.mediaQuery
4048   * @requires foundation.util.triggers
4049   * @requires foundation.util.motion
4050   */
4051
4052  var OffCanvas = function () {
4053    /**
4054     * Creates a new instance of an off-canvas wrapper.
4055     * @class
4056     * @fires OffCanvas#init
4057     * @param {Object} element - jQuery object to initialize.
4058     * @param {Object} options - Overrides to the default plugin settings.
4059     */
4060    function OffCanvas(element, options) {
4061      _classCallCheck(this, OffCanvas);
4062
4063      this.$element = element;
4064      this.options = $.extend({}, OffCanvas.defaults, this.$element.data(), options);
4065      this.$lastTrigger = $();
4066      this.$triggers = $();
4067
4068      this._init();
4069      this._events();
4070
4071      Foundation.registerPlugin(this, 'OffCanvas');
4072      Foundation.Keyboard.register('OffCanvas', {
4073        'ESCAPE': 'close'
4074      });
4075    }
4076
4077    /**
4078     * Initializes the off-canvas wrapper by adding the exit overlay (if needed).
4079     * @function
4080     * @private
4081     */
4082
4083
4084    _createClass(OffCanvas, [{
4085      key: '_init',
4086      value: function _init() {
4087        var id = this.$element.attr('id');
4088
4089        this.$element.attr('aria-hidden', 'true');
4090
4091        this.$element.addClass('is-transition-' + this.options.transition);
4092
4093        // Find triggers that affect this element and add aria-expanded to them
4094        this.$triggers = $(document).find('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-expanded', 'false').attr('aria-controls', id);
4095
4096        // Add an overlay over the content if necessary
4097        if (this.options.contentOverlay === true) {
4098          var overlay = document.createElement('div');
4099          var overlayPosition = $(this.$element).css("position") === 'fixed' ? 'is-overlay-fixed' : 'is-overlay-absolute';
4100          overlay.setAttribute('class', 'js-off-canvas-overlay ' + overlayPosition);
4101          this.$overlay = $(overlay);
4102          if (overlayPosition === 'is-overlay-fixed') {
4103            $('body').append(this.$overlay);
4104          } else {
4105            this.$element.siblings('[data-off-canvas-content]').append(this.$overlay);
4106          }
4107        }
4108
4109        this.options.isRevealed = this.options.isRevealed || new RegExp(this.options.revealClass, 'g').test(this.$element[0].className);
4110
4111        if (this.options.isRevealed === true) {
4112          this.options.revealOn = this.options.revealOn || this.$element[0].className.match(/(reveal-for-medium|reveal-for-large)/g)[0].split('-')[2];
4113          this._setMQChecker();
4114        }
4115        if (!this.options.transitionTime === true) {
4116          this.options.transitionTime = parseFloat(window.getComputedStyle($('[data-off-canvas]')[0]).transitionDuration) * 1000;
4117        }
4118      }
4119
4120      /**
4121       * Adds event handlers to the off-canvas wrapper and the exit overlay.
4122       * @function
4123       * @private
4124       */
4125
4126    }, {
4127      key: '_events',
4128      value: function _events() {
4129        this.$element.off('.zf.trigger .zf.offcanvas').on({
4130          'open.zf.trigger': this.open.bind(this),
4131          'close.zf.trigger': this.close.bind(this),
4132          'toggle.zf.trigger': this.toggle.bind(this),
4133          'keydown.zf.offcanvas': this._handleKeyboard.bind(this)
4134        });
4135
4136        if (this.options.closeOnClick === true) {
4137          var $target = this.options.contentOverlay ? this.$overlay : $('[data-off-canvas-content]');
4138          $target.on({ 'click.zf.offcanvas': this.close.bind(this) });
4139        }
4140      }
4141
4142      /**
4143       * Applies event listener for elements that will reveal at certain breakpoints.
4144       * @private
4145       */
4146
4147    }, {
4148      key: '_setMQChecker',
4149      value: function _setMQChecker() {
4150        var _this = this;
4151
4152        $(window).on('changed.zf.mediaquery', function () {
4153          if (Foundation.MediaQuery.atLeast(_this.options.revealOn)) {
4154            _this.reveal(true);
4155          } else {
4156            _this.reveal(false);
4157          }
4158        }).one('load.zf.offcanvas', function () {
4159          if (Foundation.MediaQuery.atLeast(_this.options.revealOn)) {
4160            _this.reveal(true);
4161          }
4162        });
4163      }
4164
4165      /**
4166       * Handles the revealing/hiding the off-canvas at breakpoints, not the same as open.
4167       * @param {Boolean} isRevealed - true if element should be revealed.
4168       * @function
4169       */
4170
4171    }, {
4172      key: 'reveal',
4173      value: function reveal(isRevealed) {
4174        var $closer = this.$element.find('[data-close]');
4175        if (isRevealed) {
4176          this.close();
4177          this.isRevealed = true;
4178          this.$element.attr('aria-hidden', 'false');
4179          this.$element.off('open.zf.trigger toggle.zf.trigger');
4180          if ($closer.length) {
4181            $closer.hide();
4182          }
4183        } else {
4184          this.isRevealed = false;
4185          this.$element.attr('aria-hidden', 'true');
4186          this.$element.on({
4187            'open.zf.trigger': this.open.bind(this),
4188            'toggle.zf.trigger': this.toggle.bind(this)
4189          });
4190          if ($closer.length) {
4191            $closer.show();
4192          }
4193        }
4194      }
4195
4196      /**
4197       * Stops scrolling of the body when offcanvas is open on mobile Safari and other troublesome browsers.
4198       * @private
4199       */
4200
4201    }, {
4202      key: '_stopScrolling',
4203      value: function _stopScrolling(event) {
4204        return false;
4205      }
4206
4207      // Taken and adapted from http://stackoverflow.com/questions/16889447/prevent-full-page-scrolling-ios
4208      // Only really works for y, not sure how to extend to x or if we need to.
4209
4210    }, {
4211      key: '_recordScrollable',
4212      value: function _recordScrollable(event) {
4213        var elem = this; // called from event handler context with this as elem
4214
4215        // If the element is scrollable (content overflows), then...
4216        if (elem.scrollHeight !== elem.clientHeight) {
4217          // If we're at the top, scroll down one pixel to allow scrolling up
4218          if (elem.scrollTop === 0) {
4219            elem.scrollTop = 1;
4220          }
4221          // If we're at the bottom, scroll up one pixel to allow scrolling down
4222          if (elem.scrollTop === elem.scrollHeight - elem.clientHeight) {
4223            elem.scrollTop = elem.scrollHeight - elem.clientHeight - 1;
4224          }
4225        }
4226        elem.allowUp = elem.scrollTop > 0;
4227        elem.allowDown = elem.scrollTop < elem.scrollHeight - elem.clientHeight;
4228        elem.lastY = event.originalEvent.pageY;
4229      }
4230    }, {
4231      key: '_stopScrollPropagation',
4232      value: function _stopScrollPropagation(event) {
4233        var elem = this; // called from event handler context with this as elem
4234        var up = event.pageY < elem.lastY;
4235        var down = !up;
4236        elem.lastY = event.pageY;
4237
4238        if (up && elem.allowUp || down && elem.allowDown) {
4239          event.stopPropagation();
4240        } else {
4241          event.preventDefault();
4242        }
4243      }
4244
4245      /**
4246       * Opens the off-canvas menu.
4247       * @function
4248       * @param {Object} event - Event object passed from listener.
4249       * @param {jQuery} trigger - element that triggered the off-canvas to open.
4250       * @fires OffCanvas#opened
4251       */
4252
4253    }, {
4254      key: 'open',
4255      value: function open(event, trigger) {
4256        if (this.$element.hasClass('is-open') || this.isRevealed) {
4257          return;
4258        }
4259        var _this = this;
4260
4261        if (trigger) {
4262          this.$lastTrigger = trigger;
4263        }
4264
4265        if (this.options.forceTo === 'top') {
4266          window.scrollTo(0, 0);
4267        } else if (this.options.forceTo === 'bottom') {
4268          window.scrollTo(0, document.body.scrollHeight);
4269        }
4270
4271        /**
4272         * Fires when the off-canvas menu opens.
4273         * @event OffCanvas#opened
4274         */
4275        _this.$element.addClass('is-open');
4276
4277        this.$triggers.attr('aria-expanded', 'true');
4278        this.$element.attr('aria-hidden', 'false').trigger('opened.zf.offcanvas');
4279
4280        // If `contentScroll` is set to false, add class and disable scrolling on touch devices.
4281        if (this.options.contentScroll === false) {
4282          $('body').addClass('is-off-canvas-open').on('touchmove', this._stopScrolling);
4283          this.$element.on('touchstart', this._recordScrollable);
4284          this.$element.on('touchmove', this._stopScrollPropagation);
4285        }
4286
4287        if (this.options.contentOverlay === true) {
4288          this.$overlay.addClass('is-visible');
4289        }
4290
4291        if (this.options.closeOnClick === true && this.options.contentOverlay === true) {
4292          this.$overlay.addClass('is-closable');
4293        }
4294
4295        if (this.options.autoFocus === true) {
4296          this.$element.one(Foundation.transitionend(this.$element), function () {
4297            _this.$element.find('a, button').eq(0).focus();
4298          });
4299        }
4300
4301        if (this.options.trapFocus === true) {
4302          this.$element.siblings('[data-off-canvas-content]').attr('tabindex', '-1');
4303          Foundation.Keyboard.trapFocus(this.$element);
4304        }
4305      }
4306
4307      /**
4308       * Closes the off-canvas menu.
4309       * @function
4310       * @param {Function} cb - optional cb to fire after closure.
4311       * @fires OffCanvas#closed
4312       */
4313
4314    }, {
4315      key: 'close',
4316      value: function close(cb) {
4317        if (!this.$element.hasClass('is-open') || this.isRevealed) {
4318          return;
4319        }
4320
4321        var _this = this;
4322
4323        _this.$element.removeClass('is-open');
4324
4325        this.$element.attr('aria-hidden', 'true')
4326        /**
4327         * Fires when the off-canvas menu opens.
4328         * @event OffCanvas#closed
4329         */
4330        .trigger('closed.zf.offcanvas');
4331
4332        // If `contentScroll` is set to false, remove class and re-enable scrolling on touch devices.
4333        if (this.options.contentScroll === false) {
4334          $('body').removeClass('is-off-canvas-open').off('touchmove', this._stopScrolling);
4335          this.$element.off('touchstart', this._recordScrollable);
4336          this.$element.off('touchmove', this._stopScrollPropagation);
4337        }
4338
4339        if (this.options.contentOverlay === true) {
4340          this.$overlay.removeClass('is-visible');
4341        }
4342
4343        if (this.options.closeOnClick === true && this.options.contentOverlay === true) {
4344          this.$overlay.removeClass('is-closable');
4345        }
4346
4347        this.$triggers.attr('aria-expanded', 'false');
4348
4349        if (this.options.trapFocus === true) {
4350          this.$element.siblings('[data-off-canvas-content]').removeAttr('tabindex');
4351          Foundation.Keyboard.releaseFocus(this.$element);
4352        }
4353      }
4354
4355      /**
4356       * Toggles the off-canvas menu open or closed.
4357       * @function
4358       * @param {Object} event - Event object passed from listener.
4359       * @param {jQuery} trigger - element that triggered the off-canvas to open.
4360       */
4361
4362    }, {
4363      key: 'toggle',
4364      value: function toggle(event, trigger) {
4365        if (this.$element.hasClass('is-open')) {
4366          this.close(event, trigger);
4367        } else {
4368          this.open(event, trigger);
4369        }
4370      }
4371
4372      /**
4373       * Handles keyboard input when detected. When the escape key is pressed, the off-canvas menu closes, and focus is restored to the element that opened the menu.
4374       * @function
4375       * @private
4376       */
4377
4378    }, {
4379      key: '_handleKeyboard',
4380      value: function _handleKeyboard(e) {
4381        var _this2 = this;
4382
4383        Foundation.Keyboard.handleKey(e, 'OffCanvas', {
4384          close: function () {
4385            _this2.close();
4386            _this2.$lastTrigger.focus();
4387            return true;
4388          },
4389          handled: function () {
4390            e.stopPropagation();
4391            e.preventDefault();
4392          }
4393        });
4394      }
4395
4396      /**
4397       * Destroys the offcanvas plugin.
4398       * @function
4399       */
4400
4401    }, {
4402      key: 'destroy',
4403      value: function destroy() {
4404        this.close();
4405        this.$element.off('.zf.trigger .zf.offcanvas');
4406        this.$overlay.off('.zf.offcanvas');
4407
4408        Foundation.unregisterPlugin(this);
4409      }
4410    }]);
4411
4412    return OffCanvas;
4413  }();
4414
4415  OffCanvas.defaults = {
4416    /**
4417     * Allow the user to click outside of the menu to close it.
4418     * @option
4419     * @type {boolean}
4420     * @default true
4421     */
4422    closeOnClick: true,
4423
4424    /**
4425     * Adds an overlay on top of `[data-off-canvas-content]`.
4426     * @option
4427     * @type {boolean}
4428     * @default true
4429     */
4430    contentOverlay: true,
4431
4432    /**
4433     * Enable/disable scrolling of the main content when an off canvas panel is open.
4434     * @option
4435     * @type {boolean}
4436     * @default true
4437     */
4438    contentScroll: true,
4439
4440    /**
4441     * Amount of time in ms the open and close transition requires. If none selected, pulls from body style.
4442     * @option
4443     * @type {number}
4444     * @default 0
4445     */
4446    transitionTime: 0,
4447
4448    /**
4449     * Type of transition for the offcanvas menu. Options are 'push', 'detached' or 'slide'.
4450     * @option
4451     * @type {string}
4452     * @default push
4453     */
4454    transition: 'push',
4455
4456    /**
4457     * Force the page to scroll to top or bottom on open.
4458     * @option
4459     * @type {?string}
4460     * @default null
4461     */
4462    forceTo: null,
4463
4464    /**
4465     * Allow the offcanvas to remain open for certain breakpoints.
4466     * @option
4467     * @type {boolean}
4468     * @default false
4469     */
4470    isRevealed: false,
4471
4472    /**
4473     * Breakpoint at which to reveal. JS will use a RegExp to target standard classes, if changing classnames, pass your class with the `revealClass` option.
4474     * @option
4475     * @type {?string}
4476     * @default null
4477     */
4478    revealOn: null,
4479
4480    /**
4481     * Force focus to the offcanvas on open. If true, will focus the opening trigger on close.
4482     * @option
4483     * @type {boolean}
4484     * @default true
4485     */
4486    autoFocus: true,
4487
4488    /**
4489     * Class used to force an offcanvas to remain open. Foundation defaults for this are `reveal-for-large` & `reveal-for-medium`.
4490     * @option
4491     * @type {string}
4492     * @default reveal-for-
4493     * @todo improve the regex testing for this.
4494     */
4495    revealClass: 'reveal-for-',
4496
4497    /**
4498     * Triggers optional focus trapping when opening an offcanvas. Sets tabindex of [data-off-canvas-content] to -1 for accessibility purposes.
4499     * @option
4500     * @type {boolean}
4501     * @default false
4502     */
4503    trapFocus: false
4504  };
4505
4506  // Window exports
4507  Foundation.plugin(OffCanvas, 'OffCanvas');
4508}(jQuery);
4509'use strict';
4510
4511!function ($) {
4512
4513  function Timer(elem, options, cb) {
4514    var _this = this,
4515        duration = options.duration,
4516        //options is an object for easily adding features later.
4517    nameSpace = Object.keys(elem.data())[0] || 'timer',
4518        remain = -1,
4519        start,
4520        timer;
4521
4522    this.isPaused = false;
4523
4524    this.restart = function () {
4525      remain = -1;
4526      clearTimeout(timer);
4527      this.start();
4528    };
4529
4530    this.start = function () {
4531      this.isPaused = false;
4532      // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.
4533      clearTimeout(timer);
4534      remain = remain <= 0 ? duration : remain;
4535      elem.data('paused', false);
4536      start = Date.now();
4537      timer = setTimeout(function () {
4538        if (options.infinite) {
4539          _this.restart(); //rerun the timer.
4540        }
4541        if (cb && typeof cb === 'function') {
4542          cb();
4543        }
4544      }, remain);
4545      elem.trigger('timerstart.zf.' + nameSpace);
4546    };
4547
4548    this.pause = function () {
4549      this.isPaused = true;
4550      //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.
4551      clearTimeout(timer);
4552      elem.data('paused', true);
4553      var end = Date.now();
4554      remain = remain - (end - start);
4555      elem.trigger('timerpaused.zf.' + nameSpace);
4556    };
4557  }
4558
4559  /**
4560   * Runs a callback function when images are fully loaded.
4561   * @param {Object} images - Image(s) to check if loaded.
4562   * @param {Func} callback - Function to execute when image is fully loaded.
4563   */
4564  function onImagesLoaded(images, callback) {
4565    var self = this,
4566        unloaded = images.length;
4567
4568    if (unloaded === 0) {
4569      callback();
4570    }
4571
4572    images.each(function () {
4573      // Check if image is loaded
4574      if (this.complete || this.readyState === 4 || this.readyState === 'complete') {
4575        singleImageLoaded();
4576      }
4577      // Force load the image
4578      else {
4579          // fix for IE. See https://css-tricks.com/snippets/jquery/fixing-load-in-ie-for-cached-images/
4580          var src = $(this).attr('src');
4581          $(this).attr('src', src + (src.indexOf('?') >= 0 ? '&' : '?') + new Date().getTime());
4582          $(this).one('load', function () {
4583            singleImageLoaded();
4584          });
4585        }
4586    });
4587
4588    function singleImageLoaded() {
4589      unloaded--;
4590      if (unloaded === 0) {
4591        callback();
4592      }
4593    }
4594  }
4595
4596  Foundation.Timer = Timer;
4597  Foundation.onImagesLoaded = onImagesLoaded;
4598}(jQuery);
4599'use strict';
4600
4601!function ($) {
4602
4603  Foundation.Box = {
4604    ImNotTouchingYou: ImNotTouchingYou,
4605    GetDimensions: GetDimensions,
4606    GetOffsets: GetOffsets
4607  };
4608
4609  /**
4610   * Compares the dimensions of an element to a container and determines collision events with container.
4611   * @function
4612   * @param {jQuery} element - jQuery object to test for collisions.
4613   * @param {jQuery} parent - jQuery object to use as bounding container.
4614   * @param {Boolean} lrOnly - set to true to check left and right values only.
4615   * @param {Boolean} tbOnly - set to true to check top and bottom values only.
4616   * @default if no parent object passed, detects collisions with `window`.
4617   * @returns {Boolean} - true if collision free, false if a collision in any direction.
4618   */
4619  function ImNotTouchingYou(element, parent, lrOnly, tbOnly) {
4620    var eleDims = GetDimensions(element),
4621        top,
4622        bottom,
4623        left,
4624        right;
4625
4626    if (parent) {
4627      var parDims = GetDimensions(parent);
4628
4629      bottom = eleDims.offset.top + eleDims.height <= parDims.height + parDims.offset.top;
4630      top = eleDims.offset.top >= parDims.offset.top;
4631      left = eleDims.offset.left >= parDims.offset.left;
4632      right = eleDims.offset.left + eleDims.width <= parDims.width + parDims.offset.left;
4633    } else {
4634      bottom = eleDims.offset.top + eleDims.height <= eleDims.windowDims.height + eleDims.windowDims.offset.top;
4635      top = eleDims.offset.top >= eleDims.windowDims.offset.top;
4636      left = eleDims.offset.left >= eleDims.windowDims.offset.left;
4637      right = eleDims.offset.left + eleDims.width <= eleDims.windowDims.width;
4638    }
4639
4640    var allDirs = [bottom, top, left, right];
4641
4642    if (lrOnly) {
4643      return left === right === true;
4644    }
4645
4646    if (tbOnly) {
4647      return top === bottom === true;
4648    }
4649
4650    return allDirs.indexOf(false) === -1;
4651  };
4652
4653  /**
4654   * Uses native methods to return an object of dimension values.
4655   * @function
4656   * @param {jQuery || HTML} element - jQuery object or DOM element for which to get the dimensions. Can be any element other that document or window.
4657   * @returns {Object} - nested object of integer pixel values
4658   * TODO - if element is window, return only those values.
4659   */
4660  function GetDimensions(elem, test) {
4661    elem = elem.length ? elem[0] : elem;
4662
4663    if (elem === window || elem === document) {
4664      throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");
4665    }
4666
4667    var rect = elem.getBoundingClientRect(),
4668        parRect = elem.parentNode.getBoundingClientRect(),
4669        winRect = document.body.getBoundingClientRect(),
4670        winY = window.pageYOffset,
4671        winX = window.pageXOffset;
4672
4673    return {
4674      width: rect.width,
4675      height: rect.height,
4676      offset: {
4677        top: rect.top + winY,
4678        left: rect.left + winX
4679      },
4680      parentDims: {
4681        width: parRect.width,
4682        height: parRect.height,
4683        offset: {
4684          top: parRect.top + winY,
4685          left: parRect.left + winX
4686        }
4687      },
4688      windowDims: {
4689        width: winRect.width,
4690        height: winRect.height,
4691        offset: {
4692          top: winY,
4693          left: winX
4694        }
4695      }
4696    };
4697  }
4698
4699  /**
4700   * Returns an object of top and left integer pixel values for dynamically rendered elements,
4701   * such as: Tooltip, Reveal, and Dropdown
4702   * @function
4703   * @param {jQuery} element - jQuery object for the element being positioned.
4704   * @param {jQuery} anchor - jQuery object for the element's anchor point.
4705   * @param {String} position - a string relating to the desired position of the element, relative to it's anchor
4706   * @param {Number} vOffset - integer pixel value of desired vertical separation between anchor and element.
4707   * @param {Number} hOffset - integer pixel value of desired horizontal separation between anchor and element.
4708   * @param {Boolean} isOverflow - if a collision event is detected, sets to true to default the element to full width - any desired offset.
4709   * TODO alter/rewrite to work with `em` values as well/instead of pixels
4710   */
4711  function GetOffsets(element, anchor, position, vOffset, hOffset, isOverflow) {
4712    var $eleDims = GetDimensions(element),
4713        $anchorDims = anchor ? GetDimensions(anchor) : null;
4714
4715    switch (position) {
4716      case 'top':
4717        return {
4718          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
4719          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
4720        };
4721        break;
4722      case 'left':
4723        return {
4724          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
4725          top: $anchorDims.offset.top
4726        };
4727        break;
4728      case 'right':
4729        return {
4730          left: $anchorDims.offset.left + $anchorDims.width + hOffset,
4731          top: $anchorDims.offset.top
4732        };
4733        break;
4734      case 'center top':
4735        return {
4736          left: $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
4737          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
4738        };
4739        break;
4740      case 'center bottom':
4741        return {
4742          left: isOverflow ? hOffset : $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
4743          top: $anchorDims.offset.top + $anchorDims.height + vOffset
4744        };
4745        break;
4746      case 'center left':
4747        return {
4748          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
4749          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
4750        };
4751        break;
4752      case 'center right':
4753        return {
4754          left: $anchorDims.offset.left + $anchorDims.width + hOffset + 1,
4755          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
4756        };
4757        break;
4758      case 'center':
4759        return {
4760          left: $eleDims.windowDims.offset.left + $eleDims.windowDims.width / 2 - $eleDims.width / 2,
4761          top: $eleDims.windowDims.offset.top + $eleDims.windowDims.height / 2 - $eleDims.height / 2
4762        };
4763        break;
4764      case 'reveal':
4765        return {
4766          left: ($eleDims.windowDims.width - $eleDims.width) / 2,
4767          top: $eleDims.windowDims.offset.top + vOffset
4768        };
4769      case 'reveal full':
4770        return {
4771          left: $eleDims.windowDims.offset.left,
4772          top: $eleDims.windowDims.offset.top
4773        };
4774        break;
4775      case 'left bottom':
4776        return {
4777          left: $anchorDims.offset.left,
4778          top: $anchorDims.offset.top + $anchorDims.height + vOffset
4779        };
4780        break;
4781      case 'right bottom':
4782        return {
4783          left: $anchorDims.offset.left + $anchorDims.width + hOffset - $eleDims.width,
4784          top: $anchorDims.offset.top + $anchorDims.height + vOffset
4785        };
4786        break;
4787      default:
4788        return {
4789          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left + hOffset,
4790          top: $anchorDims.offset.top + $anchorDims.height + vOffset
4791        };
4792    }
4793  }
4794}(jQuery);
4795'use strict';
4796
4797!function ($) {
4798
4799  var MutationObserver = function () {
4800    var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
4801    for (var i = 0; i < prefixes.length; i++) {
4802      if (prefixes[i] + 'MutationObserver' in window) {
4803        return window[prefixes[i] + 'MutationObserver'];
4804      }
4805    }
4806    return false;
4807  }();
4808
4809  var triggers = function (el, type) {
4810    el.data(type).split(' ').forEach(function (id) {
4811      $('#' + id)[type === 'close' ? 'trigger' : 'triggerHandler'](type + '.zf.trigger', [el]);
4812    });
4813  };
4814  // Elements with [data-open] will reveal a plugin that supports it when clicked.
4815  $(document).on('click.zf.trigger', '[data-open]', function () {
4816    triggers($(this), 'open');
4817  });
4818
4819  // Elements with [data-close] will close a plugin that supports it when clicked.
4820  // If used without a value on [data-close], the event will bubble, allowing it to close a parent component.
4821  $(document).on('click.zf.trigger', '[data-close]', function () {
4822    var id = $(this).data('close');
4823    if (id) {
4824      triggers($(this), 'close');
4825    } else {
4826      $(this).trigger('close.zf.trigger');
4827    }
4828  });
4829
4830  // Elements with [data-toggle] will toggle a plugin that supports it when clicked.
4831  $(document).on('click.zf.trigger', '[data-toggle]', function () {
4832    var id = $(this).data('toggle');
4833    if (id) {
4834      triggers($(this), 'toggle');
4835    } else {
4836      $(this).trigger('toggle.zf.trigger');
4837    }
4838  });
4839
4840  // Elements with [data-closable] will respond to close.zf.trigger events.
4841  $(document).on('close.zf.trigger', '[data-closable]', function (e) {
4842    e.stopPropagation();
4843    var animation = $(this).data('closable');
4844
4845    if (animation !== '') {
4846      Foundation.Motion.animateOut($(this), animation, function () {
4847        $(this).trigger('closed.zf');
4848      });
4849    } else {
4850      $(this).fadeOut().trigger('closed.zf');
4851    }
4852  });
4853
4854  $(document).on('focus.zf.trigger blur.zf.trigger', '[data-toggle-focus]', function () {
4855    var id = $(this).data('toggle-focus');
4856    $('#' + id).triggerHandler('toggle.zf.trigger', [$(this)]);
4857  });
4858
4859  /**
4860  * Fires once after all other scripts have loaded
4861  * @function
4862  * @private
4863  */
4864  $(window).on('load', function () {
4865    checkListeners();
4866  });
4867
4868  function checkListeners() {
4869    eventsListener();
4870    resizeListener();
4871    scrollListener();
4872    mutateListener();
4873    closemeListener();
4874  }
4875
4876  //******** only fires this function once on load, if there's something to watch ********
4877  function closemeListener(pluginName) {
4878    var yetiBoxes = $('[data-yeti-box]'),
4879        plugNames = ['dropdown', 'tooltip', 'reveal'];
4880
4881    if (pluginName) {
4882      if (typeof pluginName === 'string') {
4883        plugNames.push(pluginName);
4884      } else if (typeof pluginName === 'object' && typeof pluginName[0] === 'string') {
4885        plugNames.concat(pluginName);
4886      } else {
4887        console.error('Plugin names must be strings');
4888      }
4889    }
4890    if (yetiBoxes.length) {
4891      var listeners = plugNames.map(function (name) {
4892        return 'closeme.zf.' + name;
4893      }).join(' ');
4894
4895      $(window).off(listeners).on(listeners, function (e, pluginId) {
4896        var plugin = e.namespace.split('.')[0];
4897        var plugins = $('[data-' + plugin + ']').not('[data-yeti-box="' + pluginId + '"]');
4898
4899        plugins.each(function () {
4900          var _this = $(this);
4901
4902          _this.triggerHandler('close.zf.trigger', [_this]);
4903        });
4904      });
4905    }
4906  }
4907
4908  function resizeListener(debounce) {
4909    var timer = void 0,
4910        $nodes = $('[data-resize]');
4911    if ($nodes.length) {
4912      $(window).off('resize.zf.trigger').on('resize.zf.trigger', function (e) {
4913        if (timer) {
4914          clearTimeout(timer);
4915        }
4916
4917        timer = setTimeout(function () {
4918
4919          if (!MutationObserver) {
4920            //fallback for IE 9
4921            $nodes.each(function () {
4922              $(this).triggerHandler('resizeme.zf.trigger');
4923            });
4924          }
4925          //trigger all listening elements and signal a resize event
4926          $nodes.attr('data-events', "resize");
4927        }, debounce || 10); //default time to emit resize event
4928      });
4929    }
4930  }
4931
4932  function scrollListener(debounce) {
4933    var timer = void 0,
4934        $nodes = $('[data-scroll]');
4935    if ($nodes.length) {
4936      $(window).off('scroll.zf.trigger').on('scroll.zf.trigger', function (e) {
4937        if (timer) {
4938          clearTimeout(timer);
4939        }
4940
4941        timer = setTimeout(function () {
4942
4943          if (!MutationObserver) {
4944            //fallback for IE 9
4945            $nodes.each(function () {
4946              $(this).triggerHandler('scrollme.zf.trigger');
4947            });
4948          }
4949          //trigger all listening elements and signal a scroll event
4950          $nodes.attr('data-events', "scroll");
4951        }, debounce || 10); //default time to emit scroll event
4952      });
4953    }
4954  }
4955
4956  function mutateListener(debounce) {
4957    var $nodes = $('[data-mutate]');
4958    if ($nodes.length && MutationObserver) {
4959      //trigger all listening elements and signal a mutate event
4960      //no IE 9 or 10
4961      $nodes.each(function () {
4962        $(this).triggerHandler('mutateme.zf.trigger');
4963      });
4964    }
4965  }
4966
4967  function eventsListener() {
4968    if (!MutationObserver) {
4969      return false;
4970    }
4971    var nodes = document.querySelectorAll('[data-resize], [data-scroll], [data-mutate]');
4972
4973    //element callback
4974    var listeningElementsMutation = function (mutationRecordsList) {
4975      var $target = $(mutationRecordsList[0].target);
4976
4977      //trigger the event handler for the element depending on type
4978      switch (mutationRecordsList[0].type) {
4979
4980        case "attributes":
4981          if ($target.attr("data-events") === "scroll" && mutationRecordsList[0].attributeName === "data-events") {
4982            $target.triggerHandler('scrollme.zf.trigger', [$target, window.pageYOffset]);
4983          }
4984          if ($target.attr("data-events") === "resize" && mutationRecordsList[0].attributeName === "data-events") {
4985            $target.triggerHandler('resizeme.zf.trigger', [$target]);
4986          }
4987          if (mutationRecordsList[0].attributeName === "style") {
4988            $target.closest("[data-mutate]").attr("data-events", "mutate");
4989            $target.closest("[data-mutate]").triggerHandler('mutateme.zf.trigger', [$target.closest("[data-mutate]")]);
4990          }
4991          break;
4992
4993        case "childList":
4994          $target.closest("[data-mutate]").attr("data-events", "mutate");
4995          $target.closest("[data-mutate]").triggerHandler('mutateme.zf.trigger', [$target.closest("[data-mutate]")]);
4996          break;
4997
4998        default:
4999          return false;
5000        //nothing
5001      }
5002    };
5003
5004    if (nodes.length) {
5005      //for each element that needs to listen for resizing, scrolling, or mutation add a single observer
5006      for (var i = 0; i <= nodes.length - 1; i++) {
5007        var elementObserver = new MutationObserver(listeningElementsMutation);
5008        elementObserver.observe(nodes[i], { attributes: true, childList: true, characterData: false, subtree: true, attributeFilter: ["data-events", "style"] });
5009      }
5010    }
5011  }
5012
5013  // ------------------------------------
5014
5015  // [PH]
5016  // Foundation.CheckWatchers = checkWatchers;
5017  Foundation.IHearYou = checkListeners;
5018  // Foundation.ISeeYou = scrollListener;
5019  // Foundation.IFeelYou = closemeListener;
5020}(jQuery);
5021
5022// function domMutationObserver(debounce) {
5023//   // !!! This is coming soon and needs more work; not active  !!! //
5024//   var timer,
5025//   nodes = document.querySelectorAll('[data-mutate]');
5026//   //
5027//   if (nodes.length) {
5028//     // var MutationObserver = (function () {
5029//     //   var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
5030//     //   for (var i=0; i < prefixes.length; i++) {
5031//     //     if (prefixes[i] + 'MutationObserver' in window) {
5032//     //       return window[prefixes[i] + 'MutationObserver'];
5033//     //     }
5034//     //   }
5035//     //   return false;
5036//     // }());
5037//
5038//
5039//     //for the body, we need to listen for all changes effecting the style and class attributes
5040//     var bodyObserver = new MutationObserver(bodyMutation);
5041//     bodyObserver.observe(document.body, { attributes: true, childList: true, characterData: false, subtree:true, attributeFilter:["style", "class"]});
5042//
5043//
5044//     //body callback
5045//     function bodyMutation(mutate) {
5046//       //trigger all listening elements and signal a mutation event
5047//       if (timer) { clearTimeout(timer); }
5048//
5049//       timer = setTimeout(function() {
5050//         bodyObserver.disconnect();
5051//         $('[data-mutate]').attr('data-events',"mutate");
5052//       }, debounce || 150);
5053//     }
5054//   }
5055// }
5056//**************************************************
5057//**Work inspired by multiple jquery swipe plugins**
5058//**Done by Yohai Ararat ***************************
5059//**************************************************
5060(function ($) {
5061
5062	$.spotSwipe = {
5063		version: '1.0.0',
5064		enabled: 'ontouchstart' in document.documentElement,
5065		preventDefault: false,
5066		moveThreshold: 75,
5067		timeThreshold: 200
5068	};
5069
5070	var startPosX,
5071	    startPosY,
5072	    startTime,
5073	    elapsedTime,
5074	    isMoving = false;
5075
5076	function onTouchEnd() {
5077		//  alert(this);
5078		this.removeEventListener('touchmove', onTouchMove);
5079		this.removeEventListener('touchend', onTouchEnd);
5080		isMoving = false;
5081	}
5082
5083	function onTouchMove(e) {
5084		if ($.spotSwipe.preventDefault) {
5085			e.preventDefault();
5086		}
5087		if (isMoving) {
5088			var x = e.touches[0].pageX;
5089			var y = e.touches[0].pageY;
5090			var dx = startPosX - x;
5091			var dy = startPosY - y;
5092			var dir;
5093			elapsedTime = new Date().getTime() - startTime;
5094			if (Math.abs(dx) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
5095				dir = dx > 0 ? 'left' : 'right';
5096			}
5097			// else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
5098			//   dir = dy > 0 ? 'down' : 'up';
5099			// }
5100			if (dir) {
5101				e.preventDefault();
5102				onTouchEnd.call(this);
5103				$(this).trigger('swipe', dir).trigger('swipe' + dir);
5104			}
5105		}
5106	}
5107
5108	function onTouchStart(e) {
5109		if (e.touches.length == 1) {
5110			startPosX = e.touches[0].pageX;
5111			startPosY = e.touches[0].pageY;
5112			isMoving = true;
5113			startTime = new Date().getTime();
5114			this.addEventListener('touchmove', onTouchMove, false);
5115			this.addEventListener('touchend', onTouchEnd, false);
5116		}
5117	}
5118
5119	function init() {
5120		this.addEventListener && this.addEventListener('touchstart', onTouchStart, false);
5121	}
5122
5123	function teardown() {
5124		this.removeEventListener('touchstart', onTouchStart);
5125	}
5126
5127	$.event.special.swipe = { setup: init };
5128
5129	$.each(['left', 'up', 'down', 'right'], function () {
5130		$.event.special['swipe' + this] = { setup: function () {
5131				$(this).on('swipe', $.noop);
5132			} };
5133	});
5134})(jQuery);
5135/****************************************************
5136 * Method for adding psuedo drag events to elements *
5137 ***************************************************/
5138!function ($) {
5139	$.fn.addTouch = function () {
5140		this.each(function (i, el) {
5141			$(el).bind('touchstart touchmove touchend touchcancel', function () {
5142				//we pass the original event object because the jQuery event
5143				//object is normalized to w3c specs and does not provide the TouchList
5144				handleTouch(event);
5145			});
5146		});
5147
5148		var handleTouch = function (event) {
5149			var touches = event.changedTouches,
5150			    first = touches[0],
5151			    eventTypes = {
5152				touchstart: 'mousedown',
5153				touchmove: 'mousemove',
5154				touchend: 'mouseup'
5155			},
5156			    type = eventTypes[event.type],
5157			    simulatedEvent;
5158
5159			if ('MouseEvent' in window && typeof window.MouseEvent === 'function') {
5160				simulatedEvent = new window.MouseEvent(type, {
5161					'bubbles': true,
5162					'cancelable': true,
5163					'screenX': first.screenX,
5164					'screenY': first.screenY,
5165					'clientX': first.clientX,
5166					'clientY': first.clientY
5167				});
5168			} else {
5169				simulatedEvent = document.createEvent('MouseEvent');
5170				simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0 /*left*/, null);
5171			}
5172			first.target.dispatchEvent(simulatedEvent);
5173		};
5174	};
5175}(jQuery);
5176
5177//**********************************
5178//**From the jQuery Mobile Library**
5179//**need to recreate functionality**
5180//**and try to improve if possible**
5181//**********************************
5182
5183/* Removing the jQuery function ****
5184************************************
5185
5186(function( $, window, undefined ) {
5187
5188	var $document = $( document ),
5189		// supportTouch = $.mobile.support.touch,
5190		touchStartEvent = 'touchstart'//supportTouch ? "touchstart" : "mousedown",
5191		touchStopEvent = 'touchend'//supportTouch ? "touchend" : "mouseup",
5192		touchMoveEvent = 'touchmove'//supportTouch ? "touchmove" : "mousemove";
5193
5194	// setup new event shortcuts
5195	$.each( ( "touchstart touchmove touchend " +
5196		"swipe swipeleft swiperight" ).split( " " ), function( i, name ) {
5197
5198		$.fn[ name ] = function( fn ) {
5199			return fn ? this.bind( name, fn ) : this.trigger( name );
5200		};
5201
5202		// jQuery < 1.8
5203		if ( $.attrFn ) {
5204			$.attrFn[ name ] = true;
5205		}
5206	});
5207
5208	function triggerCustomEvent( obj, eventType, event, bubble ) {
5209		var originalType = event.type;
5210		event.type = eventType;
5211		if ( bubble ) {
5212			$.event.trigger( event, undefined, obj );
5213		} else {
5214			$.event.dispatch.call( obj, event );
5215		}
5216		event.type = originalType;
5217	}
5218
5219	// also handles taphold
5220
5221	// Also handles swipeleft, swiperight
5222	$.event.special.swipe = {
5223
5224		// More than this horizontal displacement, and we will suppress scrolling.
5225		scrollSupressionThreshold: 30,
5226
5227		// More time than this, and it isn't a swipe.
5228		durationThreshold: 1000,
5229
5230		// Swipe horizontal displacement must be more than this.
5231		horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,
5232
5233		// Swipe vertical displacement must be less than this.
5234		verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,
5235
5236		getLocation: function ( event ) {
5237			var winPageX = window.pageXOffset,
5238				winPageY = window.pageYOffset,
5239				x = event.clientX,
5240				y = event.clientY;
5241
5242			if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) ||
5243				event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) {
5244
5245				// iOS4 clientX/clientY have the value that should have been
5246				// in pageX/pageY. While pageX/page/ have the value 0
5247				x = x - winPageX;
5248				y = y - winPageY;
5249			} else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) {
5250
5251				// Some Android browsers have totally bogus values for clientX/Y
5252				// when scrolling/zooming a page. Detectable since clientX/clientY
5253				// should never be smaller than pageX/pageY minus page scroll
5254				x = event.pageX - winPageX;
5255				y = event.pageY - winPageY;
5256			}
5257
5258			return {
5259				x: x,
5260				y: y
5261			};
5262		},
5263
5264		start: function( event ) {
5265			var data = event.originalEvent.touches ?
5266					event.originalEvent.touches[ 0 ] : event,
5267				location = $.event.special.swipe.getLocation( data );
5268			return {
5269						time: ( new Date() ).getTime(),
5270						coords: [ location.x, location.y ],
5271						origin: $( event.target )
5272					};
5273		},
5274
5275		stop: function( event ) {
5276			var data = event.originalEvent.touches ?
5277					event.originalEvent.touches[ 0 ] : event,
5278				location = $.event.special.swipe.getLocation( data );
5279			return {
5280						time: ( new Date() ).getTime(),
5281						coords: [ location.x, location.y ]
5282					};
5283		},
5284
5285		handleSwipe: function( start, stop, thisObject, origTarget ) {
5286			if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
5287				Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
5288				Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
5289				var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight";
5290
5291				triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true );
5292				triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true );
5293				return true;
5294			}
5295			return false;
5296
5297		},
5298
5299		// This serves as a flag to ensure that at most one swipe event event is
5300		// in work at any given time
5301		eventInProgress: false,
5302
5303		setup: function() {
5304			var events,
5305				thisObject = this,
5306				$this = $( thisObject ),
5307				context = {};
5308
5309			// Retrieve the events data for this element and add the swipe context
5310			events = $.data( this, "mobile-events" );
5311			if ( !events ) {
5312				events = { length: 0 };
5313				$.data( this, "mobile-events", events );
5314			}
5315			events.length++;
5316			events.swipe = context;
5317
5318			context.start = function( event ) {
5319
5320				// Bail if we're already working on a swipe event
5321				if ( $.event.special.swipe.eventInProgress ) {
5322					return;
5323				}
5324				$.event.special.swipe.eventInProgress = true;
5325
5326				var stop,
5327					start = $.event.special.swipe.start( event ),
5328					origTarget = event.target,
5329					emitted = false;
5330
5331				context.move = function( event ) {
5332					if ( !start || event.isDefaultPrevented() ) {
5333						return;
5334					}
5335
5336					stop = $.event.special.swipe.stop( event );
5337					if ( !emitted ) {
5338						emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget );
5339						if ( emitted ) {
5340
5341							// Reset the context to make way for the next swipe event
5342							$.event.special.swipe.eventInProgress = false;
5343						}
5344					}
5345					// prevent scrolling
5346					if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
5347						event.preventDefault();
5348					}
5349				};
5350
5351				context.stop = function() {
5352						emitted = true;
5353
5354						// Reset the context to make way for the next swipe event
5355						$.event.special.swipe.eventInProgress = false;
5356						$document.off( touchMoveEvent, context.move );
5357						context.move = null;
5358				};
5359
5360				$document.on( touchMoveEvent, context.move )
5361					.one( touchStopEvent, context.stop );
5362			};
5363			$this.on( touchStartEvent, context.start );
5364		},
5365
5366		teardown: function() {
5367			var events, context;
5368
5369			events = $.data( this, "mobile-events" );
5370			if ( events ) {
5371				context = events.swipe;
5372				delete events.swipe;
5373				events.length--;
5374				if ( events.length === 0 ) {
5375					$.removeData( this, "mobile-events" );
5376				}
5377			}
5378
5379			if ( context ) {
5380				if ( context.start ) {
5381					$( this ).off( touchStartEvent, context.start );
5382				}
5383				if ( context.move ) {
5384					$document.off( touchMoveEvent, context.move );
5385				}
5386				if ( context.stop ) {
5387					$document.off( touchStopEvent, context.stop );
5388				}
5389			}
5390		}
5391	};
5392	$.each({
5393		swipeleft: "swipe.left",
5394		swiperight: "swipe.right"
5395	}, function( event, sourceEvent ) {
5396
5397		$.event.special[ event ] = {
5398			setup: function() {
5399				$( this ).bind( sourceEvent, $.noop );
5400			},
5401			teardown: function() {
5402				$( this ).unbind( sourceEvent );
5403			}
5404		};
5405	});
5406})( jQuery, this );
5407*/
5408'use strict';
5409
5410!function ($) {
5411
5412  var Nest = {
5413    Feather: function (menu) {
5414      var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'zf';
5415
5416      menu.attr('role', 'menubar');
5417
5418      var items = menu.find('li').attr({ 'role': 'menuitem' }),
5419          subMenuClass = 'is-' + type + '-submenu',
5420          subItemClass = subMenuClass + '-item',
5421          hasSubClass = 'is-' + type + '-submenu-parent';
5422
5423      items.each(function () {
5424        var $item = $(this),
5425            $sub = $item.children('ul');
5426
5427        if ($sub.length) {
5428          $item.addClass(hasSubClass).attr({
5429            'aria-haspopup': true,
5430            'aria-label': $item.children('a:first').text()
5431          });
5432          // Note:  Drilldowns behave differently in how they hide, and so need
5433          // additional attributes.  We should look if this possibly over-generalized
5434          // utility (Nest) is appropriate when we rework menus in 6.4
5435          if (type === 'drilldown') {
5436            $item.attr({ 'aria-expanded': false });
5437          }
5438
5439          $sub.addClass('submenu ' + subMenuClass).attr({
5440            'data-submenu': '',
5441            'role': 'menu'
5442          });
5443          if (type === 'drilldown') {
5444            $sub.attr({ 'aria-hidden': true });
5445          }
5446        }
5447
5448        if ($item.parent('[data-submenu]').length) {
5449          $item.addClass('is-submenu-item ' + subItemClass);
5450        }
5451      });
5452
5453      return;
5454    },
5455    Burn: function (menu, type) {
5456      var //items = menu.find('li'),
5457      subMenuClass = 'is-' + type + '-submenu',
5458          subItemClass = subMenuClass + '-item',
5459          hasSubClass = 'is-' + type + '-submenu-parent';
5460
5461      menu.find('>li, .menu, .menu > li').removeClass(subMenuClass + ' ' + subItemClass + ' ' + hasSubClass + ' is-submenu-item submenu is-active').removeAttr('data-submenu').css('display', '');
5462
5463      // console.log(      menu.find('.' + subMenuClass + ', .' + subItemClass + ', .has-submenu, .is-submenu-item, .submenu, [data-submenu]')
5464      //           .removeClass(subMenuClass + ' ' + subItemClass + ' has-submenu is-submenu-item submenu')
5465      //           .removeAttr('data-submenu'));
5466      // items.each(function(){
5467      //   var $item = $(this),
5468      //       $sub = $item.children('ul');
5469      //   if($item.parent('[data-submenu]').length){
5470      //     $item.removeClass('is-submenu-item ' + subItemClass);
5471      //   }
5472      //   if($sub.length){
5473      //     $item.removeClass('has-submenu');
5474      //     $sub.removeClass('submenu ' + subMenuClass).removeAttr('data-submenu');
5475      //   }
5476      // });
5477    }
5478  };
5479
5480  Foundation.Nest = Nest;
5481}(jQuery);
5482'use strict';
5483
5484var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
5485
5486function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5487
5488!function ($) {
5489
5490  /**
5491   * ResponsiveToggle module.
5492   * @module foundation.responsiveToggle
5493   * @requires foundation.util.mediaQuery
5494   */
5495
5496  var ResponsiveToggle = function () {
5497    /**
5498     * Creates a new instance of Tab Bar.
5499     * @class
5500     * @fires ResponsiveToggle#init
5501     * @param {jQuery} element - jQuery object to attach tab bar functionality to.
5502     * @param {Object} options - Overrides to the default plugin settings.
5503     */
5504    function ResponsiveToggle(element, options) {
5505      _classCallCheck(this, ResponsiveToggle);
5506
5507      this.$element = $(element);
5508      this.options = $.extend({}, ResponsiveToggle.defaults, this.$element.data(), options);
5509
5510      this._init();
5511      this._events();
5512
5513      Foundation.registerPlugin(this, 'ResponsiveToggle');
5514    }
5515
5516    /**
5517     * Initializes the tab bar by finding the target element, toggling element, and running update().
5518     * @function
5519     * @private
5520     */
5521
5522
5523    _createClass(ResponsiveToggle, [{
5524      key: '_init',
5525      value: function _init() {
5526        var targetID = this.$element.data('responsive-toggle');
5527        if (!targetID) {
5528          console.error('Your tab bar needs an ID of a Menu as the value of data-tab-bar.');
5529        }
5530
5531        this.$targetMenu = $('#' + targetID);
5532        this.$toggler = this.$element.find('[data-toggle]').filter(function () {
5533          var target = $(this).data('toggle');
5534          return target === targetID || target === "";
5535        });
5536        this.options = $.extend({}, this.options, this.$targetMenu.data());
5537
5538        // If they were set, parse the animation classes
5539        if (this.options.animate) {
5540          var input = this.options.animate.split(' ');
5541
5542          this.animationIn = input[0];
5543          this.animationOut = input[1] || null;
5544        }
5545
5546        this._update();
5547      }
5548
5549      /**
5550       * Adds necessary event handlers for the tab bar to work.
5551       * @function
5552       * @private
5553       */
5554
5555    }, {
5556      key: '_events',
5557      value: function _events() {
5558        var _this = this;
5559
5560        this._updateMqHandler = this._update.bind(this);
5561
5562        $(window).on('changed.zf.mediaquery', this._updateMqHandler);
5563
5564        this.$toggler.on('click.zf.responsiveToggle', this.toggleMenu.bind(this));
5565      }
5566
5567      /**
5568       * Checks the current media query to determine if the tab bar should be visible or hidden.
5569       * @function
5570       * @private
5571       */
5572
5573    }, {
5574      key: '_update',
5575      value: function _update() {
5576        // Mobile
5577        if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
5578          this.$element.show();
5579          this.$targetMenu.hide();
5580        }
5581
5582        // Desktop
5583        else {
5584            this.$element.hide();
5585            this.$targetMenu.show();
5586          }
5587      }
5588
5589      /**
5590       * Toggles the element attached to the tab bar. The toggle only happens if the screen is small enough to allow it.
5591       * @function
5592       * @fires ResponsiveToggle#toggled
5593       */
5594
5595    }, {
5596      key: 'toggleMenu',
5597      value: function toggleMenu() {
5598        var _this2 = this;
5599
5600        if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
5601          /**
5602           * Fires when the element attached to the tab bar toggles.
5603           * @event ResponsiveToggle#toggled
5604           */
5605          if (this.options.animate) {
5606            if (this.$targetMenu.is(':hidden')) {
5607              Foundation.Motion.animateIn(this.$targetMenu, this.animationIn, function () {
5608                _this2.$element.trigger('toggled.zf.responsiveToggle');
5609                _this2.$targetMenu.find('[data-mutate]').triggerHandler('mutateme.zf.trigger');
5610              });
5611            } else {
5612              Foundation.Motion.animateOut(this.$targetMenu, this.animationOut, function () {
5613                _this2.$element.trigger('toggled.zf.responsiveToggle');
5614              });
5615            }
5616          } else {
5617            this.$targetMenu.toggle(0);
5618            this.$targetMenu.find('[data-mutate]').trigger('mutateme.zf.trigger');
5619            this.$element.trigger('toggled.zf.responsiveToggle');
5620          }
5621        }
5622      }
5623    }, {
5624      key: 'destroy',
5625      value: function destroy() {
5626        this.$element.off('.zf.responsiveToggle');
5627        this.$toggler.off('.zf.responsiveToggle');
5628
5629        $(window).off('changed.zf.mediaquery', this._updateMqHandler);
5630
5631        Foundation.unregisterPlugin(this);
5632      }
5633    }]);
5634
5635    return ResponsiveToggle;
5636  }();
5637
5638  ResponsiveToggle.defaults = {
5639    /**
5640     * The breakpoint after which the menu is always shown, and the tab bar is hidden.
5641     * @option
5642     * @type {string}
5643     * @default 'medium'
5644     */
5645    hideFor: 'medium',
5646
5647    /**
5648     * To decide if the toggle should be animated or not.
5649     * @option
5650     * @type {boolean}
5651     * @default false
5652     */
5653    animate: false
5654  };
5655
5656  // Window exports
5657  Foundation.plugin(ResponsiveToggle, 'ResponsiveToggle');
5658}(jQuery);
5659'use strict';
5660
5661var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
5662
5663function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5664
5665!function ($) {
5666
5667  /**
5668   * Equalizer module.
5669   * @module foundation.equalizer
5670   * @requires foundation.util.mediaQuery
5671   * @requires foundation.util.timerAndImageLoader if equalizer contains images
5672   */
5673
5674  var Equalizer = function () {
5675    /**
5676     * Creates a new instance of Equalizer.
5677     * @class
5678     * @fires Equalizer#init
5679     * @param {Object} element - jQuery object to add the trigger to.
5680     * @param {Object} options - Overrides to the default plugin settings.
5681     */
5682    function Equalizer(element, options) {
5683      _classCallCheck(this, Equalizer);
5684
5685      this.$element = element;
5686      this.options = $.extend({}, Equalizer.defaults, this.$element.data(), options);
5687
5688      this._init();
5689
5690      Foundation.registerPlugin(this, 'Equalizer');
5691    }
5692
5693    /**
5694     * Initializes the Equalizer plugin and calls functions to get equalizer functioning on load.
5695     * @private
5696     */
5697
5698
5699    _createClass(Equalizer, [{
5700      key: '_init',
5701      value: function _init() {
5702        var eqId = this.$element.attr('data-equalizer') || '';
5703        var $watched = this.$element.find('[data-equalizer-watch="' + eqId + '"]');
5704
5705        this.$watched = $watched.length ? $watched : this.$element.find('[data-equalizer-watch]');
5706        this.$element.attr('data-resize', eqId || Foundation.GetYoDigits(6, 'eq'));
5707        this.$element.attr('data-mutate', eqId || Foundation.GetYoDigits(6, 'eq'));
5708
5709        this.hasNested = this.$element.find('[data-equalizer]').length > 0;
5710        this.isNested = this.$element.parentsUntil(document.body, '[data-equalizer]').length > 0;
5711        this.isOn = false;
5712        this._bindHandler = {
5713          onResizeMeBound: this._onResizeMe.bind(this),
5714          onPostEqualizedBound: this._onPostEqualized.bind(this)
5715        };
5716
5717        var imgs = this.$element.find('img');
5718        var tooSmall;
5719        if (this.options.equalizeOn) {
5720          tooSmall = this._checkMQ();
5721          $(window).on('changed.zf.mediaquery', this._checkMQ.bind(this));
5722        } else {
5723          this._events();
5724        }
5725        if (tooSmall !== undefined && tooSmall === false || tooSmall === undefined) {
5726          if (imgs.length) {
5727            Foundation.onImagesLoaded(imgs, this._reflow.bind(this));
5728          } else {
5729            this._reflow();
5730          }
5731        }
5732      }
5733
5734      /**
5735       * Removes event listeners if the breakpoint is too small.
5736       * @private
5737       */
5738
5739    }, {
5740      key: '_pauseEvents',
5741      value: function _pauseEvents() {
5742        this.isOn = false;
5743        this.$element.off({
5744          '.zf.equalizer': this._bindHandler.onPostEqualizedBound,
5745          'resizeme.zf.trigger': this._bindHandler.onResizeMeBound,
5746          'mutateme.zf.trigger': this._bindHandler.onResizeMeBound
5747        });
5748      }
5749
5750      /**
5751       * function to handle $elements resizeme.zf.trigger, with bound this on _bindHandler.onResizeMeBound
5752       * @private
5753       */
5754
5755    }, {
5756      key: '_onResizeMe',
5757      value: function _onResizeMe(e) {
5758        this._reflow();
5759      }
5760
5761      /**
5762       * function to handle $elements postequalized.zf.equalizer, with bound this on _bindHandler.onPostEqualizedBound
5763       * @private
5764       */
5765
5766    }, {
5767      key: '_onPostEqualized',
5768      value: function _onPostEqualized(e) {
5769        if (e.target !== this.$element[0]) {
5770          this._reflow();
5771        }
5772      }
5773
5774      /**
5775       * Initializes events for Equalizer.
5776       * @private
5777       */
5778
5779    }, {
5780      key: '_events',
5781      value: function _events() {
5782        var _this = this;
5783        this._pauseEvents();
5784        if (this.hasNested) {
5785          this.$element.on('postequalized.zf.equalizer', this._bindHandler.onPostEqualizedBound);
5786        } else {
5787          this.$element.on('resizeme.zf.trigger', this._bindHandler.onResizeMeBound);
5788          this.$element.on('mutateme.zf.trigger', this._bindHandler.onResizeMeBound);
5789        }
5790        this.isOn = true;
5791      }
5792
5793      /**
5794       * Checks the current breakpoint to the minimum required size.
5795       * @private
5796       */
5797
5798    }, {
5799      key: '_checkMQ',
5800      value: function _checkMQ() {
5801        var tooSmall = !Foundation.MediaQuery.is(this.options.equalizeOn);
5802        if (tooSmall) {
5803          if (this.isOn) {
5804            this._pauseEvents();
5805            this.$watched.css('height', 'auto');
5806          }
5807        } else {
5808          if (!this.isOn) {
5809            this._events();
5810          }
5811        }
5812        return tooSmall;
5813      }
5814
5815      /**
5816       * A noop version for the plugin
5817       * @private
5818       */
5819
5820    }, {
5821      key: '_killswitch',
5822      value: function _killswitch() {
5823        return;
5824      }
5825
5826      /**
5827       * Calls necessary functions to update Equalizer upon DOM change
5828       * @private
5829       */
5830
5831    }, {
5832      key: '_reflow',
5833      value: function _reflow() {
5834        if (!this.options.equalizeOnStack) {
5835          if (this._isStacked()) {
5836            this.$watched.css('height', 'auto');
5837            return false;
5838          }
5839        }
5840        if (this.options.equalizeByRow) {
5841          this.getHeightsByRow(this.applyHeightByRow.bind(this));
5842        } else {
5843          this.getHeights(this.applyHeight.bind(this));
5844        }
5845      }
5846
5847      /**
5848       * Manually determines if the first 2 elements are *NOT* stacked.
5849       * @private
5850       */
5851
5852    }, {
5853      key: '_isStacked',
5854      value: function _isStacked() {
5855        if (!this.$watched[0] || !this.$watched[1]) {
5856          return true;
5857        }
5858        return this.$watched[0].getBoundingClientRect().top !== this.$watched[1].getBoundingClientRect().top;
5859      }
5860
5861      /**
5862       * Finds the outer heights of children contained within an Equalizer parent and returns them in an array
5863       * @param {Function} cb - A non-optional callback to return the heights array to.
5864       * @returns {Array} heights - An array of heights of children within Equalizer container
5865       */
5866
5867    }, {
vendor: 4,117 bytes, lines 5868-5979
5868      key: 'getHeights',
5869      value: function getHeights(cb) {
5870        var heights = [];
5871        for (var i = 0, len = this.$watched.length; i < len; i++) {
5872          this.$watched[i].style.height = 'auto';
5873          heights.push(this.$watched[i].offsetHeight);
5874        }
5875        cb(heights);
5876      }
5877
5878      /**
5879       * Finds the outer heights of children contained within an Equalizer parent and returns them in an array
5880       * @param {Function} cb - A non-optional callback to return the heights array to.
5881       * @returns {Array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child
5882       */
5883
5884    }, {
5885      key: 'getHeightsByRow',
5886      value: function getHeightsByRow(cb) {
5887        var lastElTopOffset = this.$watched.length ? this.$watched.first().offset().top : 0,
5888            groups = [],
5889            group = 0;
5890        //group by Row
5891        groups[group] = [];
5892        for (var i = 0, len = this.$watched.length; i < len; i++) {
5893          this.$watched[i].style.height = 'auto';
5894          //maybe could use this.$watched[i].offsetTop
5895          var elOffsetTop = $(this.$watched[i]).offset().top;
5896          if (elOffsetTop != lastElTopOffset) {
5897            group++;
5898            groups[group] = [];
5899            lastElTopOffset = elOffsetTop;
5900          }
5901          groups[group].push([this.$watched[i], this.$watched[i].offsetHeight]);
5902        }
5903
5904        for (var j = 0, ln = groups.length; j < ln; j++) {
5905          var heights = $(groups[j]).map(function () {
5906            return this[1];
5907          }).get();
5908          var max = Math.max.apply(null, heights);
5909          groups[j].push(max);
5910        }
5911        cb(groups);
5912      }
5913
5914      /**
5915       * Changes the CSS height property of each child in an Equalizer parent to match the tallest
5916       * @param {array} heights - An array of heights of children within Equalizer container
5917       * @fires Equalizer#preequalized
5918       * @fires Equalizer#postequalized
5919       */
5920
5921    }, {
5922      key: 'applyHeight',
5923      value: function applyHeight(heights) {
5924        var max = Math.max.apply(null, heights);
5925        /**
5926         * Fires before the heights are applied
5927         * @event Equalizer#preequalized
5928         */
5929        this.$element.trigger('preequalized.zf.equalizer');
5930
5931        this.$watched.css('height', max);
5932
5933        /**
5934         * Fires when the heights have been applied
5935         * @event Equalizer#postequalized
5936         */
5937        this.$element.trigger('postequalized.zf.equalizer');
5938      }
5939
5940      /**
5941       * Changes the CSS height property of each child in an Equalizer parent to match the tallest by row
5942       * @param {array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child
5943       * @fires Equalizer#preequalized
5944       * @fires Equalizer#preequalizedrow
5945       * @fires Equalizer#postequalizedrow
5946       * @fires Equalizer#postequalized
5947       */
5948
5949    }, {
5950      key: 'applyHeightByRow',
5951      value: function applyHeightByRow(groups) {
5952        /**
5953         * Fires before the heights are applied
5954         */
5955        this.$element.trigger('preequalized.zf.equalizer');
5956        for (var i = 0, len = groups.length; i < len; i++) {
5957          var groupsILength = groups[i].length,
5958              max = groups[i][groupsILength - 1];
5959          if (groupsILength <= 2) {
5960            $(groups[i][0][0]).css({ 'height': 'auto' });
5961            continue;
5962          }
5963          /**
5964            * Fires before the heights per row are applied
5965            * @event Equalizer#preequalizedrow
5966            */
5967          this.$element.trigger('preequalizedrow.zf.equalizer');
5968          for (var j = 0, lenJ = groupsILength - 1; j < lenJ; j++) {
5969            $(groups[i][j][0]).css({ 'height': max });
5970          }
5971          /**
5972            * Fires when the heights per row have been applied
5973            * @event Equalizer#postequalizedrow
5974            */
5975          this.$element.trigger('postequalizedrow.zf.equalizer');
5976        }
5977        /**
5978         * Fires when the heights have been applied
5979         */
5980        this.$element.trigger('postequalized.zf.equalizer');
5981      }
5982
5983      /**
5984       * Destroys an instance of Equalizer.
5985       * @function
5986       */
5987
5988    }, {
5989      key: 'destroy',
5990      value: function destroy() {
5991        this._pauseEvents();
5992        this.$watched.css('height', 'auto');
5993
5994        Foundation.unregisterPlugin(this);
5995      }
5996    }]);
5997
5998    return Equalizer;
5999  }();
6000
6001  /**
6002   * Default settings for plugin
6003   */
6004
6005
6006  Equalizer.defaults = {
6007    /**
6008     * Enable height equalization when stacked on smaller screens.
6009     * @option
6010     * @type {boolean}
6011     * @default false
6012     */
6013    equalizeOnStack: false,
6014    /**
6015     * Enable height equalization row by row.
6016     * @option
6017     * @type {boolean}
6018     * @default false
6019     */
6020    equalizeByRow: false,
6021    /**
6022     * String representing the minimum breakpoint size the plugin should equalize heights on.
6023     * @option
6024     * @type {string}
6025     * @default ''
6026     */
6027    equalizeOn: ''
6028  };
6029
6030  // Window exports
6031  Foundation.plugin(Equalizer, 'Equalizer');
6032}(jQuery);
6033'use strict';
6034
6035var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
6036
6037function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6038
6039!function ($) {
6040
6041  /**
6042   * Toggler module.
6043   * @module foundation.toggler
6044   * @requires foundation.util.motion
6045   * @requires foundation.util.triggers
6046   */
6047
6048  var Toggler = function () {
6049    /**
6050     * Creates a new instance of Toggler.
6051     * @class
6052     * @fires Toggler#init
6053     * @param {Object} element - jQuery object to add the trigger to.
6054     * @param {Object} options - Overrides to the default plugin settings.
6055     */
6056    function Toggler(element, options) {
6057      _classCallCheck(this, Toggler);
6058
6059      this.$element = element;
6060      this.options = $.extend({}, Toggler.defaults, element.data(), options);
6061      this.className = '';
6062
6063      this._init();
6064      this._events();
6065
6066      Foundation.registerPlugin(this, 'Toggler');
6067    }
6068
6069    /**
6070     * Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate.
6071     * @function
6072     * @private
6073     */
6074
6075
6076    _createClass(Toggler, [{
6077      key: '_init',
6078      value: function _init() {
6079        var input;
6080        // Parse animation classes if they were set
6081        if (this.options.animate) {
6082          input = this.options.animate.split(' ');
6083
6084          this.animationIn = input[0];
6085          this.animationOut = input[1] || null;
6086        }
6087        // Otherwise, parse toggle class
6088        else {
6089            input = this.$element.data('toggler');
6090            // Allow for a . at the beginning of the string
6091            this.className = input[0] === '.' ? input.slice(1) : input;
6092          }
6093
6094        // Add ARIA attributes to triggers
6095        var id = this.$element[0].id;
6096        $('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-controls', id);
6097        // If the target is hidden, add aria-hidden
6098        this.$element.attr('aria-expanded', this.$element.is(':hidden') ? false : true);
6099      }
6100
6101      /**
6102       * Initializes events for the toggle trigger.
6103       * @function
6104       * @private
6105       */
6106
6107    }, {
6108      key: '_events',
6109      value: function _events() {
6110        this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this));
6111      }
6112
6113      /**
6114       * Toggles the target class on the target element. An event is fired from the original trigger depending on if the resultant state was "on" or "off".
6115       * @function
6116       * @fires Toggler#on
6117       * @fires Toggler#off
6118       */
6119
6120    }, {
6121      key: 'toggle',
6122      value: function toggle() {
6123        this[this.options.animate ? '_toggleAnimate' : '_toggleClass']();
6124      }
6125    }, {
6126      key: '_toggleClass',
6127      value: function _toggleClass() {
6128        this.$element.toggleClass(this.className);
6129
6130        var isOn = this.$element.hasClass(this.className);
6131        if (isOn) {
6132          /**
6133           * Fires if the target element has the class after a toggle.
6134           * @event Toggler#on
6135           */
6136          this.$element.trigger('on.zf.toggler');
6137        } else {
6138          /**
6139           * Fires if the target element does not have the class after a toggle.
6140           * @event Toggler#off
6141           */
6142          this.$element.trigger('off.zf.toggler');
6143        }
6144
6145        this._updateARIA(isOn);
6146        this.$element.find('[data-mutate]').trigger('mutateme.zf.trigger');
6147      }
6148    }, {
6149      key: '_toggleAnimate',
6150      value: function _toggleAnimate() {
6151        var _this = this;
6152
6153        if (this.$element.is(':hidden')) {
6154          Foundation.Motion.animateIn(this.$element, this.animationIn, function () {
6155            _this._updateARIA(true);
6156            this.trigger('on.zf.toggler');
6157            this.find('[data-mutate]').trigger('mutateme.zf.trigger');
6158          });
6159        } else {
6160          Foundation.Motion.animateOut(this.$element, this.animationOut, function () {
6161            _this._updateARIA(false);
6162            this.trigger('off.zf.toggler');
6163            this.find('[data-mutate]').trigger('mutateme.zf.trigger');
6164          });
6165        }
6166      }
6167    }, {
6168      key: '_updateARIA',
6169      value: function _updateARIA(isOn) {
6170        this.$element.attr('aria-expanded', isOn ? true : false);
6171      }
6172
6173      /**
6174       * Destroys the instance of Toggler on the element.
6175       * @function
6176       */
6177
6178    }, {
6179      key: 'destroy',
6180      value: function destroy() {
6181        this.$element.off('.zf.toggler');
6182        Foundation.unregisterPlugin(this);
6183      }
6184    }]);
6185
6186    return Toggler;
6187  }();
6188
6189  Toggler.defaults = {
6190    /**
6191     * Tells the plugin if the element should animated when toggled.
6192     * @option
6193     * @type {boolean}
6194     * @default false
6195     */
6196    animate: false
6197  };
6198
6199  // Window exports
6200  Foundation.plugin(Toggler, 'Toggler');
6201}(jQuery);
6202/*
6203 * Lazy Load - jQuery plugin for lazy loading images
6204 *
6205 * Copyright (c) 2007-2013 Mika Tuupola
6206 *
6207 * Licensed under the MIT license:
6208 *   http://www.opensource.org/licenses/mit-license.php
6209 *
6210 * Project home:
6211 *   http://www.appelsiini.net/projects/lazyload
6212 *
6213 * Version:  1.9.1
6214 *
6215 */
6216
6217(function($, window, document, undefined) {
6218    var $window = $(window);
6219
6220    $.fn.lazyload = function(options) {
6221        var elements = this;
6222        var $container;
6223        var settings = {
6224            threshold       : 0,
6225            failure_limit   : 0,
6226            event           : "scroll",
6227            effect          : "show",
6228            container       : window,
6229            data_attribute  : "original",
6230            skip_invisible  : true,
6231            appear          : null,
6232            load            : null,
6233            placeholder     : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
6234        };
6235
6236        function update() {
6237            var counter = 0;
6238
6239            elements.each(function() {
6240                var $this = $(this);
6241                if (settings.skip_invisible && !$this.is(":visible")) {
6242                    return;
6243                }
6244                if ($.abovethetop(this, settings) ||
6245                    $.leftofbegin(this, settings)) {
6246                        /* Nothing. */
6247                } else if (!$.belowthefold(this, settings) &&
6248                    !$.rightoffold(this, settings)) {
6249                        $this.trigger("appear");
6250                        /* if we found an image we'll load, reset the counter */
6251                        counter = 0;
6252                } else {
6253                    if (++counter > settings.failure_limit) {
6254                        return false;
vendor: 4,377 bytes, lines 6255-6372
6255                    }
6256                }
6257            });
6258
6259        }
6260
6261        if(options) {
6262            /* Maintain BC for a couple of versions. */
6263            if (undefined !== options.failurelimit) {
6264                options.failure_limit = options.failurelimit;
6265                delete options.failurelimit;
6266            }
6267            if (undefined !== options.effectspeed) {
6268                options.effect_speed = options.effectspeed;
6269                delete options.effectspeed;
6270            }
6271
6272            $.extend(settings, options);
6273        }
6274
6275        /* Cache container as jQuery as object. */
6276        $container = (settings.container === undefined ||
6277                      settings.container === window) ? $window : $(settings.container);
6278
6279        /* Fire one scroll event per scroll. Not one scroll event per image. */
6280        if (0 === settings.event.indexOf("scroll")) {
6281            $container.bind(settings.event, function() {
6282                return update();
6283            });
6284        }
6285
6286        this.each(function() {
6287            var self = this;
6288            var $self = $(self);
6289
6290            self.loaded = false;
6291
6292            /* If no src attribute given use data:uri. */
6293            if ($self.attr("src") === undefined || $self.attr("src") === false) {
6294                if ($self.is("img")) {
6295                    $self.attr("src", settings.placeholder);
6296                }
6297            }
6298
6299            /* When appear is triggered load original image. */
6300            $self.one("appear", function() {
6301                if (!this.loaded) {
6302                    if (settings.appear) {
6303                        var elements_left = elements.length;
6304                        settings.appear.call(self, elements_left, settings);
6305                    }
6306                    $("<img />")
6307                        .bind("load", function() {
6308
6309                            var original = $self.attr("data-" + settings.data_attribute);
6310                            $self.hide();
6311                            if ($self.is("img")) {
6312                                $self.attr("src", original);
6313                            } else {
6314                                $self.css("background-image", "url('" + original + "')");
6315                            }
6316                            $self[settings.effect](settings.effect_speed);
6317
6318                            self.loaded = true;
6319
6320                            /* Remove image from array so it is not looped next time. */
6321                            var temp = $.grep(elements, function(element) {
6322                                return !element.loaded;
6323                            });
6324                            elements = $(temp);
6325
6326                            if (settings.load) {
6327                                var elements_left = elements.length;
6328                                settings.load.call(self, elements_left, settings);
6329                            }
6330                        })
6331                        .attr("src", $self.attr("data-" + settings.data_attribute));
6332                }
6333            });
6334
6335            /* When wanted event is triggered load original image */
6336            /* by triggering appear.                              */
6337            if (0 !== settings.event.indexOf("scroll")) {
6338                $self.bind(settings.event, function() {
6339                    if (!self.loaded) {
6340                        $self.trigger("appear");
6341                    }
6342                });
6343            }
6344        });
6345
6346        /* Check if something appears when window is resized. */
6347        $window.bind("resize", function() {
6348            update();
6349        });
6350
6351        /* With IOS5 force loading images when navigating with back button. */
6352        /* Non optimal workaround. */
6353        if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) {
6354            $window.bind("pageshow", function(event) {
6355                if (event.originalEvent && event.originalEvent.persisted) {
6356                    elements.each(function() {
6357                        $(this).trigger("appear");
6358                    });
6359                }
6360            });
6361        }
6362
6363        /* Force initial check if images should appear. */
6364        $(document).ready(function() {
6365            update();
6366        });
6367
6368        return this;
6369    };
6370
6371    /* Convenience methods in jQuery namespace.           */
6372    /* Use as  $.belowthefold(element, {threshold : 100, container : window}
6372) */
6373
6374    $.belowthefold = function(element, settings) {
6375        var fold;
6376
6377        if (settings.container === undefined || settings.container === window) {
6378            fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
6379        } else {
6380            fold = $(settings.container).offset().top + $(settings.container).height();
6381        }
6382
6383        return fold <= $(element).offset().top - settings.threshold;
6384    };
6385
6386    $.rightoffold = function(element, settings) {
6387        var fold;
6388
6389        if (settings.container === undefined || settings.container === window) {
6390            fold = $window.width() + $window.scrollLeft();
6391        } else {
6392            fold = $(settings.container).offset().left + $(settings.container).width();
6393        }
6394
6395        return fold <= $(element).offset().left - settings.threshold;
6396    };
6397
6398    $.abovethetop = function(element, settings) {
6399        var fold;
6400
6401        if (settings.container === undefined || settings.container === window) {
6402            fold = $window.scrollTop();
6403        } else {
6404            fold = $(settings.container).offset().top;
6405        }
6406
6407        return fold >= $(element).offset().top + settings.threshold  + $(element).height();
6408    };
6409
6410    $.leftofbegin = function(element, settings) {
6411        var fold;
6412
6413        if (settings.container === undefined || settings.container === window) {
6414            fold = $window.scrollLeft();
6415        } else {
6416            fold = $(settings.container).offset().left;
6417        }
6418
6419        return fold >= $(element).offset().left + settings.threshold + $(element).width();
6420    };
6421
6422    $.inviewport = function(element, settings) {
6423         return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
6424                !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
6425     };
6426
6427    /* Custom selectors for your convenience.   */
6428    /* Use as $("img:below-the-fold").something() or */
6429    /* $("img").filter(":below-the-fold").something() which is faster */
6430
6431    $.extend($.expr[":"], {
6432        "below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
6433        "above-the-top"  : function(a) { return !$.belowthefold(a, {threshold : 0}); },
6434        "right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
6435        "left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
6436        "in-viewport"    : function(a) { return $.inviewport(a, {threshold : 0}); },
6437        /* Maintain BC for couple of versions. */
6438        "above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
6439        "right-of-fold"  : function(a) { return $.rightoffold(a, {threshold : 0}); },
6440        "left-of-fold"   : function(a) { return !$.rightoffold(a, {threshold : 0}); }
6441    });
6442
6443})(jQuery, window, document);
6444
6445/*! jQuery UI - v1.8.21 - 2012-06-05
6446* https://github.com/jquery/jquery-ui
6447* Includes: jquery.ui.core.js
6448* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
6449(function(a,b){function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;return!b.href||!g||f.nodeName.toLowerCase()!=="map"?!1:(h=a("img[usemap=#"+g+"]")[0],!!h&&d(h))}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(a.ui.version)return;a.extend(a.ui,{version:"1.8.21",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;return a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0),/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){return a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)}),c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){return c===b?g["inner"+d].call(this):this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){return typeof b!="number"?g["outer"+d].call(this,b):this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!d||!a.element[0].parentNode)return;for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;return b[d]>
64490?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
6450* https://github.com/jquery/jquery-ui
6451* Includes: jquery.ui.widget.js
6452* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
6453(function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){return c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}}),d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;return e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e,f&&e.charAt(0)==="_"?h:(f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b)return h=f,!1}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))}),h)}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}return this._setOptions(e),this},_setOptions:function(b){var c=this;return a.each(b,function(a,b){c._setOption(a,b)}),this},_setOption:function(a,b){return this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);return this.element.trigger(c,d),!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
6454* https://github.com/jquery/jquery-ui
6455* Includes: jquery.ui.mouse.js
6456* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
6457(function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent"))return a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(b){if(c)return;this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted)return b.preventDefault(),!0}return!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0,!0},_mouseMove:function(b){return!a.browser.msie||document.documentMode>=9||!!b.button?this._mouseStarted?(this._mouseDrag(b),b.preventDefault()):(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b)),!this._mouseStarted):this._mouseUp(b)},_mouseUp:function(b){return a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b)),!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
6458* https://github.com/jquery/jquery-ui
6459* Includes: jquery.ui.position.js
6460* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
6461(function(a,b){a.ui=a.ui||{};
6461var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;return i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1],this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]===e)return;var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0},top:function(b,c){if(c.at[1]===e)return;var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];return!c||!c.ownerDocument?null:b?a.isFunction(b)?this.each(function(c){a(this).offset(b.call(this,c,a(this).offset()))}):this.each(function(){a.offset.setOffset(this,b)}):h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);;
6462
6463var BW = BW || {};
6464
6465/*
6466  Handels image changes and modal open in gallery DCE
6467 */
6468BW.DceGallery = (function(){
6469
6470  'use strict';
6471
6472  var defaultConf = {
6473    galleryWrapperClass: 'bw-dce-gallery',
6474    switchTriggerSelector: '.bw-dce-gallery__switch',
6475    contentReplacements: [
6476      {
6477        galleryElementSelector: '.gallery__image',
6478        galleryElementHTML: true,
6479        galleryElementCSS: false,
6480        galleryElementAttr: false,
6481        triggerElementSelectorr: '.gallery__preview',
6482        triggerElementAttribute: 'data-image',
6483      }
6484    ]
6485  };
6486
6487  // placeholder for cached DOM elements
6488  var CONF = {};
6489  var DOM = {};
6490
6491  function cacheDOM(){
6492    DOM.$galleries = $(CONF.galleryWrapperClass);
6493    $(DOM.$galleries).each(function(i, gallery){
6494      DOM.$galleries[i].$switchTrigger = $(gallery).find(CONF.switchTrigger);
6495      DOM.$galleries[i].replacements = [];
6496      CONF.contentReplacements.forEach(function(e){
6497        DOM.$galleries[i].replacements
6498      });
6499    });
6500  }
6501
6502  function initEvents(){
6503
6504  }
6505
6506  /**
6507   * inits the BW.Paginate module
6508   *
6509   * @param {object} conf optional configuration override
6510   * @return {void}
6511   */
6512  function init(conf){
6513
6514    // @TODO: populate conf
6515    CONF = conf ? conf : defaultConf;
6516
6517    cacheDOM();
6518    initEvents();
6519  }
6520
6521  return {
6522    init: init
6523  }
6524
6525}());
6526
6527var BW = BW || {};
6528
6529/*
6530  Loads and displays dynamic content in Foundation Reveal Modal
6531  Requires:
6532    - Foundation Reveal (https://foundation.zurb.com/sites/docs/reveal.html)
6533 */
6534BW.Modal = (function(){
6535
6536  'use strict';
6537
6538  // e.g. <a href="http://example.com/data.json" class="bw-modal" data-bw-modal-json="{data: }"
6539  var defaultConf = {
6540    dataType: 'text',
6541    triggerSelector: '.bw-modal',
6542    modalSelector: '#bwModal',
6543    modalContentWrapperSelector: '#bwModalContent',
6544
6545    urlAttr: 'href',
6546    saveAttr: 'data-bw-modal-json',
6547  };
6548
6549  // placeholder for cached DOM elements
6550  var CONF = {};
6551  var DOM = {};
6552
6553  /**
6554   * Creates a new Foundation Reveal at the end of body
6555   *
6556   * @return {void}
6557   */
6558  function createModal(){
6559    DOM.$modal = $('<div>', {
6560      id: CONF.modalSelector,
6561      class: 'reveal reveal--bw-modal',
6562      dataReveal: ''
6563    }).append('<div>', {
6564      id: CONF.modalContentWrapperSelector
6565    }).appendTo('body');
6566  }
6567
6568  /**
6569   * Save DOM elements to variables
6570   *
6571   * @return {void}
6572   */
6573  function cacheDOM(){
6574    DOM.$modal = $(CONF.modalSelector);
6575    if(!DOM.$modal) createModal();
6576    DOM.$modalContent = DOM.$modal.find(CONF.modalContentWrapperSelector);
6577    DOM.$trigger = $(CONF.triggerSelector);
6578  }
6579
6580  /**
6581   * Add click event to all trigger elements
6582   *
6583   * @return {void}
6584   */
6585  function initListener(){
6586    DOM.$trigger.each(function(i, el){
6587      $(el).on('click', function(event){
6588        event.preventDefault();
6589        onTriggerClick(el);
6590      });
6591    });
6592  }
6593
6594  /**
6595   * Click event function
6596   *
6597   * @param {JQuery} el element that holds data url and saved attr
6598   * @return {void}
6599   */
6600  function onTriggerClick(el){
6601    var savedData = $(el).attr(CONF.saveAttr);
6602    if(savedData){
6603      openModal(savedData);
6604    } else {
6605      loadAndSaveElementData(el, openModal);
6606    }
6607    if($(el).attr('id')) {
6608      location.hash = $(el).attr('id');
6609    }
6610  }
6611
6612  /**
6613   * Ajax load of element data + cache in data saveAttr
6614   *
6615   * @param {JQuery} el element that holds data url
6616   * @param {Function} cb callback function that gets executed after success
6617   * @return {void}
6618   */
6619  function loadAndSaveElementData(el, cb){
6620    $.ajax({
6621      dataType: CONF.dataType,
6622      url: $(el).attr(CONF.urlAttr),
6623      success: function(data){
6624        $(el).attr(CONF.saveAttr, data);
6625        cb(data);
6626      }
6627    });
6628  }
6629
6630  /**
6631   * inserts html into modal and opens it
6632   *
6633   * @param {string} html content to show
6634   * @return {void}
6635   */
6636  function openModal(html){
6637    $(CONF.modalContentWrapperSelector).html(html);
6638    $(CONF.modalSelector).foundation('open');
6639  }
6640
6641  /**
6642   * inits the BW.Modal module
6643   *
6644   * @param {object} conf optional configuration override
6645   * @return {void}
6646   */
6647  function init(conf){
6648
6649    // @TODO: populate conf
6650    CONF = conf ? conf : defaultConf;
6651
6652    cacheDOM();
6653    initListener();
6654  }
6655
6656  return {
6657    init: init
6658  }
6659
6660}());
6661
6662var BW = BW || {};
6663
6664/*
6665  Creates dynamic paginate navigation
6666 */
6667BW.Paginate = (function(CONF){
6668
6669  'use strict';
6670
6671  var defaultConf = {
6672    itemsPerPage: 30,
6673    paginationSelector: '.bw-pagination',
6674    itemWrapperSelector: '.bw-pagination__items',
6675    itemSelectorClass: 'bw-pagination__items__item',
6676    itemHiddenClass: 'bw-pagination__items__item--hidden',
6677    itemIgnoreSelector: '',
6678    buttonClass: 'button',
6679    buttonPrevText: 'previous',
6680    buttonNextText: 'next',
6681    buttonActiveClass: 'active',
6682    buttonDisabledClass: 'disabled',
6683    scrollTopSelector: false
6684  };
6685
6686  // placeholder for cached DOM elements
6687  var DOM = {};
6688  // @TODO populate configuration
6689  var CONF = CONF ? CONF : defaultConf;
6690
6691  /**
6692   * Save DOM elements to variables
6693   *
6694   * @return {void}
6695   */
6696  function cacheDOM(){
6697    DOM.$pagers = $(CONF.paginationSelector);
6698    DOM.$itemWrappers = $(CONF.itemWrapperSelector);
6699  }
6700
6701  /**
6702   * Function called by click on pager button elements
6703   *
6704   * @param {integer} offset index of the clicked button element (0 - pagescount+2)
6705   * @param {JQuery} pager pager elment
6706   * @return {void}
6707   */
6708  function onButtonClick(offset, pager){
6709
6710    // abbort if first or last page and prev/1 or next/n is clicked
6711    if((offset <= 1 && pager.currentOffset==1) || (offset >= pager.pageCount && pager.currentOffset==pager.pageCount)) return false;
6712
6713    // navigate
6714    pager.navigate(offset);
6715
6716    // scroll to top
6717    if(CONF.scrollTopSelector) $('html,body').animate({scrollTop: $(CONF.scrollTopSelector).offset().top});
6718  }
6719
6720  /**
6721   * returns the button text for pager buttons (useful for language overrides)
6722   *
6723   * @param {integer} i index of the button element
6724   * @param {integer} count count of button elements
6725   * @return {string}
6726   */
6727  function getButtonText(i, count){
6728    if(i == 0) return CONF.buttonPrevText;
6729    if(i == (count+1)) return CONF.buttonNextText;
6730    return i;
6731  }
6732
6733  /**
6734   * Add functionts to given pager
6735   *
6736   * @param {integer} i offset of the pager in DOM.$pagers
6737   * @return {void}
6738   */
6739  function extendPagerFunctions(i){
6740
6741    // clear pager content
6742    $(DOM.$pagers[i]).html();
6743
6744    // cache elements
6745    DOM.$pagers[i].$itemWrapper = DOM.$itemWrappers[i];
6746    DOM.$pagers[i].$buttonGroup = $('<ul>', {class:'pagination button-group'}).appendTo(DOM.$pagers[i]);
6747
6748    // clear all navigation buttons inside
6749    DOM.$pagers[i].removeButtons = function(){
6750      $(this.$buttonGroup).html('');
6751    }
6752
6753    DOM.$pagers[i].currentOffset = 1;
6754
6755    DOM.$pagers[i].createButtons = function() {
6756
6757      // Wir speichern den 'this'-Kontext (das Pager-Objekt) sofort in einer Variable.
6758      // Das löst alle Kontext-Probleme.
6759      var pager = this;
6760
6761      $(pager.$buttonGroup).empty();
6762
6763      for (var j = 0; j < pager.pageCount + 2; j++) {
6764
6765        var listItem = $('<li>', {
6766          class: CONF.buttonClass
6767        });
6768
6769        var linkElement = $('<a />', {
6770          class: 'page-link',
6771          href: '#',
6772          'aria-label': 'gehe zu Seite ' + getButtonText(j, pager.pageCount),
6773          text: getButtonText(j, pager.pageCount),
6774          'data-page': j,
6775
6776          click: function(event) {
6777            event.preventDefault();
6778            var pageIndex = $(this).data('page');
6779
6780            // Ruft die Kernfunktion mit den korrekten Argumenten auf.
6781            // 'pager' ist hier die Variable, die wir am Anfang der Funktion gespeichert haben.
6782            onButtonClick(pageIndex, pager, event);
6783          }
6784        });
6785
6786        listItem.append(linkElement);
6787        $(pager.$buttonGroup).append(listItem);
6788      }
6789    };
6790
6791    // sets active and disabled classes for pager buttons
6792    DOM.$pagers[i].setButtonClasses = function(offset){
6793      // remove active & disabled classes
6794      $('li', this.$buttonGroup).removeClass(CONF.buttonActiveClass).removeClass(CONF.buttonDisabledClass);
6795
6796      // add active class
6797      $('li:nth-child('+(offset+1)+')', this.$buttonGroup).addClass(CONF.buttonActiveClass);
6798
6799      // add disabled class
6800      if(offset==1) $('li:first-child', this.$buttonGroup).addClass(CONF.buttonDisabledClass);
6801      if(offset==this.pageCount) $('li:last-child', this.$buttonGroup).addClass(CONF.buttonDisabledClass);
6802    }
6803
6804    // starts the filtering of pager items
6805    DOM.$pagers[i].navigate = function(offset){
6806
6807      // set offset (from clicked prev/next buttons)
6808      if(offset==0) offset = this.currentOffset==1 ? 1 : this.currentOffset-1;
6809      if(offset==this.pageCount+1) offset = this.currentOffset==this.pageCount ? this.pageCount : this.currentOffset+1;
6810
6811      this.setButtonClasses(offset);
6812
6813      // hide items from other pages
6814      $(this.$items).addClass(CONF.itemHiddenClass);
6815      for(var j=CONF.itemsPerPage*(offset-1); j<(CONF.itemsPerPage*offset); j++){
6816        $(this.$items[j]).removeClass(CONF.itemHiddenClass);
6817      }
6818
6819      this.currentOffset = offset;
6820    }
6821
6822    /**
6823     * setup pager buttons
6824     *
6825     * @param {integer} i offset of the pager in DOM.$pagers
6826     * @return {void}
6827     */
6828    DOM.$pagers[i].refresh = function(){
6829      this.$items = $('.'+CONF.itemSelectorClass, this.$itemWrapper).not(CONF.itemIgnoreSelector);
6830      this.pageCount = Math.ceil(this.$items.length / CONF.itemsPerPage);
6831      this.removeButtons();
6832
6833      // cancel if only one page
6834      if(this.pageCount < 2) return false;
6835
6836      this.createButtons();
6837    }
6838
6839  }
6840
6841  /**
6842   * triggers refresh of a single pager
6843   *
6844   * @param {integer} index global offset of pages in DOM.$pagers
6845   * @return {void}
6846   */
6847  function refreshPager(index){
6848    if (!DOM.$pagers || !DOM.$pagers[index]) return;
6849    DOM.$pagers[index].refresh();
6850    DOM.$pagers[index].navigate(1);
6851  }
6852
6853  /**
6854   * [initAllPagers description]
6855   *
6856   * @return {void}
6857   */
6858  function initAllPagers(){
6859    DOM.$pagers.each(function(i,e){
6860      // add methods to every pager
6861      extendPagerFunctions(i);
6862
6863      // refresh every pager and navigate to page 1
6864      DOM.$pagers[i].refresh();
6865      DOM.$pagers[i].navigate(1);
6866    });
6867  }
6868
6869  /**
6870   * inits the BW.Paginate module
6871   *
6872   * @param {object} conf optional configuration override
6873   * @return {void}
6874   */
6875  function init(){
6876
6877    cacheDOM();
6878    initAllPagers();
6879  }
6880
6881  return {
6882    CONF: CONF,
6883    init: init,
6884    refreshPager: refreshPager
6885  }
6886
6887});
6888
6889var BW = BW || {};
6890
6891/*
6892  Creates dynamic paginate navigation
6893 */
6894BW.Filter = (function(CONF){
6895
6896  'use strict';
6897
6898  var defaultConf = {
6899    searchContentSelector: '.bw-filter__item',
6900    filtersWrapperSelector: '.bw-filter',
6901    itemWrapperSelector: '.bw-pagination__items',
6902    itemSelectorClass: 'bw-pagination__items__item',
6903    textFilterSelector: '.bw-filter__text',
6904    selectFilterSelector: '.bw-filter__select',
6905    textFilterHiddenClass: 'bw-filter__item--hiddenByText',
6906    selectFilterHiddenClass: 'bw-filter__item--hiddenBySelect',
6907    callback: null,
6908    BwPaginateArray: []
6909  };
6910
6911  // placeholder for cached DOM elements
6912  var DOM = {};
6913  // @TODO: populate conf
6914  var CONF = CONF ? CONF : defaultConf;
6915
6916  function cacheDOM(){
6917    DOM.$filters = $(CONF.filtersWrapperSelector);
6918    DOM.$filters.each(function(i, e){
6919      DOM.$filters[i].$textFilter = $(this).find(CONF.textFilterSelector);
6920      DOM.$filters[i].$selectFilter = $(this).find(CONF.selectFilterSelector);
6921    });
6922    DOM.$itemWrappers = $(CONF.itemWrapperSelector);
6923    DOM.$itemWrappers.each(function(i, e){
6924      DOM.$itemWrappers[i].$items = $(this).find('.'+CONF.itemSelectorClass);
6925    });
6926  }
6927
6928  function refreshPagers(offset){
6929    for (var i = 0; i < CONF.BwPaginateArray.length; i++){
6930      CONF.BwPaginateArray[i].refreshPager(offset);
6931    }
6932  }
6933
6934  function hasPager(){
6935    return CONF.BwPaginateArray && CONF.BwPaginateArray.length;
6936  }
6937
6938  function getHiddenClassesFromPagers(){
6939    var classNames = '';
6940    for (var i = 0; i < CONF.BwPaginateArray.length; i++) {
6941      classNames += CONF.BwPaginateArray[i].itemHiddenClass + ' ';
6942    }
6943    return classNames;
6944  }
6945
6946  function onTextFilterKeyUp(offset){
6947    textFilter(offset);
6948    if (CONF.BwPaginateArray.length) refreshPagers(offset);
6949    if(CONF.callback) CONF.callback();
6950  }
6951
6952  function onSelectFilterChange(offset){
6953    selectFilter(offset);
6954    if (hasPager()) refreshPagers(offset);
6955    if(CONF.callback) CONF.callback();
6956  }
6957
6958  function textFilter(offset){
6959    DOM.$filters[offset].$textFilter.each(function(i, filterEl){
6960      var textboxVal = $(filterEl).val().toLowerCase();
6961
6962      $(DOM.$itemWrappers[i].$items).each(function(j, itemEl) {
6963        // to slow for people list
6964        //  var listVal = $(itemEl).find($(CONF.searchContentSelector)).text().toLowerCase().replace("fachbereich", "");
6965        var listVal = $(CONF.searchContentSelector, itemEl).text().toLowerCase().replace("fachbereich", "");
6966        if(listVal.indexOf(textboxVal) >= 0) {
6967              $(itemEl).removeClass(CONF.textFilterHiddenClass);
6968              if(hasPager()) $(itemEl).removeClass(getHiddenClassesFromPagers());
6969          } else {
6970              $(itemEl).addClass(CONF.textFilterHiddenClass);
6971          }
6972      });
6973    });
6974
6975  }
6976
6977  function selectFilter(offset){
6978    $(DOM.$itemWrappers[offset].$items).addClass(CONF.selectFilterHiddenClass);
6979    if(hasPager()) $(DOM.$itemWrappers[offset].$items).removeClass(getHiddenClassesFromPagers());
6980
6981    var filterSelector = '';
6982    $(DOM.$filters[offset].$selectFilter).each(function(i, e){
6983      var field = $(e).attr('data-field');
6984      var value = $('option:selected', e).attr('value');
6985      if(value) filterSelector += '[data-'+field+'*="uid-'+value+'-end"]';
6986    });
6987    $(DOM.$itemWrappers[offset]).find('.'+CONF.itemSelectorClass + filterSelector).removeClass(CONF.selectFilterHiddenClass);
6988  }
6989
6990  function initEvents(){
6991    DOM.$filters.each(function(i, filterEl){
6992      // text filter
6993      DOM.$filters[i].$textFilter.each(function(j, textEl){
6994        $(textEl).keyup(onTextFilterKeyUp.bind(null, i));
6995      });
6996
6997      // select filter
6998      DOM.$filters[i].$selectFilter.each(function(j, selectEl){
6999        $(selectEl).on('change', onSelectFilterChange.bind(null, i));
7000      });
7001    });
7002  }
7003
7004  /**
7005   * inits the CONF.BwFilter module
7006   *
7007   * @param {object} conf optional configuration override
7008   * @return {void}
7009   */
7010  function init(conf){
7011
7012    cacheDOM();
7013    initEvents();
7014  }
7015
7016  return {
7017    init: init
7018  }
7019
7020});
7021
7022$(document).ready(function () {
7023  var curLang = $('html').attr('lang');
7024  $("select").each(function () {
7025    $(this).val($(this).find('option[selected]').val());
7026  });
7027
7028  // hide #back-top first
7029  $("#back-top").hide();
7030
7031  // fade in #back-top
7032  $(function () {
7033    $(window).scroll(function () {
7034      if ($(this).scrollTop() > 100) {
7035        $(window).trigger('load.zf.sticky');
7036        $('#back-top').fadeIn();
7037      } else {
7038        $('#back-top').fadeOut();
7039      }
7040    });
7041
7042    // scroll body to 0px on click
7043    $('#back-top a').click(function () {
7044      $('body,html').animate({
7045        scrollTop: 0
7046      }, 800);
7047      return false;
7048    });
7049  });
7050
7051  //$(window).trigger('load');
7052  $(window).trigger('load.zf.sticky');
7053});
7054
7055$(function() {
7056  var curLang = $('html').attr('lang');
7057  $(document).foundation();
7058
7059  // tt_content Element "Verkürzt"
7060  $('.ce-textpic--short__toggle').on('click', function (e) {
7061    e.preventDefault();
7062    $(this).parent().find('.ce-textpic--short').toggleClass('ce-textpic--short-hidden');
7063  });
7064
7065  // Tabs Modul
7066  $('ul[data-tabs] a').on('click', function (e) {
7067    e.preventDefault();
7068    var ul = $(this).parent().parent();
7069    $('a', ul).removeClass('active');
7070    $(this).addClass('active');
7071    var panel = $('#' + $(ul).attr('data-tabs-target'));
7072    $('div[data-panel]', panel).removeClass('active');
7073    $('div[data-panel="' + $(this).attr('href').substr(1) + '"]', panel).addClass('active');
7074  });
7075
7076  // Touch fix for main menu
7077  /*$('#mainmenu > li > a').click(function (e) {
7078    if (whatInput.ask() === 'touch') {
7079      e.preventDefault();
7080    }
7081  });*/
7082
7083  // Keyboard accessibility: open submenu on focus (desktop only)
7084  $('#mainmenu > li > a').each(function () {
7085    var $link = $(this);
7086    var $li = $link.parent();
7087    var $submenu = $li.find('> ul');
7088
7089    if (!$submenu.length) return;
7090
7091    $link.attr('aria-haspopup', 'true').attr('aria-expanded', 'false');
7092
7093    $link.on('focus', function () {
7094      if (Foundation.MediaQuery.atLeast('medium')) {
7095        $link.attr('aria-expanded', 'true');
7096        $li.addClass('is-keyboard-focused');
7097      }
7098    });
7099
7100    $li.on('focusout', function (e) {
7101      if (!$li[0].contains(e.relatedTarget)) {
7102        $link.attr('aria-expanded', 'false');
7103        $li.removeClass('is-keyboard-focused');
7104      }
7105    });
7106
7107    $li.on('keydown', function (e) {
7108      if (e.key === 'Escape') {
7109        $link.attr('aria-expanded', 'false');
7110        $li.removeClass('is-keyboard-focused');
7111        $link.focus();
7112      }
7113    });
7114  });
7115
7116  // search reveal button
7117  $('.openSearchModal').on('click', function (e) {
7118    e.preventDefault();
7119    $('#searchModal')
7120      .foundation('open')
7121      .find('input[type="text"]').focus();
7122  });
7123
7124  function isInViewport(element, toleranceTop, toleranceBottom) {
7125    if (toleranceTop === undefined) {
7126      toleranceTop = 0;
7127    }
7128    if (toleranceBottom === undefined) {
7129      toleranceBottom = 0;
7130    }
7131    var rect = element.getBoundingClientRect();
7132    var html = document.documentElement;
7133    return (
7134      rect.top >= (0 - toleranceTop) &&
7135      rect.left >= 0 &&
7136      rect.bottom <= ((window.innerHeight + toleranceBottom) || (html.clientHeight + toleranceBottom)) &&
7137      rect.right <= (window.innerWidth || html.clientWidth)
7138    );
7139  }
7140
7141  var ScrollLock = false;
7142  var runOnScroll = function (evt) {
7143    if (ScrollLock) {
7144      return;
7145    }
7146    ScrollLock = true;
7147
7148    checkViewportForNumberElements();
7149
7150    ScrollLock = false;
7151  };
7152
7153  function checkViewportForNumberElements() {
7154    numbersElements.each(function () {
7155      if (isInViewport(this, 0, 300)) {
7156        $(this).removeClass('numbers--not-in-viewport');
7157      } else {
7158        $(this).addClass('numbers--not-in-viewport');
7159      }
7160    });
7161  }
7162
7163  // numbers animation
7164  var numbersElements = $('section.numbers');
7165  if (numbersElements.length) {
7166    checkViewportForNumberElements();
7167    window.addEventListener("scroll", runOnScroll);
7168  }
7169
7170  $('#topbar')
7171    .on('sticky.zf.stuckto:top', function () {
7172      $('body').addClass('topbar-is-stuck');
7173    })
7174    .on('sticky.zf.unstuckfrom:top', function () {
7175      $('body').removeClass('topbar-is-stuck');
7176    });
7177  $('#topbarMobile')
7178      .on('sticky.zf.stuckto:top', function () {
7179        $('body').addClass('topbar-is-stuck');
7180      })
7181      .on('sticky.zf.unstuckfrom:top', function () {
7182        $('body').removeClass('topbar-is-stuck');
7183      });
7184
7185  // allgemeines js fuer modal
7186  var modalConf = {
7187    dataType: 'text',
7188    triggerSelector: '.hsa__item',
7189    modalSelector: '#hsaModal',
7190    modalContentWrapperSelector: '.hsaModal__wrapper',
7191
7192    urlAttr: 'data-hsa-detail',
7193    saveAttr: 'data-hsa-json'
7194  };
7195  BW.Modal.init(modalConf);
7196
7197  BW.DceGallery.init({
7198    galleryWrapperClass: 'bw-dce-gallery',
7199    switchTriggerSelector: '.bw-dce-gallery__switch',
7200    contentReplacements: [
7201      {
7202        galleryElementSelector: '.gallery__image',
7203        galleryElementHTML: false,
7204        galleryElementCSS: 'background-image',
7205        galleryElementAttr: false,
7206        triggerElementSelectorr: '.gallery__preview',
7207        triggerElementAttribute: 'data-image'
7208      },
7209      {
7210        galleryElementSelector: '.gallery__image',
7211        galleryElementHTML: false,
7212        galleryElementCSS: false,
7213        galleryElementAttr: 'data-video',
7214        triggerElementSelectorr: '.gallery__preview',
7215        triggerElementAttribute: 'data-video'
7216      },
7217      {
7218        galleryElementSelector: '.gallery__image a',
7219        galleryElementHTML: false,
7220        galleryElementCSS: false,
7221        galleryElementAttr: 'data-video',
7222        triggerElementSelectorr: '.gallery__preview',
7223        triggerElementAttribute: 'data-video'
7224      },
7225      {
7226        galleryElementSelector: '.gallery__header1',
7227        galleryElementHTML: true,
7228        galleryElementCSS: false,
7229        galleryElementAttr: false,
7230        triggerElementSelectorr: '.gallery__preview',
7231        triggerElementAttribute: 'data-gallery__header1'
7232      },
7233      {
7234        galleryElementSelector: '.gallery__header2',
7235        galleryElementHTML: true,
7236        galleryElementCSS: false,
7237        galleryElementAttr: false,
7238        triggerElementSelectorr: '.gallery__preview',
7239        triggerElementAttribute: 'data-gallery__header2'
7240      },
7241      {
7242        galleryElementSelector: '.gallery__header3',
7243        galleryElementHTML: true,
7244        galleryElementCSS: false,
7245        galleryElementAttr: false,
7246        triggerElementSelectorr: '.gallery__preview',
7247        triggerElementAttribute: 'data-gallery__header3'
7248      }
7249    ]
7250  });
7251
7252  // gallery dce
7253  var _this = this;
7254
7255  $('section.gallery').each(function () {
7256    var galleryNmb = $(this).attr('data-gallery-uid');
7257    var gallery = $('section.gallery[data-gallery-uid="'+ galleryNmb +'"]');
7258    gallery.find('.gallery__nav a').on('click', function (e) {
7259      e.preventDefault();
7260      // change active status
7261      gallery.find('.gallery__nav a').removeClass('active');
7262      $(this).addClass('active');
7263
7264      // change large image content
7265      gallery.find('.gallery__image')
7266        .attr('style', 'background-image:url(' + gallery.find('a.active .gallery__preview').attr('data-image') + ')')
7267        .attr('data-video', $('.gallery__preview', this).attr('data-video'))
7268        .find('a').attr('data-gallery', 'c'+ galleryNmb +'gallery'+$(this).parent().index())
7269        .find('.gallery__header1')
7270        .html($('.gallery__preview', this).attr('data-gallery__header1'))
7271        .next().html($('.gallery__preview', this).attr('data-gallery__header2'))
7272        .next().html($('.gallery__preview', this).attr('data-gallery__header3'));
7273    });
7274
7275    gallery.find('.gallery__image a').on('click', function (e) {
7276      e.preventDefault();
7277      $('#' + $(this).attr('data-gallery')).foundation('open');
7278    });
7279
7280    function reAddVideoSrc(arr) {
7281      video = arr[0];
7282      videoSRC = arr[1];
7283      if(videoSRC) $(video).attr('src', videoSRC);
7284    }
7285
7286    // on lightbox close
7287    $(window).on('closed.zf.reveal', function (e) {
7288      var video = e.target;
7289      video = $(video).find('iframe');
7290
7291      if(!video.length) return;
7292      var videoSRC = $(video).attr('src');
7293
7294      $(video).attr('src', '');
7295      setTimeout(reAddVideoSrc.bind(null, [video, videoSRC]), 100);
7296    });
7297
7298    // überprüfe alle slider auf videos
7299    $('.orbit.orbit--textmedia').each(function (i, e) {
7300      if ($(e).find('iframe').length) {
7301        $(e).addClass('contains-video');
7302        if ($(e).find('.orbit-slide.is-active iframe').length) {
7303          $(e).attr('data-active-video', '0');
7304        }
7305      }
7306    });
7307
7308    // bei slider change
7309    $(window).on('slidechange.zf.orbit', function (e){
7310      // exit if orbit slider has no video
7311      if(!$(e.target).hasClass('contains-video')) return;
7312
7313      // kill video if slide exits from active video
7314      if ($(e.target)[0].hasAttribute('data-active-video')) {
7315        var video = $(e.target).find('li[data-slide="' + $(e.target).attr('data-active-video') + '"] iframe');
7316        var videoSRC = $(video).attr('src');
7317        $(video).attr('src', '');
7318        setTimeout(function(){ $(video).attr('src', videoSRC); }, 100);
7319      }
7320
7321      // falls die nächste (aktuelle) slide ein video enthält
7322      if ($(e.target).find('li.is-active iframe').length) {
7323        var slideId = $(e.target).find('li.is-active iframe').closest('li').attr('data-sli
7323de');
7324        $(e.target).attr('data-active-video', slideId);
7325      } else {
7326        $(e.target).removeAttr('data-active-video');
7327      }
7328    });
7329  });
7330
7331  switch (curLang) {
7332    case 'de':
7333      // start pagination plugin
7334      var bwPaginateDefault = BW.Paginate({
7335        itemsPerPage: 30,
7336        paginationSelector: '.hsa__pagination',
7337        itemWrapperSelector: '.searchresults',
7338        itemSelectorClass: 'list__item',
7339        itemHiddenClass: 'list__item--hiddenByPagination',
7340        itemIgnoreSelector: '.list__item--hiddenByFilter,.list__item--hiddenBySearch',
7341        buttonClass: 'button third',
7342        buttonPrevText: 'zurück',
7343        buttonNextText: 'vor',
7344        buttonActiveClass: 'active',
7345        buttonDisabledClass: 'disabled',
7346        scrollTopSelector: 'h1'
7347      });
7348      bwPaginateDefault.init();
7349
7350      // galerie CE
7351      var bwPaginateImageGallery = BW.Paginate({
7352        itemsPerPage: 25,
7353        paginationSelector: '.hsa__pagination-gallery',
7354        itemWrapperSelector: '.searchresults-gallery',
7355        itemSelectorClass: 'list__item',
7356        itemHiddenClass: 'list__item--hiddenByPagination',
7357        itemIgnoreSelector: '.list__item--hiddenByFilter,.list__item--hiddenBySearch',
7358        buttonClass: 'button third',
7359        buttonPrevText: 'zurück',
7360        buttonNextText: 'vor',
7361        buttonActiveClass: 'active',
7362        buttonDisabledClass: 'disabled',
7363        scrollTopSelector: '.searchresults-gallery'
7364      });
7365      bwPaginateImageGallery.init();
7366
7367      // cal listview
7368      var bwPaginateCal = BW.Paginate({
7369        itemsPerPage: 9,
7370        paginationSelector: '.hsa__pagination-cal',
7371        itemWrapperSelector: '.searchresults',
7372        itemSelectorClass: 'list__item',
7373        itemHiddenClass: 'list__item--hiddenByPagination',
7374        itemIgnoreSelector: '.list__item--hiddenByFilter,.list__item--hiddenBySearch',
7375        buttonClass: 'button third',
7376        buttonPrevText: 'zurück',
7377        buttonNextText: 'vor',
7378        buttonActiveClass: 'active',
7379        buttonDisabledClass: 'disabled',
7380        scrollTopSelector: '.tx-cal-controller'
7381      });
7382      bwPaginateCal.init();
7383      break;
7384    default:
7385      // start pagination plugin
7386      var bwPaginateDefault = BW.Paginate({
7387        itemsPerPage: 30,
7388        paginationSelector: '.hsa__pagination',
7389        itemWrapperSelector: '.searchresults',
7390        itemSelectorClass: 'list__item',
7391        itemHiddenClass: 'list__item--hiddenByPagination',
7392        itemIgnoreSelector: '.list__item--hiddenByFilter,.list__item--hiddenBySearch',
7393        buttonClass: 'button third',
7394        buttonPrevText: 'previous',
7395        buttonNextText: 'next',
7396        buttonActiveClass: 'active',
7397        buttonDisabledClass: 'disabled',
7398        scrollTopSelector: 'h1'
7399      });
7400      bwPaginateDefault.init();
7401
7402      // galerie CE
7403      var bwPaginateImageGallery = BW.Paginate({
7404        itemsPerPage: 25,
7405        paginationSelector: '.hsa__pagination-gallery',
7406        itemWrapperSelector: '.searchresults-gallery',
7407        itemSelectorClass: 'list__item',
7408        itemHiddenClass: 'list__item--hiddenByPagination',
7409        itemIgnoreSelector: '.list__item--hiddenByFilter,.list__item--hiddenBySearch',
7410        buttonClass: 'button third',
7411        buttonPrevText: 'previous',
7412        buttonNextText: 'next',
7413        buttonActiveClass: 'active',
7414        buttonDisabledClass: 'disabled',
7415        scrollTopSelector: '.searchresults-gallery'
7416      });
7417      bwPaginateImageGallery.init();
7418
7419      // cal listview
7420      var bwPaginateCal = BW.Paginate({
7421        itemsPerPage: 9,
7422        paginationSelector: '.hsa__pagination-cal',
7423        itemWrapperSelector: '.searchresults',
7424        itemSelectorClass: 'list__item',
7425        itemHiddenClass: 'list__item--hiddenByPagination',
7426        itemIgnoreSelector: '.list__item--hiddenByFilter,.list__item--hiddenBySearch',
7427        buttonClass: 'button third',
7428        buttonPrevText: 'previous',
7429        buttonNextText: 'next',
7430        buttonActiveClass: 'active',
7431        buttonDisabledClass: 'disabled',
7432        scrollTopSelector: '.tx-cal-controller'
7433      });
7434      bwPaginateCal.init();
7435  }
7436
7437
7438  // start filter plugin
7439  var bwFilterDefault = BW.Filter({
7440    searchContentSelector: '.searchcontent',
7441    filtersWrapperSelector: '.hsa__filter',
7442    itemWrapperSelector: '.searchresults',
7443    itemSelectorClass: 'list__item',
7444    textFilterSelector: '#filter',
7445    selectFilterSelector: 'select',
7446    textFilterHiddenClass: 'list__item--hiddenBySearch',
7447    selectFilterHiddenClass: 'list__item--hiddenByFilter',
7448    callback: function () {
7449      $('.lazyimg').lazyload({
7450        effect : "fadeIn",
7451        effect_speed: 500,
7452        load: function (elements_left, settings){
7453        }
7454      });
7455    },
7456    BwPaginateArray: [bwPaginateDefault, bwPaginateCal]
7457  });
7458  bwFilterDefault.init();
7459
7460  // restart Orbit in revealPopUp, für cal, showroom, news usw. (EVI)
7461  $(window).on('open.zf.reveal', function (e) {
7462    $('.orbit').foundation();
7463    $('#content').addClass("hide-for-print");
7464    $('footer').addClass("hide-for-print");
7465    //$('#content').fadeOut();
7466    //$('footer').fadeOut();
7467
7468    $('.accordion').foundation();
7469  });
7470
7471  // fuer print um content unter dem popup nicht zu drucken
7472  $(window).on('closed.zf.reveal', function (e) {
7473    $('#content').removeClass("hide-for-print");
7474    $('footer').removeClass("hide-for-print");
7475    //$('#content').fadeIn();
7476    //$('footer').fadeIn();
7477
7478    $('section.gallery').each(function () {
7479      var galleryNmb = $(this).attr('data-gallery-uid');
7480      var gallery = $('section.gallery[data-gallery-uid="' + galleryNmb + '"]');
7481      gallery.find('.gallery__image').attr('style', 'background-image:url(' + gallery.find('a.active .gallery__preview').attr('data-image') + ')');
7482    });
7483  });
7484
7485  // lazy loading for Images (EVI)
7486  $('.lazyimg').lazyload({
7487    effect : "fadeIn",
7488    effect_speed: 500,
7489    load: function(elements_left, settings){
7490    }
7491  });
7492
7493  // equalizer in tabs bugfix
7494  $(".tabcontent .tabs").on("change.zf.tabs", function (e) {
7495    var newId = $(e.target).find('li.tabs-title.is-active a').attr('aria-controls');
7496    var currentScrollTop = document.documentElement.scrollTop;
7497    window.location.hash = newId;
7498    window.scrollTo(0, currentScrollTop);
7499    $('html,body').animate({scrollTop: $(e.target).offset().top - 100}, 'slow');
7500    if ($('[data-equalizer]').length) {
7501      Foundation.reInit('equalizer');
7502    }
7503    if ($('[data-orbit]').length) {
7504      Foundation.reInit('orbit');
7505    }
7506  });
7507  $("#studiengang-tabs").on("change.zf.tabs", function (e) {
7508    var newId = $(e.target).find('li.tabs-title.is-active a').attr('aria-controls');
7509    window.location.hash = newId;
7510    window.scrollTo(0, 0);
7511    if ($('[data-equalizer]').length) {
7512      Foundation.reInit('equalizer');
7513    }
7514    if ($('[data-orbit]').length) {
7515      Foundation.reInit('orbit');
7516    }
7517  });
7518
7519  if (window.location.hash) {
7520    var f6dl_url = window.location.hash;
7521    var f6dl_hash = f6dl_url.substring(f6dl_url.indexOf("#") + 1);
7522    if($('#' + f6dl_hash).length) {
7523      var f6dl_ulid = 'tabs-title';
7524      $('.' + f6dl_ulid).find('a').each(function (e) {
7525        var f6dl_href = $(this).attr('href');
7526        if (f6dl_href.substring(f6dl_href.indexOf("#") + 1) == f6dl_hash) {
7527          // Click the link to activate the tab
7528          $(this).click();
7529        }
7530      });
7531      // open modal with anchor in uri
7532      var f6dl_ulid = 'list__item';
7533      $('.' + f6dl_ulid).find('.hsa__item').each(function (e) {
7534        var f6dl_id = $(this).attr('id');
7535        if (f6dl_id == f6dl_hash) {
7536          $(this).click();
7537        }
7538      });
7539    }
7540  }
7541  // https://varvy.com/pagespeed/defer-videos.html
7542  $(window).on('open.zf.reveal', function (e) {
7543    $('.lazyimg').lazyload();
7544    var vidDefer = document.getElementsByTagName('iframe');
7545    for (var i=0; i<vidDefer.length; i++) {
7546      if(vidDefer[i].getAttribute('data-src')) {
7547        vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
7548      }
7549    }
7550  });
7551
7552});
7553
7554/*neu um den orbit slider auf der startseite vom alten foundation zu lösen*/
7555
7556document.addEventListener('DOMContentLoaded', () => {
7557    const sliderRoot = document.querySelector('#hero .custom-hero-slider');
7558    if (!sliderRoot) return;
7559
7560    const slides = sliderRoot.querySelectorAll('.custom-slider-item');
7561    const dots = sliderRoot.querySelectorAll('[data-custom-dot]');
7562    const prevBtn = sliderRoot.querySelector('.hero__arrow--prev');
7563    const nextBtn = sliderRoot.querySelector('.hero__arrow--next');
7564
7565    if (slides.length === 0) return;
7566
7567    const intervalTime = parseInt(sliderRoot.getAttribute('data-custom-timer'), 10) || 8000;
7568    let currentIndex = 0;
7569    let sliderInterval = null;
7570
7571    // Weist den Slides automatisch die Indizes passend zu den Fluid-Buttons zu
7572    slides.forEach((slide, i) => {
7573        slide.setAttribute('data-custom-slide', i);
7574    });
7575
7576    function showSlide(index) {
7577        if (index >= slides.length) currentIndex = 0;
7578        else if (index < 0) currentIndex = slides.length - 1;
7579        else currentIndex = index;
7580
7581        // Slides toggeln
7582        slides.forEach((slide, i) => {
7583            if (i === currentIndex) {
7584                slide.classList.add('is-active');
7585                slide.setAttribute('aria-live', 'polite');
7586            } else {
7587                slide.classList.remove('is-active');
7588                slide.removeAttribute('aria-live');
7589            }
7590        });
7591
7592        // Fluid-Dots toggeln
7593        dots.forEach((dot, i) => {
7594            if (i === currentIndex) {
7595                dot.classList.add('is-active');
7596            } else {
7597                dot.classList.remove('is-active');
7598            }
7599        });
7600    }
7601
7602    function nextSlide() { showSlide(currentIndex + 1); }
7603    function prevSlide() { showSlide(currentIndex - 1); }
7604
7605    function startAutoplay() {
7606        stopAutoplay();
7607        sliderInterval = setInterval(nextSlide, intervalTime);
7608    }
7609
7610    function stopAutoplay() {
7611        if (sliderInterval) clearInterval(sliderInterval);
7612    }
7613
7614    // Event-Listener für Pfeile
7615    if (nextBtn) {
7616        nextBtn.addEventListener('click', (e) => {
7617            e.preventDefault(); nextSlide(); startAutoplay();
7618        });
7619    }
7620
7621    if (prevBtn) {
7622        prevBtn.addEventListener('click', (e) => {
7623            e.preventDefault(); prevSlide(); startAutoplay();
7624        });
7625    }
7626
7627    // Event-Listener für deine Fluid-Buttons
7628    dots.forEach(dot => {
7629        dot.addEventListener('click', (e) => {
7630            e.preventDefault();
7631            const targetIndex = parseInt(e.target.getAttribute('data-custom-dot'), 10);
7632            showSlide(targetIndex);
7633            startAutoplay();
7634        });
7635    });
7636
7637    // Hover-Pause & Tastatur
7638    sliderRoot.addEventListener('mouseenter', stopAutoplay);
7639    sliderRoot.addEventListener('mouseleave', startAutoplay);
7640
7641    sliderRoot.addEventListener('keydown', (e) => {
7642        if (e.key === 'ArrowRight') { nextSlide(); startAutoplay(); }
7643        if (e.key === 'ArrowLeft') { prevSlide(); startAutoplay(); }
7644    });
7645
7646    // Initialer Start (Zustand 0)
7647    showSlide(currentIndex);
7648    startAutoplay();
7649});

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.