PageSourceSearch

https://www.teesporthealth.co.uk/wp-content/themes/itchyrobot_parent/js/vendor/foundation.js

js teesporthealth.co.uk collected 2026-09-28 12:42:17 UTC 294,691 bytes, 9,069 lines download raw bytes

1!function ($) {
2
3  "use strict";
4
5  var FOUNDATION_VERSION = '6.2.2';
6
7  // Global Foundation object
8  // This is attached to the window, or used as a module for AMD/Browserify
9  var Foundation = {
10    version: FOUNDATION_VERSION,
11
12    /**
13     * Stores initialized plugins.
14     */
15    _plugins: {},
16
17    /**
18     * Stores generated unique ids for plugin instances
19     */
20    _uuids: [],
21
22    /**
23     * Returns a boolean for RTL support
24     */
25    rtl: function () {
26      return $('html').attr('dir') === 'rtl';
27    },
28    /**
29     * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing.
30     * @param {Object} plugin - The constructor of the plugin.
31     */
32    plugin: function (plugin, name) {
33      // Object key to use when adding to global Foundation object
34      // Examples: Foundation.Reveal, Foundation.OffCanvas
35      var className = name || functionName(plugin);
36      // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin
37      // Examples: data-reveal, data-off-canvas
38      var attrName = hyphenate(className);
39
40      // Add to the Foundation object and the plugins list (for reflowing)
41      this._plugins[attrName] = this[className] = plugin;
42    },
43    /**
44     * @function
45     * Populates the _uuids array with pointers to each individual plugin instance.
46     * Adds the `zfPlugin` data-attribute to programmatically created plugins to allow use of $(selector).foundation(method) calls.
47     * Also fires the initialization event for each plugin, consolidating repetitive code.
48     * @param {Object} plugin - an instance of a plugin, usually `this` in context.
49     * @param {String} name - the name of the plugin, passed as a camelCased string.
50     * @fires Plugin#init
51     */
52    registerPlugin: function (plugin, name) {
53      var pluginName = name ? hyphenate(name) : functionName(plugin.constructor).toLowerCase();
54      plugin.uuid = this.GetYoDigits(6, pluginName);
55
56      if (!plugin.$element.attr('data-' + pluginName)) {
57        plugin.$element.attr('data-' + pluginName, plugin.uuid);
58      }
59      if (!plugin.$element.data('zfPlugin')) {
60        plugin.$element.data('zfPlugin', plugin);
61      }
62      /**
63       * Fires when the plugin has initialized.
64       * @event Plugin#init
65       */
66      plugin.$element.trigger('init.zf.' + pluginName);
67
68      this._uuids.push(plugin.uuid);
69
70      return;
71    },
72    /**
73     * @function
74     * Removes the plugins uuid from the _uuids array.
75     * Removes the zfPlugin data attribute, as well as the data-plugin-name attribute.
76     * Also fires the destroyed event for the plugin, consolidating repetitive code.
77     * @param {Object} plugin - an instance of a plugin, usually `this` in context.
78     * @fires Plugin#destroyed
79     */
80    unregisterPlugin: function (plugin) {
81      var pluginName = hyphenate(functionName(plugin.$element.data('zfPlugin').constructor));
82
83      this._uuids.splice(this._uuids.indexOf(plugin.uuid), 1);
84      plugin.$element.removeAttr('data-' + pluginName).removeData('zfPlugin')
85      /**
86       * Fires when the plugin has been destroyed.
87       * @event Plugin#destroyed
88       */
89      .trigger('destroyed.zf.' + pluginName);
90      for (var prop in plugin) {
91        plugin[prop] = null; //clean up script to prep for garbage collection.
92      }
93      return;
94    },
95
96    /**
97     * @function
98     * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc.
99     * @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'`
100     * @default If no argument is passed, reflow all currently active plugins.
101     */
102    reInit: function (plugins) {
103      var isJQ = plugins instanceof $;
104      try {
105        if (isJQ) {
106          plugins.each(function () {
107            $(this).data('zfPlugin')._init();
108          });
109        } else {
110          var type = typeof plugins,
111              _this = this,
112              fns = {
113            'object': function (plgs) {
114              plgs.forEach(function (p) {
115                p = hyphenate(p);
116                $('[data-' + p + ']').foundation('_init');
117              });
118            },
119            'string': function () {
120              plugins = hyphenate(plugins);
121              $('[data-' + plugins + ']').foundation('_init');
122            },
123            'undefined': function () {
124              this['object'](Object.keys(_this._plugins));
125            }
126          };
127          fns[type](plugins);
128        }
129      } catch (err) {
130        console.error(err);
131      } finally {
132        return plugins;
133      }
134    },
135
136    /**
137     * returns a random base-36 uid with namespacing
138     * @function
139     * @param {Number} length - number of random base-36 digits desired. Increase for more random strings.
140     * @param {String} namespace - name of plugin to be incorporated in uid, optional.
141     * @default {String} '' - if no plugin name is provided, nothing is appended to the uid.
142     * @returns {String} - unique id
143     */
144    GetYoDigits: function (length, namespace) {
145      length = length || 6;
146      return Math.round(Math.pow(36, length + 1) - Math.random() * Math.pow(36, length)).toString(36).slice(1) + (namespace ? '-' + namespace : '');
147    },
148    /**
149     * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized.
150     * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object.
151     * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything.
152     */
153    reflow: function (elem, plugins) {
154
155      // If plugins is undefined, just grab everything
156      if (typeof plugins === 'undefined') {
157        plugins = Object.keys(this._plugins);
158      }
159      // If plugins is a string, convert it to an array with one item
160      else if (typeof plugins === 'string') {
161          plugins = [plugins];
162        }
163
164      var _this = this;
165
166      // Iterate through each plugin
167      $.each(plugins, function (i, name) {
168        // Get the current plugin
169        var plugin = _this._plugins[name];
170
171        // Localize the search to all elements inside elem, as well as elem itself, unless elem === document
172        var $elem = $(elem).find('[data-' + name + ']').addBack('[data-' + name + ']');
173
174        // For each plugin found, initialize it
175        $elem.each(function () {
176          var $el = $(this),
177              opts = {};
178          // Don't double-dip on plugins
179          if ($el.data('zfPlugin')) {
180            console.warn("Tried to initialize " + name + " on an element that already has a Foundation plugin.");
181            return;
182          }
183
184          if ($el.attr('data-options')) {
185            var thing = $el.attr('data-options').split(';').forEach(function (e, i) {
186              var opt = e.split(':').map(function (el) {
187                return el.trim();
188              });
189              if (opt[0]) opts[opt[0]] = parseValue(opt[1]);
190            });
191          }
192          try {
193            $el.data('zfPlugin', new plugin($(this), opts));
194          } catch (er) {
195            console.error(er);
196          } finally {
197            return;
198          }
199        });
200      });
201    },
202    getFnName: functionName,
203    transitionend: function ($elem) {
204      var transitions = {
205        'transition': 'transitionend',
206        'WebkitTransition': 'webkitTransitionEnd',
207        'MozTransition': 'transitionend',
208        'OTransition': 'otransitionend'
209      };
210      var elem = document.createElement('div'),
211          end;
212
213      for (var t in transitions) {
214        if (typeof elem.style[t] !== 'undefined') {
215          end = transitions[t];
216        }
217      }
218      if (end) {
219        return end;
220      } else {
221        end = setTimeout(function () {
222          $elem.triggerHandler('transitionend', [$elem]);
223        }, 1);
224        return 'transitionend';
225      }
226    }
227  };
228
229  Foundation.util = {
230    /**
231     * Function for applying a debounce effect to a function call.
232     * @function
233     * @param {Function} func - Function to be called at end of timeout.
234     * @param {Number} delay - Time in ms to delay the call of `func`.
235     * @returns function
236     */
237    throttle: function (func, delay) {
238      var timer = null;
239
240      return function () {
241        var context = this,
242            args = arguments;
243
244        if (timer === null) {
245          timer = setTimeout(function () {
246            func.apply(context, args);
247            timer = null;
248          }, delay);
249        }
250      };
251    }
252  };
253
254  // TODO: consider not making this a jQuery function
255  // TODO: need way to reflow vs. re-initialize
256  /**
257   * The Foundation jQuery method.
258   * @param {String|Array} method - An action to perform on the current jQuery object.
259   */
260  var foundation = function (method) {
261    var type = typeof method,
262        $meta = $('meta.foundation-mq'),
263        $noJS = $('.no-js');
264
265    if (!$meta.length) {
266      $('<meta class="foundation-mq">').appendTo(document.head);
267    }
268    if ($noJS.length) {
269      $noJS.removeClass('no-js');
270    }
271
272    if (type === 'undefined') {
273      //needs to initialize the Foundation object, or an individual plugin.
274      Foundation.MediaQuery._init();
275      Foundation.reflow(this);
276    } else if (type === 'string') {
277      //an individual method to invoke on a plugin or group of plugins
278      var args = Array.prototype.slice.call(arguments, 1); //collect all the arguments, if necessary
279      var plugClass = this.data('zfPlugin'); //determine the class of plugin
280
281      if (plugClass !== undefined && plugClass[method] !== undefined) {
282        //make sure both the class and method exist
283        if (this.length === 1) {
284          //if there's only one, call it directly.
285          plugClass[method].apply(plugClass, args);
286        } else {
287          this.each(function (i, el) {
288            //otherwise loop through the jQuery collection and invoke the method on each
289            plugClass[method].apply($(el).data('zfPlugin'), args);
290          });
291        }
292      } else {
293        //error for no class or no method
294        throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.');
295      }
296    } else {
297      //error for invalid argument type
298      throw new TypeError('We\'re sorry, ' + type + ' is not a valid parameter. You must use a string representing the method you wish to invoke.');
299    }
300    return this;
301  };
302
303  window.Foundation = Foundation;
304  $.fn.foundation = foundation;
305
306  // Polyfill for requestAnimationFrame
307  (function () {
308    if (!Date.now || !window.Date.now) window.Date.now = Date.now = function () {
309      return new Date().getTime();
310    };
311
312    var vendors = ['webkit', 'moz'];
313    for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
314      var vp = vendors[i];
315      window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
316      window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];
317    }
318    if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
319      var lastTime = 0;
320      window.requestAnimationFrame = function (callback) {
321        var now = Date.now();
322        var nextTime = Math.max(lastTime + 16, now);
323        return setTimeout(function () {
324          callback(lastTime = nextTime);
325        }, nextTime - now);
326      };
327      window.cancelAnimationFrame = clearTimeout;
328    }
329    /**
330     * Polyfill for performance.now, required by rAF
331     */
332    if (!window.performance || !window.performance.now) {
333      window.performance = {
334        start: Date.now(),
335        now: function () {
336          return Date.now() - this.start;
337        }
338      };
339    }
340  })();
341  if (!Function.prototype.bind) {
342    Function.prototype.bind = function (oThis) {
343      if (typeof this !== 'function') {
344        // closest thing possible to the ECMAScript 5
345        // internal IsCallable function
346        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
347      }
348
349      var aArgs = Array.prototype.slice.call(arguments, 1),
350          fToBind = this,
351          fNOP = function () {},
352          fBound = function () {
353        return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
354      };
355
356      if (this.prototype) {
357        // native functions don't have a prototype
358        fNOP.prototype = this.prototype;
359      }
360      fBound.prototype = new fNOP();
361
362      return fBound;
363    };
364  }
365  // Polyfill to get the name of a function in IE9
366  function functionName(fn) {
367    if (Function.prototype.name === undefined) {
368      var funcNameRegex = /function\s([^(]{1,})\(/;
369      var results = funcNameRegex.exec(fn.toString());
370      return results && results.length > 1 ? results[1].trim() : "";
371    } else if (fn.prototype === undefined) {
372      return fn.constructor.name;
373    } else {
374      return fn.prototype.constructor.name;
375    }
376  }
377  function parseValue(str) {
378    if (/true/.test(str)) return true;else if (/false/.test(str)) return false;else if (!isNaN(str * 1)) return parseFloat(str);
379    return str;
380  }
381  // Convert PascalCase to kebab-case
382  // Thank you: http://stackoverflow.com/a/8955580
383  function hyphenate(str) {
384    return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
385  }
386}(jQuery);
387'use strict';
388
389!function ($) {
390
391  // Default set of media queries
392  var defaultQueries = {
393    'default': 'only screen',
394    landscape: 'only screen and (orientation: landscape)',
395    portrait: 'only screen and (orientation: portrait)',
396    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)'
397  };
398
399  var MediaQuery = {
400    queries: [],
401
402    current: '',
403
404    /**
405     * Initializes the media query helper, by extracting the breakpoint list from the CSS and activating the breakpoint watcher.
406     * @function
407     * @private
408     */
409    _init: function () {
410      var self = this;
411      var extractedStyles = $('.foundation-mq').css('font-family');
412      var namedQueries;
413
414      namedQueries = parseStyleToObject(extractedStyles);
415
416      for (var key in namedQueries) {
417        if (namedQueries.hasOwnProperty(key)) {
418          self.queries.push({
419            name: key,
420            value: 'only screen and (min-width: ' + namedQueries[key] + ')'
421          });
422        }
423      }
424
425      this.current = this._getCurrentSize();
426
427      this._watcher();
428    },
429
430
431    /**
432     * Checks if the screen is at least as wide as a breakpoint.
433     * @function
434     * @param {String} size - Name of the breakpoint to check.
435     * @returns {Boolean} `true` if the breakpoint matches, `false` if it's smaller.
436     */
437    atLeast: function (size) {
438      var query = this.get(size);
439
440      if (query) {
441        return window.matchMedia(query).matches;
442      }
443
444      return false;
445    },
446
447
448    /**
449     * Gets the media query of a breakpoint.
450     * @function
451     * @param {String} size - Name of the breakpoint to get.
452     * @returns {String|null} - The media query of the breakpoint, or `null` if the breakpoint doesn't exist.
453     */
454    get: function (size) {
455      for (var i in this.queries) {
456        if (this.queries.hasOwnProperty(i)) {
457          var query = this.queries[i];
458          if (size === query.name) return query.value;
459        }
460      }
461
462      return null;
463    },
464
465
466    /**
467     * Gets the current breakpoint name by testing every breakpoint and returning the last one to match (the biggest one).
468     * @function
469     * @private
470     * @returns {String} Name of the current breakpoint.
471     */
472    _getCurrentSize: function () {
473      var matched;
474
475      for (var i = 0; i < this.queries.length; i++) {
476        var query = this.queries[i];
477
478        if (window.matchMedia(query.value).matches) {
479          matched = query;
480        }
481      }
482
483      if (typeof matched === 'object') {
484        return matched.name;
485      } else {
486        return matched;
487      }
488    },
489
490
491    /**
492     * Activates the breakpoint watcher, which fires an event on the window whenever the breakpoint changes.
493     * @function
494     * @private
495     */
496    _watcher: function () {
497      var _this = this;
498
499      $(window).on('resize.zf.mediaquery', function () {
500        var newSize = _this._getCurrentSize(),
501            currentSize = _this.current;
502
503        if (newSize !== currentSize) {
504          // Change the current media query
505          _this.current = newSize;
506
507          // Broadcast the media query change on the window
508          $(window).trigger('changed.zf.mediaquery', [newSize, currentSize]);
509        }
510      });
511    }
512  };
513
514  Foundation.MediaQuery = MediaQuery;
515
516  // matchMedia() polyfill - Test a CSS media type/query in JS.
517  // Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license
518  window.matchMedia || (window.matchMedia = function () {
519    'use strict';
520
521    // For browsers that support matchMedium api such as IE 9 and webkit
522
523    var styleMedia = window.styleMedia || window.media;
524
525    // For those that don't support matchMedium
526    if (!styleMedia) {
527      var style = document.createElement('style'),
528          script = document.getElementsByTagName('script')[0],
529          info = null;
530
531      style.type = 'text/css';
532      style.id = 'matchmediajs-test';
533
534      script.parentNode.insertBefore(style, script);
535
536      // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
537      info = 'getComputedStyle' in window && window.getComputedStyle(style, null) || style.currentStyle;
538
539      styleMedia = {
540        matchMedium: function (media) {
541          var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
542
543          // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
544          if (style.styleSheet) {
545            style.styleSheet.cssText = text;
546          } else {
547            style.textContent = text;
548          }
549
550          // Test if media query is true or false
551          return info.width === '1px';
552        }
553      };
554    }
555
556    return function (media) {
557      return {
558        matches: styleMedia.matchMedium(media || 'all'),
559        media: media || 'all'
560      };
561    };
562  }());
563
564  // Thank you: https://github.com/sindresorhus/query-string
565  function parseStyleToObject(str) {
566    var styleObject = {};
567
568    if (typeof str !== 'string') {
569      return styleObject;
570    }
571
572    str = str.trim().slice(1, -1);
572 // browsers re-quote string style values
573
574    if (!str) {
575      return styleObject;
576    }
577
578    styleObject = str.split('&').reduce(function (ret, param) {
579      var parts = param.replace(/\+/g, ' ').split('=');
580      var key = parts[0];
581      var val = parts[1];
582      key = decodeURIComponent(key);
583
584      // missing `=` should be `null`:
585      // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
586      val = val === undefined ? null : decodeURIComponent(val);
587
588      if (!ret.hasOwnProperty(key)) {
589        ret[key] = val;
590      } else if (Array.isArray(ret[key])) {
591        ret[key].push(val);
592      } else {
593        ret[key] = [ret[key], val];
594      }
595      return ret;
596    }, {});
597
598    return styleObject;
599  }
600
601  Foundation.MediaQuery = MediaQuery;
602}(jQuery);
603/*******************************************
604 *                                         *
605 * This util was created by Marius Olbertz *
606 * Please thank Marius on GitHub /owlbertz *
607 * or the web http://www.mariusolbertz.de/ *
608 *                                         *
609 ******************************************/
610
611'use strict';
612
613!function ($) {
614
615  var keyCodes = {
616    9: 'TAB',
617    13: 'ENTER',
618    27: 'ESCAPE',
619    32: 'SPACE',
620    37: 'ARROW_LEFT',
621    38: 'ARROW_UP',
622    39: 'ARROW_RIGHT',
623    40: 'ARROW_DOWN'
624  };
625
626  var commands = {};
627
628  var Keyboard = {
629    keys: getKeyCodes(keyCodes),
630
631    /**
632     * Parses the (keyboard) event and returns a String that represents its key
633     * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
634     * @param {Event} event - the event generated by the event handler
635     * @return String key - String that represents the key pressed
636     */
637    parseKey: function (event) {
638      var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase();
639      if (event.shiftKey) key = 'SHIFT_' + key;
640      if (event.ctrlKey) key = 'CTRL_' + key;
641      if (event.altKey) key = 'ALT_' + key;
642      return key;
643    },
644
645
646    /**
647     * Handles the given (keyboard) event
648     * @param {Event} event - the event generated by the event handler
649     * @param {String} component - Foundation component's name, e.g. Slider or Reveal
650     * @param {Objects} functions - collection of functions that are to be executed
651     */
652    handleKey: function (event, component, functions) {
653      var commandList = commands[component],
654          keyCode = this.parseKey(event),
655          cmds,
656          command,
657          fn;
658
659      if (!commandList) return console.warn('Component not defined!');
660
661      if (typeof commandList.ltr === 'undefined') {
662        // this component does not differentiate between ltr and rtl
663        cmds = commandList; // use plain list
664      } else {
665          // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa
666          if (Foundation.rtl()) cmds = $.extend({}, commandList.ltr, commandList.rtl);else cmds = $.extend({}, commandList.rtl, commandList.ltr);
667        }
668      command = cmds[keyCode];
669
670      fn = functions[command];
671      if (fn && typeof fn === 'function') {
672        // execute function  if exists
673        var returnValue = fn.apply();
674        if (functions.handled || typeof functions.handled === 'function') {
675          // execute function when event was handled
676          functions.handled(returnValue);
677        }
678      } else {
679        if (functions.unhandled || typeof functions.unhandled === 'function') {
680          // execute function when event was not handled
681          functions.unhandled();
682        }
683      }
684    },
685
686
687    /**
688     * Finds all focusable elements within the given `$element`
689     * @param {jQuery} $element - jQuery object to search within
690     * @return {jQuery} $focusable - all focusable elements within `$element`
691     */
692    findFocusable: function ($element) {
693      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 () {
694        if (!$(this).is(':visible') || $(this).attr('tabindex') < 0) {
695          return false;
696        } //only have visible elements and those that have a tabindex greater or equal 0
697        return true;
698      });
699    },
700
701
702    /**
703     * Returns the component name name
704     * @param {Object} component - Foundation component, e.g. Slider or Reveal
705     * @return String componentName
706     */
707
708    register: function (componentName, cmds) {
709      commands[componentName] = cmds;
710    }
711  };
712
713  /*
714   * Constants for easier comparing.
715   * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
716   */
717  function getKeyCodes(kcs) {
718    var k = {};
719    for (var kc in kcs) {
720      k[kcs[kc]] = kcs[kc];
721    }return k;
722  }
723
724  Foundation.Keyboard = Keyboard;
725}(jQuery);
726'use strict';
727
728!function ($) {
729
730  /**
731   * Motion module.
732   * @module foundation.motion
733   */
734
735  var initClasses = ['mui-enter', 'mui-leave'];
736  var activeClasses = ['mui-enter-active', 'mui-leave-active'];
737
738  var Motion = {
739    animateIn: function (element, animation, cb) {
740      animate(true, element, animation, cb);
741    },
742
743    animateOut: function (element, animation, cb) {
744      animate(false, element, animation, cb);
745    }
746  };
747
748  function Move(duration, elem, fn) {
749    var anim,
750        prog,
751        start = null;
752    // console.log('called');
753
754    function move(ts) {
755      if (!start) start = window.performance.now();
756      // console.log(start, ts);
757      prog = ts - start;
758      fn.apply(elem);
759
760      if (prog < duration) {
761        anim = window.requestAnimationFrame(move, elem);
762      } else {
763        window.cancelAnimationFrame(anim);
764        elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
765      }
766    }
767    anim = window.requestAnimationFrame(move);
768  }
769
770  /**
771   * Animates an element in or out using a CSS transition class.
772   * @function
773   * @private
774   * @param {Boolean} isIn - Defines if the animation is in or out.
775   * @param {Object} element - jQuery or HTML object to animate.
776   * @param {String} animation - CSS class to use.
777   * @param {Function} cb - Callback to run when animation is finished.
778   */
779  function animate(isIn, element, animation, cb) {
780    element = $(element).eq(0);
781
782    if (!element.length) return;
783
784    var initClass = isIn ? initClasses[0] : initClasses[1];
785    var activeClass = isIn ? activeClasses[0] : activeClasses[1];
786
787    // Set up the animation
788    reset();
789
790    element.addClass(animation).css('transition', 'none');
791
792    requestAnimationFrame(function () {
793      element.addClass(initClass);
794      if (isIn) element.show();
795    });
796
797    // Start the animation
798    requestAnimationFrame(function () {
799      element[0].offsetWidth;
800      element.css('transition', '').addClass(activeClass);
801    });
802
803    // Clean up the animation when it finishes
804    element.one(Foundation.transitionend(element), finish);
805
806    // Hides the element (for out animations), resets the element, and runs a callback
807    function finish() {
808      if (!isIn) element.hide();
809      reset();
810      if (cb) cb.apply(element);
811    }
812
813    // Resets transitions and removes motion-specific classes
814    function reset() {
815      element[0].style.transitionDuration = 0;
816      element.removeClass(initClass + ' ' + activeClass + ' ' + animation);
817    }
818  }
819
820  Foundation.Move = Move;
821  Foundation.Motion = Motion;
822}(jQuery);
823'use strict';
824
825!function ($) {
826
827  var Nest = {
828    Feather: function (menu) {
829      var type = arguments.length <= 1 || arguments[1] === undefined ? 'zf' : arguments[1];
830
831      menu.attr('role', 'menubar');
832
833      var items = menu.find('li').attr({ 'role': 'menuitem' }),
834          subMenuClass = 'is-' + type + '-submenu',
835          subItemClass = subMenuClass + '-item',
836          hasSubClass = 'is-' + type + '-submenu-parent';
837
838      menu.find('a:first').attr('tabindex', 0);
839
840      items.each(function () {
841        var $item = $(this),
842            $sub = $item.children('ul');
843
844        if ($sub.length) {
845          $item.addClass(hasSubClass).attr({
846            'aria-haspopup': true,
847            'aria-expanded': false,
848            'aria-label': $item.children('a:first').text()
849          });
850
851          $sub.addClass('submenu ' + subMenuClass).attr({
852            'data-submenu': '',
853            'aria-hidden': true,
854            'role': 'menu'
855          });
856        }
857
858        if ($item.parent('[data-submenu]').length) {
859          $item.addClass('is-submenu-item ' + subItemClass);
860        }
861      });
862
863      return;
864    },
865    Burn: function (menu, type) {
866      var items = menu.find('li').removeAttr('tabindex'),
867          subMenuClass = 'is-' + type + '-submenu',
868          subItemClass = subMenuClass + '-item',
869          hasSubClass = 'is-' + type + '-submenu-parent';
870
871      menu.find('*').removeClass(subMenuClass + ' ' + subItemClass + ' ' + hasSubClass + ' is-submenu-item submenu is-active').removeAttr('data-submenu').css('display', '');
872
873      // console.log(      menu.find('.' + subMenuClass + ', .' + subItemClass + ', .has-submenu, .is-submenu-item, .submenu, [data-submenu]')
874      //           .removeClass(subMenuClass + ' ' + subItemClass + ' has-submenu is-submenu-item submenu')
875      //           .removeAttr('data-submenu'));
876      // items.each(function(){
877      //   var $item = $(this),
878      //       $sub = $item.children('ul');
879      //   if($item.parent('[data-submenu]').length){
880      //     $item.removeClass('is-submenu-item ' + subItemClass);
881      //   }
882      //   if($sub.length){
883      //     $item.removeClass('has-submenu');
884      //     $sub.removeClass('submenu ' + subMenuClass).removeAttr('data-submenu');
885      //   }
886      // });
887    }
888  };
889
890  Foundation.Nest = Nest;
891}(jQuery);
892'use strict';
893
894!function ($) {
895
896  Foundation.Box = {
897    ImNotTouchingYou: ImNotTouchingYou,
898    GetDimensions: GetDimensions,
899    GetOffsets: GetOffsets
900  };
901
902  /**
903   * Compares the dimensions of an element to a container and determines collision events with container.
904   * @function
905   * @param {jQuery} element - jQuery object to test for collisions.
906   * @param {jQuery}
906 parent - jQuery object to use as bounding container.
907   * @param {Boolean} lrOnly - set to true to check left and right values only.
908   * @param {Boolean} tbOnly - set to true to check top and bottom values only.
909   * @default if no parent object passed, detects collisions with `window`.
910   * @returns {Boolean} - true if collision free, false if a collision in any direction.
911   */
912  function ImNotTouchingYou(element, parent, lrOnly, tbOnly) {
913    var eleDims = GetDimensions(element),
914        top,
915        bottom,
916        left,
917        right;
918
919    if (parent) {
920      var parDims = GetDimensions(parent);
921
922      bottom = eleDims.offset.top + eleDims.height <= parDims.height + parDims.offset.top;
923      top = eleDims.offset.top >= parDims.offset.top;
924      left = eleDims.offset.left >= parDims.offset.left;
925      right = eleDims.offset.left + eleDims.width <= parDims.width + parDims.offset.left;
926    } else {
927      bottom = eleDims.offset.top + eleDims.height <= eleDims.windowDims.height + eleDims.windowDims.offset.top;
928      top = eleDims.offset.top >= eleDims.windowDims.offset.top;
929      left = eleDims.offset.left >= eleDims.windowDims.offset.left;
930      right = eleDims.offset.left + eleDims.width <= eleDims.windowDims.width;
931    }
932
933    var allDirs = [bottom, top, left, right];
934
935    if (lrOnly) {
936      return left === right === true;
937    }
938
939    if (tbOnly) {
940      return top === bottom === true;
941    }
942
943    return allDirs.indexOf(false) === -1;
944  };
945
946  /**
947   * Uses native methods to return an object of dimension values.
948   * @function
949   * @param {jQuery || HTML} element - jQuery object or DOM element for which to get the dimensions. Can be any element other that document or window.
950   * @returns {Object} - nested object of integer pixel values
951   * TODO - if element is window, return only those values.
952   */
953  function GetDimensions(elem, test) {
954    elem = elem.length ? elem[0] : elem;
955
956    if (elem === window || elem === document) {
957      throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");
958    }
959
960    var rect = elem.getBoundingClientRect(),
961        parRect = elem.parentNode.getBoundingClientRect(),
962        winRect = document.body.getBoundingClientRect(),
963        winY = window.pageYOffset,
964        winX = window.pageXOffset;
965
966    return {
967      width: rect.width,
968      height: rect.height,
969      offset: {
970        top: rect.top + winY,
971        left: rect.left + winX
972      },
973      parentDims: {
974        width: parRect.width,
975        height: parRect.height,
976        offset: {
977          top: parRect.top + winY,
978          left: parRect.left + winX
979        }
980      },
981      windowDims: {
982        width: winRect.width,
983        height: winRect.height,
984        offset: {
985          top: winY,
986          left: winX
987        }
988      }
989    };
990  }
991
992  /**
993   * Returns an object of top and left integer pixel values for dynamically rendered elements,
994   * such as: Tooltip, Reveal, and Dropdown
995   * @function
996   * @param {jQuery} element - jQuery object for the element being positioned.
997   * @param {jQuery} anchor - jQuery object for the element's anchor point.
998   * @param {String} position - a string relating to the desired position of the element, relative to it's anchor
999   * @param {Number} vOffset - integer pixel value of desired vertical separation between anchor and element.
1000   * @param {Number} hOffset - integer pixel value of desired horizontal separation between anchor and element.
1001   * @param {Boolean} isOverflow - if a collision event is detected, sets to true to default the element to full width - any desired offset.
1002   * TODO alter/rewrite to work with `em` values as well/instead of pixels
1003   */
1004  function GetOffsets(element, anchor, position, vOffset, hOffset, isOverflow) {
1005    var $eleDims = GetDimensions(element),
1006        $anchorDims = anchor ? GetDimensions(anchor) : null;
1007
1008    switch (position) {
1009      case 'top':
1010        return {
1011          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
1012          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
1013        };
1014        break;
1015      case 'left':
1016        return {
1017          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
1018          top: $anchorDims.offset.top
1019        };
1020        break;
1021      case 'right':
1022        return {
1023          left: $anchorDims.offset.left + $anchorDims.width + hOffset,
1024          top: $anchorDims.offset.top
1025        };
1026        break;
1027      case 'center top':
1028        return {
1029          left: $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
1030          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
1031        };
1032        break;
1033      case 'center bottom':
1034        return {
1035          left: isOverflow ? hOffset : $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
1036          top: $anchorDims.offset.top + $anchorDims.height + vOffset
1037        };
1038        break;
1039      case 'center left':
1040        return {
1041          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
1042          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
1043        };
1044        break;
1045      case 'center right':
1046        return {
1047          left: $anchorDims.offset.left + $anchorDims.width + hOffset + 1,
1048          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
1049        };
1050        break;
1051      case 'center':
1052        return {
1053          left: $eleDims.windowDims.offset.left + $eleDims.windowDims.width / 2 - $eleDims.width / 2,
1054          top: $eleDims.windowDims.offset.top + $eleDims.windowDims.height / 2 - $eleDims.height / 2
1055        };
1056        break;
1057      case 'reveal':
1058        return {
1059          left: ($eleDims.windowDims.width - $eleDims.width) / 2,
1060          top: $eleDims.windowDims.offset.top + vOffset
1061        };
1062      case 'reveal full':
1063        return {
1064          left: $eleDims.windowDims.offset.left,
1065          top: $eleDims.windowDims.offset.top
1066        };
1067        break;
1068      case 'left bottom':
1069        return {
1070          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
1071          top: $anchorDims.offset.top + $anchorDims.height
1072        };
1073        break;
1074      case 'right bottom':
1075        return {
1076          left: $anchorDims.offset.left + $anchorDims.width + hOffset - $eleDims.width,
1077          top: $anchorDims.offset.top + $anchorDims.height
1078        };
1079        break;
1080      default:
1081        return {
1082          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
1083          top: $anchorDims.offset.top + $anchorDims.height + vOffset
1084        };
1085    }
1086  }
1087}(jQuery);
1088'use strict';
1089
1090!function ($) {
1091
1092  var MutationObserver = function () {
1093    var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
1094    for (var i = 0; i < prefixes.length; i++) {
1095      if (prefixes[i] + 'MutationObserver' in window) {
1096        return window[prefixes[i] + 'MutationObserver'];
1097      }
1098    }
1099    return false;
1100  }();
1101
1102  var triggers = function (el, type) {
1103    el.data(type).split(' ').forEach(function (id) {
1104      $('#' + id)[type === 'close' ? 'trigger' : 'triggerHandler'](type + '.zf.trigger', [el]);
1105    });
1106  };
1107  // Elements with [data-open] will reveal a plugin that supports it when clicked.
1108  $(document).on('click.zf.trigger', '[data-open]', function () {
1109    triggers($(this), 'open');
1110  });
1111
1112  // Elements with [data-close] will close a plugin that supports it when clicked.
1113  // If used without a value on [data-close], the event will bubble, allowing it to close a parent component.
1114  $(document).on('click.zf.trigger', '[data-close]', function () {
1115    var id = $(this).data('close');
1116    if (id) {
1117      triggers($(this), 'close');
1118    } else {
1119      $(this).trigger('close.zf.trigger');
1120    }
1121  });
1122
1123  // Elements with [data-toggle] will toggle a plugin that supports it when clicked.
1124  $(document).on('click.zf.trigger', '[data-toggle]', function () {
1125    triggers($(this), 'toggle');
1126  });
1127
1128  // Elements with [data-closable] will respond to close.zf.trigger events.
1129  $(document).on('close.zf.trigger', '[data-closable]', function (e) {
1130    e.stopPropagation();
1131    var animation = $(this).data('closable');
1132
1133    if (animation !== '') {
1134      Foundation.Motion.animateOut($(this), animation, function () {
1135        $(this).trigger('closed.zf');
1136      });
1137    } else {
1138      $(this).fadeOut().trigger('closed.zf');
1139    }
1140  });
1141
1142  $(document).on('focus.zf.trigger blur.zf.trigger', '[data-toggle-focus]', function () {
1143    var id = $(this).data('toggle-focus');
1144    $('#' + id).triggerHandler('toggle.zf.trigger', [$(this)]);
1145  });
1146
1147  /**
1148  * Fires once after all other scripts have loaded
1149  * @function
1150  * @private
1151  */
1152  $(window).load(function () {
1153    checkListeners();
1154  });
1155
1156  function checkListeners() {
1157    eventsListener();
1158    resizeListener();
1159    scrollListener();
1160    closemeListener();
1161  }
1162
1163  //******** only fires this function once on load, if there's something to watch ********
1164  function closemeListener(pluginName) {
1165    var yetiBoxes = $('[data-yeti-box]'),
1166        plugNames = ['dropdown', 'tooltip', 'reveal'];
1167
1168    if (pluginName) {
1169      if (typeof pluginName === 'string') {
1170        plugNames.push(pluginName);
1171      } else if (typeof pluginName === 'object' && typeof pluginName[0] === 'string') {
1172        plugNames.concat(pluginName);
1173      } else {
1174        console.error('Plugin names must be strings');
1175      }
1176    }
1177    if (yetiBoxes.length) {
1178      var listeners = plugNames.map(function (name) {
1179        return 'closeme.zf.' + name;
1180      }).join(' ');
1181
1182      $(window).off(listeners).on(listeners, function (e, pluginId) {
1183        var plugin = e.namespace.split('.')[0];
1184        var plugins = $('[data-' + plugin + ']').not('[data-yeti-box="' + pluginId + '"]');
1185
1186        plugins.each(function () {
1187          var _this = $(this);
1188
1189          _this.triggerHandler('close.zf.trigger', [_this]);
1190        });
1191      });
1192    }
1193  }
1194
1195  function resizeListener(debounce) {
1196    var timer = void 0,
1197        $nodes = $('[data-resize]');
1198    if ($nodes.length) {
1199      $(window).off('resize.zf.trigger').on('resize.zf.trigger', function (e) {
1200        if (timer) {
1201          clearTimeout(timer);
1202        }
1203
1204        timer = setTimeout(function () {
1205
1206          if (!MutationObserver) {
1207            //fallback for IE 9
1208            $nodes.each(function () {
1209              $(this).triggerHandler('resizeme.zf.trigger');
1210            });
1211          }
1212          //trigger all listening elements and signal a resize event
1213          $nodes.attr('data-events', "resize");
1214        }, debounce || 10); //default time to emit resize event
1215      });
1216    }
1217  }
1218
1219  function scrollListener(debounce) {
1220    var timer = void 0,
1221        $nodes = $('[data-scroll]');
1222    if ($nodes.length) {
1223      $(window).off('scroll.zf.trigger').on('scroll.zf.trigger', function (e) {
1224        if (timer) {
1225          clearTimeout(timer);
1226        }
1227
1228        timer = setTimeout(function () {
1229
1230          if (!MutationObserver) {
1231            //fallback for IE 9
1232            $nodes.each(function () {
1233              $(this).triggerHandler('scrollme.zf.trigger');
1234            });
1235          }
1236          //trigger all listening elements and signal a scroll event
1237          $nodes.attr('data-events', "scroll");
1238        }, debounce || 10); //default time to emit scroll event
1239      });
1240    }
1241  }
1242
1243  function eventsListener() {
1244    if (!MutationObserver) {
1245      return false;
1246    }
1247    var nodes = document.querySelectorAll('[data-resize], [data-scroll], [data-mutate]');
1248
1249    //element callback
1250    var listeningElementsMutation = function (mutationRecordsList) {
1251      var $target = $(mutationRecordsList[0].target);
1252      //trigger the event handler for the element depending on type
1253      switch ($target.attr("data-events")) {
1254
1255        case "resize":
1256          $target.triggerHandler('resizeme.zf.trigger', [$target]);
1257          break;
1258
1259        case "scroll":
1260          $target.triggerHandler('scrollme.zf.trigger', [$target, window.pageYOffset]);
1261          break;
1262
1263        // case "mutate" :
1264        // console.log('mutate', $target);
1265        // $target.triggerHandler('mutate.zf.trigger');
1266        //
1267        // //make sure we don't get stuck in an infinite loop from sloppy codeing
1268        // if ($target.index('[data-mutate]') == $("[data-mutate]").length-1) {
1269        //   domMutationObserver();
1270        // }
1271        // break;
1272
1273        default:
1274          return false;
1275        //nothing
1276      }
1277    };
1278
1279    if (nodes.length) {
1280      //for each element that needs to listen for resizing, scrolling, (or coming soon mutation) add a single observer
1281      for (var i = 0; i <= nodes.length - 1; i++) {
1282        var elementObserver = new MutationObserver(listeningElementsMutation);
1283        elementObserver.observe(nodes[i], { attributes: true, childList: false, characterData: false, subtree: false, attributeFilter: ["data-events"] });
1284      }
1285    }
1286  }
1287
1288  // ------------------------------------
1289
1290  // [PH]
1291  // Foundation.CheckWatchers = checkWatchers;
1292  Foundation.IHearYou = checkListeners;
1293  // Foundation.ISeeYou = scrollListener;
1294  // Foundation.IFeelYou = closemeListener;
1295}(jQuery);
1296
1297// function domMutationObserver(debounce) {
1298//   // !!! This is coming soon and needs more work; not active  !!! //
1299//   var timer,
1300//   nodes = document.querySelectorAll('[data-mutate]');
1301//   //
1302//   if (nodes.length) {
1303//     // var MutationObserver = (function () {
1304//     //   var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
1305//     //   for (var i=0; i < prefixes.length; i++) {
1306//     //     if (prefixes[i] + 'MutationObserver' in window) {
1307//     //       return window[prefixes[i] + 'MutationObserver'];
1308//     //     }
1309//     //   }
1310//     //   return false;
1311//     // }());
1312//
1313//
1314//     //for the body, we need to listen for all changes effecting the style and class attributes
1315//     var bodyObserver = new MutationObserver(bodyMutation);
1316//     bodyObserver.observe(document.body, { attributes: true, childList: true, characterData: false, subtree:true, attributeFilter:["style", "class"]});
1317//
1318//
1319//     //body callback
1320//     function bodyMutation(mutate) {
1321//       //trigger all listening elements and signal a mutation event
1322//       if (timer) { clearTimeout(timer); }
1323//
1324//       timer = setTimeout(function() {
1325//         bodyObserver.disconnect();
1326//         $('[data-mutate]').attr('data-events',"mutate");
1327//       }, debounce || 150);
1328//     }
1329//   }
1330// }
1331'use strict';
1332
1333!function ($) {
1334
1335  function Timer(elem, options, cb) {
1336    var _this = this,
1337        duration = options.duration,
1338        //options is an object for easily adding features later.
1339    nameSpace = Object.keys(elem.data())[0] || 'timer',
1340        remain = -1,
1341        start,
1342        timer;
1343
1344    this.isPaused = false;
1345
1346    this.restart = function () {
1347      remain = -1;
1348      clearTimeout(timer);
1349      this.start();
1350    };
1351
1352    this.start = function () {
1353      this.isPaused = false;
1354      // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.
1355      clearTimeout(timer);
1356      remain = remain <= 0 ? duration : remain;
1357      elem.data('paused', false);
1358      start = Date.now();
1359      timer = setTimeout(function () {
1360        if (options.infinite) {
1361          _this.restart(); //rerun the timer.
1362        }
1363        cb();
1364      }, remain);
1365      elem.trigger('timerstart.zf.' + nameSpace);
1366    };
1367
1368    this.pause = function () {
1369      this.isPaused = true;
1370      //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.
1371      clearTimeout(timer);
1372      elem.data('paused', true);
1373      var end = Date.now();
1374      remain = remain - (end - start);
1375      elem.trigger('timerpaused.zf.' + nameSpace);
1376    };
1377  }
1378
1379  /**
1380   * Runs a callback function when images are fully loaded.
1381   * @param {Object} images - Image(s) to check if loaded.
1382   * @param {Func} callback - Function to execute when image is fully loaded.
1383   */
1384  function onImagesLoaded(images, callback) {
1385    var self = this,
1386        unloaded = images.length;
1387
1388    if (unloaded === 0) {
1389      callback();
1390    }
1391
1392    images.each(function () {
1393      if (this.complete) {
1394        singleImageLoaded();
1395      }
1395 else if (typeof this.naturalWidth !== 'undefined' && this.naturalWidth > 0) {
1396        singleImageLoaded();
1397      } else {
1398        $(this).one('load', function () {
1399          singleImageLoaded();
1400        });
1401      }
1402    });
1403
1404    function singleImageLoaded() {
1405      unloaded--;
1406      if (unloaded === 0) {
1407        callback();
1408      }
1409    }
1410  }
1411
1412  Foundation.Timer = Timer;
1413  Foundation.onImagesLoaded = onImagesLoaded;
1414}(jQuery);
1415//**************************************************
1416//**Work inspired by multiple jquery swipe plugins**
1417//**Done by Yohai Ararat ***************************
1418//**************************************************
1419(function ($) {
1420
1421	$.spotSwipe = {
1422		version: '1.0.0',
1423		enabled: 'ontouchstart' in document.documentElement,
1424		preventDefault: false,
1425		moveThreshold: 75,
1426		timeThreshold: 200
1427	};
1428
1429	var startPosX,
1430	    startPosY,
1431	    startTime,
1432	    elapsedTime,
1433	    isMoving = false;
1434
1435	function onTouchEnd() {
1436		//  alert(this);
1437		this.removeEventListener('touchmove', onTouchMove);
1438		this.removeEventListener('touchend', onTouchEnd);
1439		isMoving = false;
1440	}
1441
1442	function onTouchMove(e) {
1443		if ($.spotSwipe.preventDefault) {
1444			e.preventDefault();
1445		}
1446		if (isMoving) {
1447			var x = e.touches[0].pageX;
1448			var y = e.touches[0].pageY;
1449			var dx = startPosX - x;
1450			var dy = startPosY - y;
1451			var dir;
1452			elapsedTime = new Date().getTime() - startTime;
1453			if (Math.abs(dx) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
1454				dir = dx > 0 ? 'left' : 'right';
1455			}
1456			// else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
1457			//   dir = dy > 0 ? 'down' : 'up';
1458			// }
1459			if (dir) {
1460				e.preventDefault();
1461				onTouchEnd.call(this);
1462				$(this).trigger('swipe', dir).trigger('swipe' + dir);
1463			}
1464		}
1465	}
1466
1467	function onTouchStart(e) {
1468		if (e.touches.length == 1) {
1469			startPosX = e.touches[0].pageX;
1470			startPosY = e.touches[0].pageY;
1471			isMoving = true;
1472			startTime = new Date().getTime();
1473			this.addEventListener('touchmove', onTouchMove, false);
1474			this.addEventListener('touchend', onTouchEnd, false);
1475		}
1476	}
1477
1478	function init() {
1479		this.addEventListener && this.addEventListener('touchstart', onTouchStart, false);
1480	}
1481
1482	function teardown() {
1483		this.removeEventListener('touchstart', onTouchStart);
1484	}
1485
1486	$.event.special.swipe = { setup: init };
1487
1488	$.each(['left', 'up', 'down', 'right'], function () {
1489		$.event.special['swipe' + this] = { setup: function () {
1490				$(this).on('swipe', $.noop);
1491			} };
1492	});
1493})(jQuery);
1494/****************************************************
1495 * Method for adding psuedo drag events to elements *
1496 ***************************************************/
1497!function ($) {
1498	$.fn.addTouch = function () {
1499		this.each(function (i, el) {
1500			$(el).bind('touchstart touchmove touchend touchcancel', function () {
1501				//we pass the original event object because the jQuery event
1502				//object is normalized to w3c specs and does not provide the TouchList
1503				handleTouch(event);
1504			});
1505		});
1506
1507		var handleTouch = function (event) {
1508			var touches = event.changedTouches,
1509			    first = touches[0],
1510			    eventTypes = {
1511				touchstart: 'mousedown',
1512				touchmove: 'mousemove',
1513				touchend: 'mouseup'
1514			},
1515			    type = eventTypes[event.type],
1516			    simulatedEvent;
1517
1518			if ('MouseEvent' in window && typeof window.MouseEvent === 'function') {
1519				simulatedEvent = new window.MouseEvent(type, {
1520					'bubbles': true,
1521					'cancelable': true,
1522					'screenX': first.screenX,
1523					'screenY': first.screenY,
1524					'clientX': first.clientX,
1525					'clientY': first.clientY
1526				});
1527			} else {
1528				simulatedEvent = document.createEvent('MouseEvent');
1529				simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0 /*left*/, null);
1530			}
1531			first.target.dispatchEvent(simulatedEvent);
1532		};
1533	};
1534}(jQuery);
1535
1536//**********************************
1537//**From the jQuery Mobile Library**
1538//**need to recreate functionality**
1539//**and try to improve if possible**
1540//**********************************
1541
1542/* Removing the jQuery function ****
1543************************************
1544
1545(function( $, window, undefined ) {
1546
1547	var $document = $( document ),
1548		// supportTouch = $.mobile.support.touch,
1549		touchStartEvent = 'touchstart'//supportTouch ? "touchstart" : "mousedown",
1550		touchStopEvent = 'touchend'//supportTouch ? "touchend" : "mouseup",
1551		touchMoveEvent = 'touchmove'//supportTouch ? "touchmove" : "mousemove";
1552
1553	// setup new event shortcuts
1554	$.each( ( "touchstart touchmove touchend " +
1555		"swipe swipeleft swiperight" ).split( " " ), function( i, name ) {
1556
1557		$.fn[ name ] = function( fn ) {
1558			return fn ? this.bind( name, fn ) : this.trigger( name );
1559		};
1560
1561		// jQuery < 1.8
1562		if ( $.attrFn ) {
1563			$.attrFn[ name ] = true;
1564		}
1565	});
1566
1567	function triggerCustomEvent( obj, eventType, event, bubble ) {
1568		var originalType = event.type;
1569		event.type = eventType;
1570		if ( bubble ) {
1571			$.event.trigger( event, undefined, obj );
1572		} else {
1573			$.event.dispatch.call( obj, event );
1574		}
1575		event.type = originalType;
1576	}
1577
1578	// also handles taphold
1579
1580	// Also handles swipeleft, swiperight
1581	$.event.special.swipe = {
1582
1583		// More than this horizontal displacement, and we will suppress scrolling.
1584		scrollSupressionThreshold: 30,
1585
1586		// More time than this, and it isn't a swipe.
1587		durationThreshold: 1000,
1588
1589		// Swipe horizontal displacement must be more than this.
1590		horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,
1591
1592		// Swipe vertical displacement must be less than this.
1593		verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,
1594
1595		getLocation: function ( event ) {
1596			var winPageX = window.pageXOffset,
1597				winPageY = window.pageYOffset,
1598				x = event.clientX,
1599				y = event.clientY;
1600
1601			if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) ||
1602				event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) {
1603
1604				// iOS4 clientX/clientY have the value that should have been
1605				// in pageX/pageY. While pageX/page/ have the value 0
1606				x = x - winPageX;
1607				y = y - winPageY;
1608			} else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) {
1609
1610				// Some Android browsers have totally bogus values for clientX/Y
1611				// when scrolling/zooming a page. Detectable since clientX/clientY
1612				// should never be smaller than pageX/pageY minus page scroll
1613				x = event.pageX - winPageX;
1614				y = event.pageY - winPageY;
1615			}
1616
1617			return {
1618				x: x,
1619				y: y
1620			};
1621		},
1622
1623		start: function( event ) {
1624			var data = event.originalEvent.touches ?
1625					event.originalEvent.touches[ 0 ] : event,
1626				location = $.event.special.swipe.getLocation( data );
1627			return {
1628						time: ( new Date() ).getTime(),
1629						coords: [ location.x, location.y ],
1630						origin: $( event.target )
1631					};
1632		},
1633
1634		stop: function( event ) {
1635			var data = event.originalEvent.touches ?
1636					event.originalEvent.touches[ 0 ] : event,
1637				location = $.event.special.swipe.getLocation( data );
1638			return {
1639						time: ( new Date() ).getTime(),
1640						coords: [ location.x, location.y ]
1641					};
1642		},
1643
1644		handleSwipe: function( start, stop, thisObject, origTarget ) {
1645			if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
1646				Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
1647				Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
1648				var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight";
1649
1650				triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true );
1651				triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true );
1652				return true;
1653			}
1654			return false;
1655
1656		},
1657
1658		// This serves as a flag to ensure that at most one swipe event event is
1659		// in work at any given time
1660		eventInProgress: false,
1661
1662		setup: function() {
1663			var events,
1664				thisObject = this,
1665				$this = $( thisObject ),
1666				context = {};
1667
1668			// Retrieve the events data for this element and add the swipe context
1669			events = $.data( this, "mobile-events" );
1670			if ( !events ) {
1671				events = { length: 0 };
1672				$.data( this, "mobile-events", events );
1673			}
1674			events.length++;
1675			events.swipe = context;
1676
1677			context.start = function( event ) {
1678
1679				// Bail if we're already working on a swipe event
1680				if ( $.event.special.swipe.eventInProgress ) {
1681					return;
1682				}
1683				$.event.special.swipe.eventInProgress = true;
1684
1685				var stop,
1686					start = $.event.special.swipe.start( event ),
1687					origTarget = event.target,
1688					emitted = false;
1689
1690				context.move = function( event ) {
1691					if ( !start || event.isDefaultPrevented() ) {
1692						return;
1693					}
1694
1695					stop = $.event.special.swipe.stop( event );
1696					if ( !emitted ) {
1697						emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget );
1698						if ( emitted ) {
1699
1700							// Reset the context to make way for the next swipe event
1701							$.event.special.swipe.eventInProgress = false;
1702						}
1703					}
1704					// prevent scrolling
1705					if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
1706						event.preventDefault();
1707					}
1708				};
1709
1710				context.stop = function() {
1711						emitted = true;
1712
1713						// Reset the context to make way for the next swipe event
1714						$.event.special.swipe.eventInProgress = false;
1715						$document.off( touchMoveEvent, context.move );
1716						context.move = null;
1717				};
1718
1719				$document.on( touchMoveEvent, context.move )
1720					.one( touchStopEvent, context.stop );
1721			};
1722			$this.on( touchStartEvent, context.start );
1723		},
1724
1725		teardown: function() {
1726			var events, context;
1727
1728			events = $.data( this, "mobile-events" );
1729			if ( events ) {
1730				context = events.swipe;
1731				delete events.swipe;
1732				events.length--;
1733				if ( events.length === 0 ) {
1734					$.removeData( this, "mobile-events" );
1735				}
1736			}
1737
1738			if ( context ) {
1739				if ( context.start ) {
1740					$( this ).off( touchStartEvent, context.start );
1741				}
1742				if ( context.move ) {
1743					$document.off( touchMoveEvent, context.move );
1744				}
1745				if ( context.stop ) {
1746					$document.off( touchStopEvent, context.stop );
1747				}
1748			}
1749		}
1750	};
1751	$.each({
1752		swipeleft: "swipe.left",
1753		swiperight: "swipe.right"
1754	}, function( event, sourceEvent ) {
1755
1756		$.event.special[ event ] = {
1757			setup: function() {
1758				$( this ).bind( sourceEvent, $.noop );
1759			},
1760			teardown: function() {
1761				$( this ).unbind( sourceEvent );
1762			}
1763		};
1764	});
1765})( jQuery, this );
1766*/
1767'use strict';
1768
1769var _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; }; }();
1770
1771function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1772
1773!function ($) {
1774
1775  /**
1776   * Abide module.
1777   * @module foundation.abide
1778   */
1779
1780  var Abide = function () {
1781    /**
1782     * Creates a new instance of Abide.
1783     * @class
1784     * @fires Abide#init
1785     * @param {Object} element - jQuery object to add the trigger to.
1786     * @param {Object} options - Overrides to the default plugin settings.
1787     */
1788
1789    function Abide(element) {
1790      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
1791
1792      _classCallCheck(this, Abide);
1793
1794      this.$element = element;
1795      this.options = $.extend({}, Abide.defaults, this.$element.data(), options);
1796
1797      this._init();
1798
1799      Foundation.registerPlugin(this, 'Abide');
1800    }
1801
1802    /**
1803     * Initializes the Abide plugin and calls functions to get Abide functioning on load.
1804     * @private
1805     */
1806
1807
1808    _createClass(Abide, [{
1809      key: '_init',
1810      value: function _init() {
1811        this.$inputs = this.$element.find('input, textarea, select');
1812
1813        this._events();
1814      }
1815
1816      /**
1817       * Initializes events for Abide.
1818       * @private
1819       */
1820
1821    }, {
1822      key: '_events',
1823      value: function _events() {
1824        var _this2 = this;
1825
1826        this.$element.off('.abide').on('reset.zf.abide', function () {
1827          _this2.resetForm();
1828        }).on('submit.zf.abide', function () {
1829          return _this2.validateForm();
1830        });
1831
1832        if (this.options.validateOn === 'fieldChange') {
1833          this.$inputs.off('change.zf.abide').on('change.zf.abide', function (e) {
1834            _this2.validateInput($(e.target));
1835          });
1836        }
1837
1838        if (this.options.liveValidate) {
1839          this.$inputs.off('input.zf.abide').on('input.zf.abide', function (e) {
1840            _this2.validateInput($(e.target));
1841          });
1842        }
1843      }
1844
1845      /**
1846       * Calls necessary functions to update Abide upon DOM change
1847       * @private
1848       */
1849
1850    }, {
vendor: 4,857 bytes, lines 1851-2011
1851      key: '_reflow',
1852      value: function _reflow() {
1853        this._init();
1854      }
1855
1856      /**
1857       * Checks whether or not a form element has the required attribute and if it's checked or not
1858       * @param {Object} element - jQuery object to check for required attribute
1859       * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty
1860       */
1861
1862    }, {
1863      key: 'requiredCheck',
1864      value: function requiredCheck($el) {
1865        if (!$el.attr('required')) return true;
1866
1867        var isGood = true;
1868
1869        switch ($el[0].type) {
1870          case 'checkbox':
1871            isGood = $el[0].checked;
1872            break;
1873
1874          case 'select':
1875          case 'select-one':
1876          case 'select-multiple':
1877            var opt = $el.find('option:selected');
1878            if (!opt.length || !opt.val()) isGood = false;
1879            break;
1880
1881          default:
1882            if (!$el.val() || !$el.val().length) isGood = false;
1883        }
1884
1885        return isGood;
1886      }
1887
1888      /**
1889       * Based on $el, get the first element with selector in this order:
1890       * 1. The element's direct sibling('s).
1891       * 3. The element's parent's children.
1892       *
1893       * This allows for multiple form errors per input, though if none are found, no form errors will be shown.
1894       *
1895       * @param {Object} $el - jQuery object to use as reference to find the form error selector.
1896       * @returns {Object} jQuery object with the selector.
1897       */
1898
1899    }, {
1900      key: 'findFormError',
1901      value: function findFormError($el) {
1902        var $error = $el.siblings(this.options.formErrorSelector);
1903
1904        if (!$error.length) {
1905          $error = $el.parent().find(this.options.formErrorSelector);
1906        }
1907
1908        return $error;
1909      }
1910
1911      /**
1912       * Get the first element in this order:
1913       * 2. The <label> with the attribute `[for="someInputId"]`
1914       * 3. The `.closest()` <label>
1915       *
1916       * @param {Object} $el - jQuery object to check for required attribute
1917       * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty
1918       */
1919
1920    }, {
1921      key: 'findLabel',
1922      value: function findLabel($el) {
1923        var id = $el[0].id;
1924        var $label = this.$element.find('label[for="' + id + '"]');
1925
1926        if (!$label.length) {
1927          return $el.closest('label');
1928        }
1929
1930        return $label;
1931      }
1932
1933      /**
1934       * Get the set of labels associated with a set of radio els in this order
1935       * 2. The <label> with the attribute `[for="someInputId"]`
1936       * 3. The `.closest()` <label>
1937       *
1938       * @param {Object} $el - jQuery object to check for required attribute
1939       * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty
1940       */
1941
1942    }, {
1943      key: 'findRadioLabels',
1944      value: function findRadioLabels($els) {
1945        var _this3 = this;
1946
1947        var labels = $els.map(function (i, el) {
1948          var id = el.id;
1949          var $label = _this3.$element.find('label[for="' + id + '"]');
1950
1951          if (!$label.length) {
1952            $label = $(el).closest('label');
1953          }
1954          return $label[0];
1955        });
1956
1957        return $(labels);
1958      }
1959
1960      /**
1961       * Adds the CSS error class as specified by the Abide settings to the label, input, and the form
1962       * @param {Object} $el - jQuery object to add the class to
1963       */
1964
1965    }, {
1966      key: 'addErrorClasses',
1967      value: function addErrorClasses($el) {
1968        var $label = this.findLabel($el);
1969        var $formError = this.findFormError($el);
1970
1971        if ($label.length) {
1972          $label.addClass(this.options.labelErrorClass);
1973        }
1974
1975        if ($formError.length) {
1976          $formError.addClass(this.options.formErrorClass);
1977        }
1978
1979        $el.addClass(this.options.inputErrorClass).attr('data-invalid', '');
1980      }
1981
1982      /**
1983       * Remove CSS error classes etc from an entire radio button group
1984       * @param {String} groupName - A string that specifies the name of a radio button group
1985       *
1986       */
1987
1988    }, {
1989      key: 'removeRadioErrorClasses',
1990      value: function removeRadioErrorClasses(groupName) {
1991        var $els = this.$element.find(':radio[name="' + groupName + '"]');
1992        var $labels = this.findRadioLabels($els);
1993        var $formErrors = this.findFormError($els);
1994
1995        if ($labels.length) {
1996          $labels.removeClass(this.options.labelErrorClass);
1997        }
1998
1999        if ($formErrors.length) {
2000          $formErrors.removeClass(this.options.formErrorClass);
2001        }
2002
2003        $els.removeClass(this.options.inputErrorClass).removeAttr('data-invalid');
2004      }
2005
2006      /**
2007       * Removes CSS error class as specified by the Abide settings from the label, input, and the form
2008       * @param {Object} $el - jQuery object to remove the class from
2009       */
2010
2011    }, {
2012      key: 'removeErrorClasses',
2013      value: function removeErrorClasses($el) {
2014        // radios need to clear all of the els
2015        if ($el[0].type == 'radio') {
2016          return this.removeRadioErrorClasses($el.attr('name'));
2017        }
2018
2019        var $label = this.findLabel($el);
2020        var $formError = this.findFormError($el);
2021
2022        if ($label.length) {
2023          $label.removeClass(this.options.labelErrorClass);
2024        }
2025
2026        if ($formError.length) {
2027          $formError.removeClass(this.options.formErrorClass);
2028        }
2029
2030        $el.removeClass(this.options.inputErrorClass).removeAttr('data-invalid');
2031      }
2032
2033      /**
2034       * Goes through a form to find inputs and proceeds to validate them in ways specific to their type
2035       * @fires Abide#invalid
2036       * @fires Abide#valid
2037       * @param {Object} element - jQuery object to validate, should be an HTML input
2038       * @returns {Boolean} goodToGo - If the input is valid or not.
2039       */
2040
2041    }, {
2042      key: 'validateInput',
2043      value: function validateInput($el) {
2044        var clearRequire = this.requiredCheck($el),
2045            validated = false,
2046            customValidator = true,
2047            validator = $el.attr('data-validator'),
2048            equalTo = true;
2049
2050        // don't validate ignored inputs or hidden inputs
2051        if ($el.is('[data-abide-ignore]') || $el.is('[type="hidden"]')) {
2052          return true;
2053        }
2054
2055        switch ($el[0].type) {
2056          case 'radio':
2057            validated = this.validateRadio($el.attr('name'));
2058            break;
2059
2060          case 'checkbox':
2061            validated = clearRequire;
2062            break;
2063
2064          case 'select':
2065          case 'select-one':
2066          case 'select-multiple':
2067            validated = clearRequire;
2068            break;
2069
2070          default:
2071            validated = this.validateText($el);
2072        }
2073
2074        if (validator) {
2075          customValidator = this.matchValidation($el, validator, $el.attr('required'));
2076        }
2077
2078        if ($el.attr('data-equalto')) {
2079          equalTo = this.options.validators.equalTo($el);
2080        }
2081
2082        var goodToGo = [clearRequire, validated, customValidator, equalTo].indexOf(false) === -1;
2083        var message = (goodToGo ? 'valid' : 'invalid') + '.zf.abide';
2084
2085        this[goodToGo ? 'removeErrorClasses' : 'addErrorClasses']($el);
2086
2087        /**
2088         * Fires when the input is done checking for validation. Event trigger is either `valid.zf.abide` or `invalid.zf.abide`
2089         * Trigger includes the DOM element of the input.
2090         * @event Abide#valid
2091         * @event Abide#invalid
2092         */
2093        $el.trigger(message, [$el]);
2094
2095        return goodToGo;
2096      }
2097
2098      /**
2099       * Goes through a form and if there are any invalid inputs, it will display the form error element
2100       * @returns {Boolean} noError - true if no errors were detected...
2101       * @fires Abide#formvalid
2102       * @fires Abide#forminvalid
2103       */
2104
2105    }, {
2106      key: 'validateForm',
2107      value: function validateForm() {
2108        var acc = [];
2109        var _this = this;
2110
2111        this.$inputs.each(function () {
2112          acc.push(_this.validateInput($(this)));
2113        });
2114
2115        var noError = acc.indexOf(false) === -1;
2116
2117        this.$element.find('[data-abide-error]').css('display', noError ? 'none' : 'block');
2118
2119        /**
2120         * Fires when the form is finished validating. Event trigger is either `formvalid.zf.abide` or `forminvalid.zf.abide`.
2121         * Trigger includes the element of the form.
2122         * @event Abide#formvalid
2123         * @event Abide#forminvalid
2124         */
2125        this.$element.trigger((noError ? 'formvalid' : 'forminvalid') + '.zf.abide', [this.$element]);
2126
2127        return noError;
2128      }
2129
2130      /**
2131       * Determines whether or a not a text input is valid based on the pattern specified in the attribute. If no matching pattern is found, returns true.
2132       * @param {Object} $el - jQuery object to validate, should be a text input HTML element
2133       * @param {String} pattern - string value of one of the RegEx patterns in Abide.options.patterns
2134       * @returns {Boolean} Boolean value depends on whether or not the input value matches the pattern specified
2135       */
2136
2137    }, {
2138      key: 'validateText',
2139      value: function validateText($el, pattern) {
2140        // A pattern can be passed to this function, or it will be infered from the input's "pattern" attribute, or it's "type" attribute
2141        pattern = pattern || $el.attr('pattern') || $el.attr('type');
2142        var inputText = $el.val();
2143        var valid = false;
2144
2145        if (inputText.length) {
2146          // If the pattern attribute on the element is in Abide's list of patterns, then test that regexp
2147          if (this.options.patterns.hasOwnProperty(pattern)) {
2148            valid = this.options.patterns[pattern].test(inputText);
2149          }
2150          // If the pattern name isn't also the type attribute of the field, then test it as a regexp
2151          else if (pattern !== $el.attr('type')) {
2152              valid = new RegExp(pattern).test(inputText);
2153            } else {
2154              valid = true;
2155            }
2156        }
2157        // An empty field is valid if it's not required
2158        else if (!$el.prop('required')) {
2159            valid = true;
2160          }
2161
2162        return valid;
2163      }
2164
2165      /**
2166       * Determines whether or a not a radio input is valid based on whether or not it is required and selected. Although the function targets a single `<input>`, it validates by checking the `required` and `checked` properties of all radio buttons in its group.
2167       * @param {String} groupName - A string that specifies the name of a radio button group
2168       * @returns {Boolean} Boolean value depends on whether or not at least one radio input has been selected (if it's required)
2169       */
2170
2171    }, {
2172      key: 'validateRadio',
2173      value: function validateRadio(groupName) {
2174        // If at least one radio in the group has the `required` attribute, the group is considered required
2175        // Per W3C spec, all radio buttons in a group should have `required`, but we're being nice
2176        var $group = this.$element.find(':radio[name="' + groupName + '"]');
2177        var valid = false,
2178            required = false;
2179
2180        // For the group to be required, at least one radio needs to be required
2181        $group.each(function (i, e) {
2182          if ($(e).attr('required')) {
2183            required = true;
2184          }
2185        });
2186        if (!required) valid = true;
2187
2188        if (!valid) {
2189          // For the group to be valid, at least one radio needs to be checked
2190          $group.each(function (i, e) {
2191            if ($(e).prop('checked')) {
2192              valid = true;
2193            }
2194          });
2195        };
2196
2197        return valid;
2198      }
2199
2200      /**
2201       * Determines if a selected input passes a custom validation function. Multiple validations can be used, if passed to the element with `data-validator="foo bar baz"` in a space separated listed.
2202       * @param {Object} $el - jQuery input element.
2203       * @param {String} validators - a string of function names matching functions in the Abide.options.validators object.
2204       * @param {Boolean} required - self explanatory?
2205       * @returns {Boolean} - true if validations passed.
2206       */
2207
2208    }, {
2209      key: 'matchValidation',
2210      value: function matchValidation($el, validators, required) {
2211        var _this4 = this;
2212
2213        required = required ? true : false;
2214
2215        var clear = validators.split(' ').map(function (v) {
2216          return _this4.options.validators[v]($el, required, $el.parent());
2217        });
2218        return clear.indexOf(false) === -1;
2219      }
2220
2221      /**
2222       * Resets form inputs and styles
2223       * @fires Abide#formreset
2224       */
2225
2226    }, {
2227      key: 'resetForm',
2228      value: function resetForm() {
2229        var $form = this.$element,
2230            opts = this.options;
2231
2232        $('.' + opts.labelErrorClass, $form).not('small').removeClass(opts.labelErrorClass);
2233        $('.' + opts.inputErrorClass, $form).not('small').removeClass(opts.inputErrorClass);
2234        $(opts.formErrorSelector + '.' + opts.formErrorClass).removeClass(opts.formErrorClass);
2235        $form.find('[data-abide-error]').css('display', 'none');
2236        $(':input', $form).not(':button, :submit, :reset, :hidden, :radio, :checkbox, [data-abide-ignore]').val('').removeAttr('data-invalid');
2237        $(':input:radio', $form).not('[data-abide-ignore]').prop('checked', false).removeAttr('data-invalid');
2238        $(':input:checkbox', $form).not('[data-abide-ignore]').prop('checked', false).removeAttr('data-invalid');
2239        /**
2240         * Fires when the form has been reset.
2241         * @event Abide#formreset
2242         */
2243        $form.trigger('formreset.zf.abide', [$form]);
2244      }
2245
2246      /**
2247       * Destroys an instance of Abide.
2248       * Removes error styles and classes from elements, without resetting their values.
2249       */
2250
2251    }, {
2252      key: 'destroy',
2253      value: function destroy() {
2254        var _this = this;
2255        this.$element.off('.abide').find('[data-abide-error]').css('display', 'none');
2256
2257        this.$inputs.off('.abide').each(function () {
2258          _this.removeErrorClasses($(this));
2259        });
2260
2261        Foundation.unregisterPlugin(this);
2262      }
2263    }]);
2264
2265    return Abide;
2266  }();
2267
2268  /**
2269   * Default settings for plugin
2270   */
2271
2272
2273  Abide.defaults = {
2274    /**
2275     * The default event to validate inputs. Checkboxes and radios validate immediately.
2276     * Remove or change this value for manual validation.
2277     * @option
2278     * @example 'fieldChange'
2279     */
2280    validateOn: 'fieldChange',
2281
2282    /**
2283     * Class to be applied to input labels on failed validation.
2284     * @option
2285     * @example 'is-invalid-label'
2286     */
2287    labelErrorClass: 'is-invalid-label',
2288
2289    /**
2290     * Class to be applied to inputs on failed validation.
2291     * @option
2292     * @example 'is-invalid-input'
2293     */
2294    inputErrorClass: 'is-invalid-input',
2295
2296    /**
2297     * Class selector to use to target Form Errors for show/hide.
2298     * @option
2299     * @example '.form-error'
2300     */
2301    formErrorSelector: '.form-error',
2302
2303    /**
2304     * Class added to Form Errors on failed validation.
2305     * @option
2306     * @example 'is-visible'
2307     */
2308    formErrorClass: 'is-visible',
2309
2310    /**
2311     * Set to true to validate text inputs on any value change.
2312     * @option
2313     * @example false
2314     */
2315    liveValidate: false,
2316
2317    patterns: {
2318      alpha: /^[a-zA-Z]+$/,
2319      alpha_numeric: /^[a-zA-Z0-9]+$/,
2320      integer: /^[-+]?\d+$/,
2321      number: /^[-+]?\d*(?:[\.\,]\d+)?$/,
2322
2323      // amex, visa, diners
2324      card: /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
2325      cvv: /^([0-9]){3,4}$/,
2326
2327      // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
2328      email: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,
2329
2330      url: /^(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/,
2331      // abc.de
2332      domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/,
2333
2334      datetime: /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/,
2335      // YYYY-MM-DD
2336      date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/,
2337      // HH:MM:SS
2338      time: /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/,
2339      dateISO: /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/,
2340      // MM/DD/YYYY
2341      month_day_year: /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/,
2342      // DD/MM/YYYY
2343      day_month_year: /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/,
2344
2345      // #FFF or #FFFFFF
2346      color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
2347    },
2348
2349    /**
2350     * Optional validation functions to be used. `equalTo` being the only default included function.
2351     * Functions should return only a boolean if the input is valid or not. Functions are given the following arguments:
2352     * el : The jQuery element to validate.
2353     * required : Boolean value of the required attribute be present or not.
2354     * parent : The direct parent of the input.
2355     * @option
2356     */
2357    validators: {
2358      equalTo: function (el, required, parent) {
2359        return $('#' + el.attr('data-equalto')).val() === el.val();
2360      }
2361    }
2362  };
2363
2364  // Window exports
2365  Foundation.plugin(Abide, 'Abide');
2366}(jQuery);
2367'use strict';
2368
2369var _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; }; }();
2370
2371function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2372
2373!function ($) {
2374
2375  /**
2376   * Accordion module.
2377   * @module foundation.accordion
2378   * @requires foundation.util.keyboard
2379   * @requires foundation.util.motion
2380   */
2381
2382  var Accordion = function () {
2383    /**
2384     * Creates a new instance of an accordion.
2385     * @class
2386     * @fires Accordion#init
2387     * @param {jQuery} element - jQuery object to make into an accordion.
2388     * @param {Object} options - a plain object with settings to override the default options.
2389     */
2390
2391    function Accordion(element, options) {
2392      _classCallCheck(this, Accordion);
2393
2394      this.$element = element;
2395      this.options = $.extend({}, Accordion.defaults, this.$element.data(), options);
2396
2397      this._init();
2398
2399      Foundation.registerPlugin(this, 'Accordion');
2400      Foundation.Keyboard.register('Accordion', {
2401        'ENTER': 'toggle',
2402        'SPACE': 'toggle',
2403        'ARROW_DOWN': 'next',
2404        'ARROW_UP': 'previous'
2405      });
2406    }
2407
2408    /**
2409     * Initializes the accordion by animating the preset active pane(s).
2410     * @private
2411     */
2412
2413
2414    _createClass(Accordion, [{
2415      key: '_init',
2416      value: function _init() {
2417        this.$element.attr('role', 'tablist');
2418        this.$tabs = this.$element.children('li, [data-accordion-item]');
2419
2420        this.$tabs.each(function (idx, el) {
2421          var $el = $(el),
2422              $content = $el.children('[data-tab-content]'),
2423              id = $content[0].id || Foundation.GetYoDigits(6, 'accordion'),
2424              linkId = el.id || id + '-label';
2425
2426          $el.find('a:first').attr({
2427            'aria-controls': id,
2428            'role': 'tab',
2429            'id': linkId,
2430            'aria-expanded': false,
2431            'aria-selected': false
2432          });
2433
2434          $content.attr({ 'role': 'tabpanel', 'aria-labelledby': linkId, 'aria-hidden': true, 'id': id });
2435        });
2436        var $initActive = this.$element.find('.is-active').children('[data-tab-content]');
2437        if ($initActive.length) {
2438          this.down($initActive, true);
2439        }
2440        this._events();
2441      }
2442
2443      /**
2444       * Adds event handlers for items within the accordion.
2445       * @private
2446       */
2447
2448    }, {
2449      key: '_events',
2450      value: function _events() {
2451        var _this = this;
2452
2453        this.$tabs.each(function () {
2454          var $elem = $(this);
2455          var $tabContent = $elem.children('[data-tab-content]');
2456          if ($tabContent.length) {
2457            $elem.children('a').off('click.zf.accordion keydown.zf.accordion').on('click.zf.accordion', function (e) {
2458              // $(this).children('a').on('click.zf.accordion', function(e) {
2459              e.preventDefault();
2460              if ($elem.hasClass('is-active')) {
2461                if (_this.options.allowAllClosed || $elem.siblings().hasClass('is-active')) {
2462                  _this.up($tabContent);
2463                }
2464              } else {
2465                _this.down($tabContent);
2466              }
2467            }).on('keydown.zf.accordion', function (e) {
2468              Foundation.Keyboard.handleKey(e, 'Accordion', {
2469                toggle: function () {
2470                  _this.toggle($tabContent);
2471                },
2472                next: function () {
2473                  var $a = $elem.next().find('a').focus();
2474                  if (!_this.options.multiExpand) {
2475                    $a.trigger('click.zf.accordion');
2476                  }
2477                },
2478                previous: function () {
2479                  var $a = $elem.prev().find('a').focus();
2480                  if (!_this.options.multiExpand) {
2481                    $a.trigger('click.zf.accordion');
2482                  }
2483                },
2484                handled: function () {
2485                  e.preventDefault();
2486                  e.stopPropagation();
2487                }
2488              });
2489            });
2490          }
2491        });
2492      }
2493
2494      /**
2495       * Toggles the selected content pane's open/close state.
2496       * @param {jQuery} $target - jQuery object of the pane to toggle.
2497       * @function
2498       */
2499
2500    }, {
2501      key: 'toggle',
2502      value: function toggle($target) {
2503        if ($target.parent().hasClass('is-active')) {
2504          if (this.options.allowAllClosed || $target.parent().siblings().hasClass('is-active')) {
2505            this.up($target);
2506          } else {
2507            return;
2508          }
2509        } else {
2510          this.down($target);
2511        }
2512      }
2513
2514      /**
2515       * Opens the accordion tab defined by `$target`.
2516       * @param {jQuery} $target - Accordion pane to open.
2517       * @param {Boolean} firstTime - flag to determine if reflow should happen.
2518       * @fires Accordion#down
2519       * @function
2520       */
2521
2522    }, {
2523      key: 'down',
2524      value: function down($target, firstTime) {
2525        var _this2 = this;
2526
2527        if (!this.options.multiExpand && !firstTime) {
2528          var $currentActive = this.$element.children('.is-active').children('[data-tab-content]');
2529          if ($currentActive.length) {
2530            this.up($currentActive);
2531          }
2532        }
2533
2534        $target.attr('aria-hidden', false).parent('[data-tab-content]').addBack().parent().addClass('is-active');
2535
2536        $target.slideDown(this.options.slideSpeed, function () {
2537          /**
2538           * Fires when the tab is done opening.
2539           * @event Accordion#down
2540           */
2541          _this2.$element.trigger('down.zf.accordion', [$target]);
2542        });
2543
2544        $('#' + $target.attr('aria-labelledby')).attr({
2545          'aria-expanded': true,
2546          'aria-selected': true
2547        });
2548      }
2549
2550      /**
2551       * Closes the tab defined by `$target`.
2552       * @param {jQuery} $target - Accordion tab to close.
2553       * @fires Accordion#up
2554       * @function
2555       */
2556
2557    }, {
2558      key: 'up',
2559      value: function up($target) {
2560        var $aunts = $target.parent().siblings(),
2561            _this = this;
2562        var canClose = this.options.multiExpand ? $aunts.hasClass('is-active') : $target.parent().hasClass('is-active');
2563
2564        if (!this.options.allowAllClosed && !canClose) {
2565          return;
2566        }
2567
2568        // Foundation.Move(this.options.slideSpeed, $target, function(){
2569        $target.slideUp(_this.options.slideSpeed, function () {
2570          /**
2571           * Fires when the tab is done collapsing up.
2572           * @event Accordion#up
2573           */
2574          _this.$element.trigger('up.zf.accordion', [$target]);
2575        });
2576        // });
2577
2578        $target.attr('aria-hidden', true).parent().removeClass('is-active');
2579
2580        $('#' + $target.attr('aria-labelledby')).attr({
2581          'aria-expanded': false,
2582          'aria-selected': false
2583        });
2584      }
2585
2586      /**
2587       * Destroys an instance of an accordion.
2588       * @fires Accordion#destroyed
2589       * @function
2590       */
2591
2592    }, {
2593      key: 'destroy',
2594      value: function destroy() {
2595        this.$element.find('[data-tab-content]').stop(true).slideUp(0).css('display', '');
2596        this.$element.find('a').off('.zf.accordion');
2597
2598        Foundation.unregisterPlugin(this);
2599      }
2600    }]);
2601
2602    return Accordion;
2603  }();
2604
2605  Accordion.defaults = {
2606    /**
2607     * Amount of time to animate the opening of an accordion pane.
2608     * @option
2609     * @example 250
2610     */
2611    slideSpeed: 250,
2612    /**
2613     * Allow the accordion to have multiple open panes.
2614     * @option
2615     * @example false
2616     */
2617    multiExpand: false,
2618    /**
2619     * Allow the accordion to close all panes.
2620     * @option
2621     * @example false
2622     */
2623    allowAllClosed: false
2624  };
2625
2626  // Window exports
2627  Foundation.plugin(Accordion, 'Accordion');
2628}(jQuery);
2629'use strict';
2630
2631var _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; }; }();
2632
2633function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2634
2635!function ($) {
2636
2637  /**
2638   * AccordionMenu module.
2639   * @module foundation.accordionMenu
2640   * @requires foundation.util.keyboard
2641   * @requires foundation.util.motion
2642   * @requires foundation.util.nest
2643   */
2644
2645  var AccordionMenu = function () {
2646    /**
2647     * Creates a new instance of an accordion menu.
2648     * @class
2649     * @fires AccordionMenu#init
2650     * @param {jQuery} element - jQuery object to make into an accordion menu.
2651     * @param {Object} options - Overrides to the default plugin settings.
2652     */
2653
2654    function AccordionMenu(element, options) {
2655      _classCallCheck(this, AccordionMenu);
2656
2657      this.$element = element;
2658      this.options = $.extend({}, AccordionMenu.defaults, this.$element.data(), options);
2659
2660      Foundation.Nest.Feather(this.$element, 'accordion');
2661
2662      this._init();
2663
2664      Foundation.registerPlugin(this, 'AccordionMenu');
2665      Foundation.Keyboard.register('AccordionMenu', {
2666        'ENTER': 'toggle',
2667        'SPACE': 'toggle',
2668        'ARROW_RIGHT': 'open',
2669        'ARROW_UP': 'up',
2670        'ARROW_DOWN': 'down',
2671        'ARROW_LEFT': 'close',
2672        'ESCAPE': 'closeAll',
2673        'TAB': 'down',
2674        'SHIFT_TAB': 'up'
2675      });
2676    }
2677
2678    /**
2679     * Initializes the accordion menu by hiding all nested menus.
2680     * @private
2681     */
2682
2683
2684    _createClass(AccordionMenu, [{
2685      key: '_init',
2686      value: function _init() {
2687        this.$element.find('[data-submenu]').not('.is-active').slideUp(0); //.find('a').css('padding-left', '1rem');
2688        this.$element.attr({
2689          'role': 'tablist',
2690          'aria-multiselectable': this.options.multiOpen
2691        });
2692
2693        this.$menuLinks = this.$element.find('.is-accordion-submenu-parent');
2694        this.$menuLinks.each(function () {
2695          var linkId = this.id || Foundation.GetYoDigits(6, 'acc-menu-link'),
2696              $elem = $(this),
2697              $sub = $elem.children('[data-submenu]'),
2698              subId = $sub[0].id || Foundation.GetYoDigits(6, 'acc-menu'),
2699              isActive = $sub.hasClass('is-active');
2700          $elem.attr({
2701            'aria-controls': subId,
2702            'aria-expanded': isActive,
2703            'role': 'tab',
2704            'id': linkId
2705          });
2706          $sub.attr({
2707            'aria-labelledby': linkId,
2708            'aria-hidden': !isActive,
2709            'role': 'tabpanel',
2710            'id': subId
2711          });
2712        });
2713        var initPanes = this.$element.find('.is-active');
2714        if (initPanes.length) {
2715          var _this = this;
2716          initPanes.each(function () {
2717            _this.down($(this));
2718          });
2719        }
2720        this._events();
2721      }
2722
2723      /**
2724       * Adds event handlers for items within the menu.
2725       * @private
2726       */
2727
2728    }, {
2729      key: '_events',
2730      value: function _events() {
2731        var _this = this;
2732
2733        this.$element.find('li').each(function () {
2734          var $submenu = $(this).children('[data-submenu]');
2735
2736          if ($submenu.length) {
2737            $(this).children('a').off('click.zf.accordionMenu').on('click.zf.accordionMenu', function (e) {
2738              e.preventDefault();
2739
2740              _this.toggle($submenu);
2741            });
2742          }
2743        }).on('keydown.zf.accordionmenu', function (e) {
2744          var $element = $(this),
2745              $elements = $element.parent('ul').children('li'),
2746              $prevElement,
2747              $nextElement,
2748              $target = $element.children('[data-submenu]');
2749
2750          $elements.each(function (i) {
2751            if ($(this).is($element)) {
2752              $prevElement = $elements.eq(Math.max(0, i - 1)).find('a').first();
2753              $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1)).find('a').first();
2754
2755              if ($(this).children('[data-submenu]:visible').length) {
2756                // has open sub menu
2757                $nextElement = $element.find('li:first-child').find('a').first();
2758              }
2759              if ($(this).is(':first-child')) {
2760                // is first element of sub menu
2761                $prevElement = $element.parents('li').first().find('a').first();
2762              } else if ($prevElement.children('[data-submenu]:visible').length) {
2763                // if previous element has open sub menu
2764                $prevElement = $prevElement.find('li:last-child').find('a').first();
2765              }
2766              if ($(this).is(':last-child')) {
2767                // is last element of sub menu
2768                $nextElement = $element.parents('li').first().next('li').find('a').first();
2769              }
2770
2771              return;
2772            }
2773          });
2774          Foundation.Keyboard.handleKey(e, 'AccordionMenu', {
2775            open: function () {
2776              if ($target.is(':hidden')) {
2777                _this.down($target);
2778                $target.find('li').first().find('a').first().focus();
2779              }
2780            },
2781            close: function () {
2782              if ($target.length && !$target.is(':hidden')) {
2783                // close active sub of this item
2784                _this.up($target);
2785              } else if ($element.parent('[data-submenu]').length) {
2786                // close currently open sub
2787                _this.up($element.parent('[data-submenu]'));
2788                $element.parents('li').first().find('a').first().focus();
2789              }
2790            },
2791            up: function () {
2792              $prevElement.attr('tabindex', -1).focus();
2793              return true;
2794            },
2795            down: function () {
2796              $nextElement.attr('tabindex', -1).focus();
2797              return true;
2798            },
2799            toggle: function () {
2800              if ($element.children('[data-submenu]').length) {
2801                _this.toggle($element.children('[data-submenu]'));
2802              }
2803            },
2804            closeAll: function () {
2805              _this.hideAll();
2806            },
2807            handled: function (preventDefault) {
2808              if (preventDefault) {
2809                e.preventDefault();
2810              }
2811              e.stopImmediatePropagation();
2812            }
2813          });
2814        }); //.attr('tabindex', 0);
2815      }
2816
2817      /**
2818       * Closes all panes of the menu.
2819       * @function
2820       */
2821
2822    }, {
2823      key: 'hideAll',
2824      value: function hideAll() {
2825        this.$element.find('[data-submenu]').slideUp(this.options.slideSpeed);
2826      }
2827
2828      /**
2829       * Toggles the open/close state of a submenu.
2830       * @function
2831       * @param {jQuery} $target - the submenu to toggle
2832       */
2833
2834    }, {
2835      key: 'toggle',
2836      value: function toggle($target) {
2837        if (!$target.is(':animated')) {
2838          if (!$target.is(':hidden')) {
2839            this.up($target);
2840          } else {
2841            this.down($target);
2842          }
2843        }
2844      }
2845
2846      /**
2847       * Opens the sub-menu defined by `$target`.
2848       * @param {jQuery} $target - Sub-menu to open.
2849       * @fires AccordionMenu#down
2850       */
2851
2852    }, {
2853      key: 'down',
2854      value: function down($target) {
2855        var _this = this;
2856
2857        if (!this.options.multiOpen) {
2858          this.up(this.$element.find('.is-active').not($target.parentsUntil(this.$element).add($target)));
2859        }
2860
2861        $target.addClass('is-active').attr({ 'aria-hidden': false }).parent('.is-accordion-submenu-parent').attr({ 'aria-expanded': true });
2862
2863        //Foundation.Move(this.options.slideSpeed, $target, function() {
2864        $target.slideDown(_this.options.slideSpeed, function () {
2865          /**
2866           * Fires when the menu is done opening.
2867           * @event AccordionMenu#down
2868           */
2869          _this.$element.trigger('down.zf.accordionMenu', [$target]);
2870        });
2871        //});
2872      }
2873
2874      /**
2875       * Closes the sub-menu defined by `$target`. All sub-menus inside the target will be closed as well.
2876       * @param {jQuery} $target - Sub-menu to close.
2877       * @fires AccordionMenu#up
2878       */
2879
2880    }, {
2881      key: 'up',
2882      value: function up($target) {
2883        var _this = this;
2884        //Foundation.Move(this.options.slideSpeed, $target, function(){
2885        $target.slideUp(_this.options.slideSpeed, function () {
2886          /**
2887           * Fires when the menu is done collapsing up.
2888           * @event AccordionMenu#up
2889           */
2890          _this.$element.trigger('up.zf.accordionMenu', [$target]);
2891        });
2892        //});
2893
2894        var $menus = $target.find('[data-submenu]').slideUp(0).addBack().attr('aria-hidden', true);
2895
2896        $menus.parent('.is-accordion-submenu-parent').attr('aria-expanded', false);
2897      }
2898
2899      /**
2900       * Destroys an instance of accordion menu.
2901       * @fires AccordionMenu#destroyed
2902       */
2903
2904    }, {
2905      key: 'destroy',
2906      value: function destroy() {
2907        this.$element.find('[data-submenu]').slideDown(0).css('display', '');
2908        this.$element.find('a').off('click.zf.accordionMenu');
2909
2910        Foundation.Nest.Burn(this.$element, 'accordion');
2911        Foundation.unregisterPlugin(this);
2912      }
2913    }]);
2914
2915    return AccordionMenu;
2916  }();
2917
2918  AccordionMenu.defaults = {
2919    /**
2920     * Amount of time to animate the opening of a submenu in ms.
2921     * @option
2922     * @example 250
2923     */
2924    slideSpeed: 250,
2925    /**
2926     * Allow the menu to have multiple open panes.
2927     * @option
2928     * @example true
2929     */
2930    multiOpen: true
2931  };
2932
2933  // Window exports
2934  Foundation.plugin(AccordionMenu, 'AccordionMenu');
2935}(jQuery);
2936'use strict';
2937
2938var _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; }; }();
2939
2940function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2941
2942!function ($) {
2943
2944  /**
2945   * Drilldown module.
2946   * @module foundation.drilldown
2947   * @requires foundation.util.keyboard
2948   * @requires foundation.util.motion
2949   * @requires foundation.util.nest
2950   */
2951
2952  var Drilldown = function () {
2953    /**
2954     * Creates a new instance of a drilldown menu.
2955     * @class
2956     * @param {jQuery} element - jQuery object to make into an accordion menu.
2957     * @param {Object} options - Overrides to the default plugin settings.
2958     */
2959
2960    function Drilldown(element, options) {
2961      _classCallCheck(this, Drilldown);
2962
2963      this.$element = element;
2964      this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);
2965
2966      Foundation.Nest.Feather(this.$element, 'drilldown');
2967
2968      this._init();
2969
2970      Foundation.registerPlugin(this, 'Drilldown');
2971      Foundation.Keyboard.register('Drilldown', {
2972        'ENTER': 'open',
2973        'SPACE': 'open',
vendor: 6,806 bytes, lines 2974-3171
2974        'ARROW_RIGHT': 'next',
2975        'ARROW_UP': 'up',
2976        'ARROW_DOWN': 'down',
2977        'ARROW_LEFT': 'previous',
2978        'ESCAPE': 'close',
2979        'TAB': 'down',
2980        'SHIFT_TAB': 'up'
2981      });
2982    }
2983
2984    /**
2985     * Initializes the drilldown by creating jQuery collections of elements
2986     * @private
2987     */
2988
2989
2990    _createClass(Drilldown, [{
2991      key: '_init',
2992      value: function _init() {
2993        this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
2994        this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]');
2995        this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem').find('a');
2996
2997        this._prepareMenu();
2998
2999        this._keyboardEvents();
3000      }
3001
3002      /**
3003       * prepares drilldown menu by setting attributes to links and elements
3004       * sets a min height to prevent content jumping
3005       * wraps the element if not already wrapped
3006       * @private
3007       * @function
3008       */
3009
3010    }, {
3011      key: '_prepareMenu',
3012      value: function _prepareMenu() {
3013        var _this = this;
3014        // if(!this.options.holdOpen){
3015        //   this._menuLinkEvents();
3016        // }
3017        this.$submenuAnchors.each(function () {
3018          var $link = $(this);
3019          var $sub = $link.parent();
3020          if (_this.options.parentLink) {
3021            $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>');
3022          }
3023          $link.data('savedHref', $link.attr('href')).removeAttr('href');
3024          $link.children('[data-submenu]').attr({
3025            'aria-hidden': true,
3026            'tabindex': 0,
3027            'role': 'menu'
3028          });
3029          _this._events($link);
3030        });
3031        this.$submenus.each(function () {
3032          var $menu = $(this),
3033              $back = $menu.find('.js-drilldown-back');
3034          if (!$back.length) {
3035            $menu.prepend(_this.options.backButton);
3036          }
3037          _this._back($menu);
3038        });
3039        if (!this.$element.parent().hasClass('is-drilldown')) {
3040          this.$wrapper = $(this.options.wrapper).addClass('is-drilldown');
3041          this.$wrapper = this.$element.wrap(this.$wrapper).parent().css(this._getMaxDims());
3042        }
3043      }
3044
3045      /**
3046       * Adds event handlers to elements in the menu.
3047       * @function
3048       * @private
3049       * @param {jQuery} $elem - the current menu item to add handlers to.
3050       */
3051
3052    }, {
3053      key: '_events',
3054      value: function _events($elem) {
3055        var _this = this;
3056
3057        $elem.off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
3058          if ($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')) {
3059            e.stopImmediatePropagation();
3060            e.preventDefault();
3061          }
3062
3063          // if(e.target !== e.currentTarget.firstElementChild){
3064          //   return false;
3065          // }
3066          _this._show($elem.parent('li'));
3067
3068          if (_this.options.closeOnClick) {
3069            var $body = $('body');
3070            $body.off('.zf.drilldown').on('click.zf.drilldown', function (e) {
3071              if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
3072                return;
3073              }
3074              e.preventDefault();
3075              _this._hideAll();
3076              $body.off('.zf.drilldown');
3077            });
3078          }
3079        });
3080      }
3081
3082      /**
3083       * Adds keydown event listener to `li`'s in the menu.
3084       * @private
3085       */
3086
3087    }, {
3088      key: '_keyboardEvents',
3089      value: function _keyboardEvents() {
3090        var _this = this;
3091
3092        this.$menuItems.add(this.$element.find('.js-drilldown-back > a')).on('keydown.zf.drilldown', function (e) {
3093
3094          var $element = $(this),
3095              $elements = $element.parent('li').parent('ul').children('li').children('a'),
3096              $prevElement,
3097              $nextElement;
3098
3099          $elements.each(function (i) {
3100            if ($(this).is($element)) {
3101              $prevElement = $elements.eq(Math.max(0, i - 1));
3102              $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1));
3103              return;
3104            }
3105          });
3106
3107          Foundation.Keyboard.handleKey(e, 'Drilldown', {
3108            next: function () {
3109              if ($element.is(_this.$submenuAnchors)) {
3110                _this._show($element.parent('li'));
3111                $element.parent('li').one(Foundation.transitionend($element), function () {
3112                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
3113                });
3114                return true;
3115              }
3116            },
3117            previous: function () {
3118              _this._hide($element.parent('li').parent('ul'));
3119              $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
3120                setTimeout(function () {
3121                  $element.parent('li').parent('ul').parent('li').children('a').first().focus();
3122                }, 1);
3123              });
3124              return true;
3125            },
3126            up: function () {
3127              $prevElement.focus();
3128              return true;
3129            },
3130            down: function () {
3131              $nextElement.focus();
3132              return true;
3133            },
3134            close: function () {
3135              _this._back();
3136              //_this.$menuItems.first().focus(); // focus to first element
3137            },
3138            open: function () {
3139              if (!$element.is(_this.$menuItems)) {
3140                // not menu item means back button
3141                _this._hide($element.parent('li').parent('ul'));
3142                $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
3143                  setTimeout(function () {
3144                    $element.parent('li').parent('ul').parent('li').children('a').first().focus();
3145                  }, 1);
3146                });
3147              } else if ($element.is(_this.$submenuAnchors)) {
3148                _this._show($element.parent('li'));
3149                $element.parent('li').one(Foundation.transitionend($element), function () {
3150                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
3151                });
3152              }
3153              return true;
3154            },
3155            handled: function (preventDefault) {
3156              if (preventDefault) {
3157                e.preventDefault();
3158              }
3159              e.stopImmediatePropagation();
3160            }
3161          });
3162        }); // end keyboardAccess
3163      }
3164
3165      /**
3166       * Closes all open elements, and returns to root menu.
3167       * @function
3168       * @fires Drilldown#closed
3169       */
3170
3171    }, {
3172      key: '_hideAll',
3173      value: function _hideAll() {
3174        var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing');
3175        $elem.one(Foundation.transitionend($elem), function (e) {
3176          $elem.removeClass('is-active is-closing');
3177        });
3178        /**
3179         * Fires when the menu is fully closed.
3180         * @event Drilldown#closed
3181         */
3182        this.$element.trigger('closed.zf.drilldown');
3183      }
3184
3185      /**
3186       * Adds event listener for each `back` button, and closes open menus.
3187       * @function
3188       * @fires Drilldown#back
3189       * @param {jQuery} $elem - the current sub-menu to add `back` event.
3190       */
3191
3192    }, {
3193      key: '_back',
3194      value: function _back($elem) {
3195        var _this = this;
3196        $elem.off('click.zf.drilldown');
3197        $elem.children('.js-drilldown-back').on('click.zf.drilldown', function (e) {
3198          e.stopImmediatePropagation();
3199          // console.log('mouseup on back');
3200          _this._hide($elem);
3201        });
3202      }
3203
3204      /**
3205       * Adds event listener to menu items w/o submenus to close open menus on click.
3206       * @function
3207       * @private
3208       */
3209
3210    }, {
3211      key: '_menuLinkEvents',
3212      value: function _menuLinkEvents() {
3213        var _this = this;
3214        this.$menuItems.not('.is-drilldown-submenu-parent').off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
3215          // e.stopImmediatePropagation();
3216          setTimeout(function () {
3217            _this._hideAll();
3218          }, 0);
3219        });
3220      }
3221
3222      /**
3223       * Opens a submenu.
3224       * @function
3225       * @fires Drilldown#open
3226       * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
3227       */
3228
3229    }, {
3230      key: '_show',
3231      value: function _show($elem) {
3232        $elem.children('[data-submenu]').addClass('is-active');
3233        /**
3234         * Fires when the submenu has opened.
3235         * @event Drilldown#open
3236         */
3237        this.$element.trigger('open.zf.drilldown', [$elem]);
3238      }
3239    }, {
3240      key: '_hide',
3241
3242
3243      /**
3244       * Hides a submenu
3245       * @function
3246       * @fires Drilldown#hide
3247       * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
3248       */
3249      value: function _hide($elem) {
3250        var _this = this;
3251        $elem.addClass('is-closing').one(Foundation.transitionend($elem), function () {
3252          $elem.removeClass('is-active is-closing');
3253          $elem.blur();
3254        });
3255        /**
3256         * Fires when the submenu has closed.
3257         * @event Drilldown#hide
3258         */
3259        $elem.trigger('hide.zf.drilldown', [$elem]);
3260      }
3261
3262      /**
3263       * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
3264       * Prevents content jumping.
3265       * @function
3266       * @private
3267       */
3268
3269    }, {
3270      key: '_getMaxDims',
3271      value: function _getMaxDims() {
3272        var max = 0,
3273            result = {};
3274        this.$submenus.add(this.$element).each(function () {
3275          var numOfElems = $(this).children('li').length;
3276          max = numOfElems > max ? numOfElems : max;
3277        });
3278
3279        result['min-height'] = max * this.$menuItems[0].getBoundingClientRect().height + 'px';
3280        result['max-width'] = this.$element[0].getBoundingClientRect().width + 'px';
3281
3282        return result;
3283      }
3284
3285      /**
3286       * Destroys the Drilldown Menu
3287       * @function
3288       */
3289
3290    }, {
3291      key: 'destroy',
3292      value: function destroy() {
3293        this._hideAll();
3294        Foundation.Nest.Burn(this.$element, 'drilldown');
3295        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');
3296        this.$submenuAnchors.each(function () {
3297          $(this).off('.zf.drilldown');
3298        });
3299        this.$element.find('a').each(function () {
3300          var $link = $(this);
3301          if ($link.data('savedHref')) {
3302            $link.attr('href', $link.data('savedHref')).removeData('savedHref');
3303          } else {
3304            return;
3305          }
3306        });
3307        Foundation.unregisterPlugin(this);
3308      }
3309    }]);
3310
3311    return Drilldown;
3312  }();
3313
3314  Drilldown.defaults = {
3315    /**
3316     * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
3317     * @option
3318     * @example '<\li><\a>Back<\/a><\/li>'
3319     */
3320    backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
3321    /**
3322     * 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.
3323     * @option
3324     * @example '<\div class="is-drilldown"><\/div>'
3325     */
3326    wrapper: '<div></div>',
3327    /**
3328     * Adds the parent link to the submenu.
3329     * @option
3330     * @example false
3331     */
3332    parentLink: false,
3333    /**
3334     * Allow the menu to return to root list on body click.
3335     * @option
3336     * @example false
3337     */
3338    closeOnClick: false
3339    // holdOpen: false
3340  };
3341
3342  // Window exports
3343  Foundation.plugin(Drilldown, 'Drilldown');
3344}(jQuery);
3345'use strict';
3346
3347var _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; }; }();
3348
3349function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3350
3351!function ($) {
3352
3353  /**
3354   * Dropdown module.
3355   * @module foundation.dropdown
3356   * @requires foundation.util.keyboard
3357   * @requires foundation.util.box
3358   * @requires foundation.util.triggers
3359   */
3360
3361  var Dropdown = function () {
3362    /**
3363     * Creates a new instance of a dropdown.
3364     * @class
3365     * @param {jQuery} element - jQuery object to make into a dropdown.
3366     *        Object should be of the dropdown panel, rather than 
3366its anchor.
3367     * @param {Object} options - Overrides to the default plugin settings.
3368     */
3369
3370    function Dropdown(element, options) {
3371      _classCallCheck(this, Dropdown);
3372
3373      this.$element = element;
3374      this.options = $.extend({}, Dropdown.defaults, this.$element.data(), options);
3375      this._init();
3376
3377      Foundation.registerPlugin(this, 'Dropdown');
3378      Foundation.Keyboard.register('Dropdown', {
3379        'ENTER': 'open',
3380        'SPACE': 'open',
3381        'ESCAPE': 'close',
3382        'TAB': 'tab_forward',
3383        'SHIFT_TAB': 'tab_backward'
3384      });
3385    }
3386
3387    /**
3388     * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anchor.
3389     * @function
3390     * @private
3391     */
3392
3393
3394    _createClass(Dropdown, [{
3395      key: '_init',
3396      value: function _init() {
3397        var $id = this.$element.attr('id');
3398
3399        this.$anchor = $('[data-toggle="' + $id + '"]') || $('[data-open="' + $id + '"]');
3400        this.$anchor.attr({
3401          'aria-controls': $id,
3402          'data-is-focus': false,
3403          'data-yeti-box': $id,
3404          'aria-haspopup': true,
3405          'aria-expanded': false
3406
3407        });
3408
3409        this.options.positionClass = this.getPositionClass();
3410        this.counter = 4;
3411        this.usedPositions = [];
3412        this.$element.attr({
3413          'aria-hidden': 'true',
3414          'data-yeti-box': $id,
3415          'data-resize': $id,
3416          'aria-labelledby': this.$anchor[0].id || Foundation.GetYoDigits(6, 'dd-anchor')
3417        });
3418        this._events();
3419      }
3420
3421      /**
3422       * Helper function to determine current orientation of dropdown pane.
3423       * @function
3424       * @returns {String} position - string value of a position class.
3425       */
3426
3427    }, {
3428      key: 'getPositionClass',
3429      value: function getPositionClass() {
3430        var verticalPosition = this.$element[0].className.match(/(top|left|right|bottom)/g);
3431        verticalPosition = verticalPosition ? verticalPosition[0] : '';
3432        var horizontalPosition = /float-(\S+)\s/.exec(this.$anchor[0].className);
3433        horizontalPosition = horizontalPosition ? horizontalPosition[1] : '';
3434        var position = horizontalPosition ? horizontalPosition + ' ' + verticalPosition : verticalPosition;
3435        return position;
3436      }
3437
3438      /**
3439       * Adjusts the dropdown panes orientation by adding/removing positioning classes.
3440       * @function
3441       * @private
3442       * @param {String} position - position class to remove.
3443       */
3444
3445    }, {
3446      key: '_reposition',
3447      value: function _reposition(position) {
3448        this.usedPositions.push(position ? position : 'bottom');
3449        //default, try switching to opposite side
3450        if (!position && this.usedPositions.indexOf('top') < 0) {
3451          this.$element.addClass('top');
3452        } else if (position === 'top' && this.usedPositions.indexOf('bottom') < 0) {
3453          this.$element.removeClass(position);
3454        } else if (position === 'left' && this.usedPositions.indexOf('right') < 0) {
3455          this.$element.removeClass(position).addClass('right');
3456        } else if (position === 'right' && this.usedPositions.indexOf('left') < 0) {
3457          this.$element.removeClass(position).addClass('left');
3458        }
3459
3460        //if default change didn't work, try bottom or left first
3461        else if (!position && this.usedPositions.indexOf('top') > -1 && this.usedPositions.indexOf('left') < 0) {
3462            this.$element.addClass('left');
3463          } else if (position === 'top' && this.usedPositions.indexOf('bottom') > -1 && this.usedPositions.indexOf('left') < 0) {
3464            this.$element.removeClass(position).addClass('left');
3465          } else if (position === 'left' && this.usedPositions.indexOf('right') > -1 && this.usedPositions.indexOf('bottom') < 0) {
3466            this.$element.removeClass(position);
3467          } else if (position === 'right' && this.usedPositions.indexOf('left') > -1 && this.usedPositions.indexOf('bottom') < 0) {
3468            this.$element.removeClass(position);
3469          }
3470          //if nothing cleared, set to bottom
3471          else {
3472              this.$element.removeClass(position);
3473            }
3474        this.classChanged = true;
3475        this.counter--;
3476      }
3477
3478      /**
3479       * Sets the position and orientation of the dropdown pane, checks for c
3479ollisions.
3480       * Recursively calls itself if a collision is detected, with a new position class.
3481       * @function
3482       * @private
3483       */
3484
3485    }, {
3486      key: '_setPosition',
3487      value: function _setPosition() {
3488        if (this.$anchor.attr('aria-expanded') === 'false') {
3489          return false;
3490        }
3491        var position = this.getPositionClass(),
3492            $eleDims = Foundation.Box.GetDimensions(this.$element),
3493            $anchorDims = Foundation.Box.GetDimensions(this.$anchor),
3494            _this = this,
3495            direction = position === 'left' ? 'left' : position === 'right' ? 'left' : 'top',
3496            param = direction === 'top' ? 'height' : 'width',
3497            offset = param === 'height' ? this.options.vOffset : this.options.hOffset;
3498
3499        if ($eleDims.width >= $eleDims.windowDims.width || !this.counter && !Foundation.Box.ImNotTouchingYou(this.$element)) {
3500          this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
3501            'width': $eleDims.windowDims.width - this.options.hOffset * 2,
3502            'height': 'auto'
3503          });
3504          this.classChanged = true;
3505          return false;
3506        }
3507
3508        this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, position, this.options.vOffset, this.options.hOffset));
3509
3510        while (!Foundation.Box.ImNotTouchingYou(this.$element, false, true) && this.counter) {
3511          this._reposition(position);
3512          this._setPosition();
3513        }
3514      }
3515
3516      /**
3517       * Adds event listeners to the element utilizing the triggers utility library.
3518       * @function
3519       * @private
3520       */
3521
3522    }, {
3523      key: '_events',
3524      value: function _events() {
3525        var _this = this;
3526        this.$element.on({
3527          'open.zf.trigger': this.open.bind(this),
3528          'close.zf.trigger': this.close.bind(this),
3529          'toggle.zf.trigger': this.toggle.bind(this),
3530          'resizeme.zf.trigger': this._setPosition.bind(this)
3531        });
3532
3533        if (this.options.hover) {
3534          this.$anchor.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () {
3535            clearTimeout(_this.timeout);
3536            _this.timeout = setTimeout(function () {
3537              _this.open();
3538              _this.$anchor.data('hover', true);
3539            }, _this.options.hoverDelay);
3540          }).on('mouseleave.zf.dropdown', function () {
3541            clearTimeout(_this.timeout);
3542            _this.timeout = setTimeout(function () {
3543              _this.close();
3544              _this.$anchor.data('hover', false);
3545            }, _this.options.hoverDelay);
3546          });
3547          if (this.options.hoverPane) {
3548            this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () {
3549              clearTimeout(_this.timeout);
3550            }).on('mouseleave.zf.dropdown', function () {
3551              clearTimeout(_this.timeout);
3552              _this.timeout = setTimeout(function () {
3553                _this.close();
3554                _this.$anchor.data('hover', false);
3555              }, _this.options.hoverDelay);
3556            });
3557          }
3558        }
3559        this.$anchor.add(this.$element).on('keydown.zf.dropdown', function (e) {
3560
3561          var $target = $(this),
3562              visibleFocusableElements = Foundation.Keyboard.findFocusable(_this.$element);
3563
3564          Foundation.Keyboard.handleKey(e, 'Dropdown', {
3565            tab_forward: function () {
3566              if (_this.$element.find(':focus').is(visibleFocusableElements.eq(-1))) {
3567                // left modal downwards, setting focus to first element
3568                if (_this.options.trapFocus) {
3569                  // if focus shall be trapped
3570                  visibleFocusableElements.eq(0).focus();
3571                  e.preventDefault();
3572                } else {
3573                  // if focus is not trapped, close dropdown on focus out
3574                  _this.close();
3575                }
3576              }
3577            },
3578            tab_backward: function () {
3579              if (_this.$element.find(':focus').is(visibleFocusableElements.eq(0)) || _this.$element.is(':focus')) {
3580                // left modal upwards, setting focus to last element
3581                if (_this.options.trapFocus) {
3582                  // if focus shall be trapped
3583                  visibleFocusableElements.eq(-1).focus();
3584                  e.preventDefault();
3585                } else {
3586                  // if focus is not trapped, close dropdown on focus out
3587                  _this.close();
3588                }
3589              }
3590            },
3591            open: function () {
3592              if ($target.is(_this.$anchor)) {
3593                _this.open();
3594                _this.$element.attr('tabindex', -1).focus();
3595                e.preventDefault();
3596              }
3597            },
3598            close: function () {
3599              _this.close();
3600              _this.$anchor.focus();
3601            }
3602          });
3603        });
3604      }
3605
3606      /**
3607       * Adds an event handler to the body to close any dropdowns on a click.
3608       * @function
3609       * @private
3610       */
3611
3612    }, {
3613      key: '_addBodyHandler',
3614      value: function _addBodyHandler() {
3615        var $body = $(document.body).not(this.$element),
3616            _this = this;
3617        $body.off('click.zf.dropdown').on('click.zf.dropdown', function (e) {
3618          if (_this.$anchor.is(e.target) || _this.$anchor.find(e.target).length) {
3619            return;
3620          }
3621          if (_this.$element.find(e.target).length) {
3622            return;
3623          }
3624          _this.close();
3625          $body.off('click.zf.dropdown');
3626        });
3627      }
3628
3629      /**
3630       * Opens the dropdown pane, and fires a bubbling event to close other dropdowns.
3631       * @function
3632       * @fires Dropdown#closeme
3633       * @fires Dropdown#show
3634       */
3635
3636    }, {
3637      key: 'open',
3638      value: function open() {
3639        // var _this = this;
3640        /**
3641         * Fires to close other open dropdowns
3642         * @event Dropdown#closeme
3643         */
3644        this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id'));
3645        this.$anchor.addClass('hover').attr({ 'aria-expanded': true });
3646        // this.$element/*.show()*/;
3647        this._setPosition();
3648        this.$element.addClass('is-open').attr({ 'aria-hidden': false });
3649
3650        if (this.options.autoFocus) {
3651          var $focusable = Foundation.Keyboard.findFocusable(this.$element);
3652          if ($focusable.length) {
3653            $focusable.eq(0).focus();
3654          }
3655        }
3656
3657        if (this.options.closeOnClick) {
3658          this._addBodyHandler();
3659        }
3660
3661        /**
3662         * Fires once the dropdown is visible.
3663         * @event Dropdown#show
3664         */
3665        this.$element.trigger('show.zf.dropdown', [this.$element]);
3666      }
3667
3668      /**
3669       * Closes the open dropdown pane.
3670       * @function
3671       * @fires Dropdown#hide
3672       */
3673
3674    }, {
3675      key: 'close',
3676      value: function close() {
3677        if (!this.$element.hasClass('is-open')) {
3678          return false;
3679        }
3680        this.$element.removeClass('is-open').attr({ 'aria-hidden': true });
3681
3682        this.$anchor.removeClass('hover').attr('aria-expanded', false);
3683
3684        if (this.classChanged) {
3685          var curPositionClass = this.getPositionClass();
3686          if (curPositionClass) {
3687            this.$element.removeClass(curPositionClass);
3688          }
3689          this.$element.addClass(this.options.positionClass)
3690          /*.hide()*/.css({ height: '', width: '' });
3691          this.classChanged = false;
3692          this.counter = 4;
3693          this.usedPositions.length = 0;
3694        }
3695        this.$element.trigger('hide.zf.dropdown', [this.$element]);
3696      }
3697
3698      /**
3699       * Toggles the dropdown pane's visibility.
3700       * @function
3701       */
3702
3703    }, {
3704      key: 'toggle',
3705      value: function toggle() {
3706        if (this.$element.hasClass('is-open')) {
3707          if (this.$anchor.data('hover')) return;
3708          this.close();
3709        } else {
3710          this.open();
3711        }
3712      }
3713
3714      /**
3715       * Destroys the dropdown.
3716       * @function
3717       */
3718
3719    }, {
3720      key: 'destroy',
3721      value: function destroy() {
3722        this.$element.off('.zf.trigger').hide();
3723        this.$anchor.off('.zf.dropdown');
3724
3725        Foundation.unregisterPlugin(this);
3726      }
3727    }]);
3728
3729    return Dropdown;
3730  }();
3731
3732  Dropdown.defaults = {
3733    /**
3734     * Amount of time to delay opening a submenu on hover event.
3735     * @option
3736     * @example 250
3737     */
3738    hoverDelay: 250,
3739    /**
3740     * Allow submenus to open on hover events
3741     * @option
3742     * @example false
3743     */
3744    hover: false,
3745    /**
3746     * Don't close dropdown when hovering over dropdown pane
3747     * @option
3748     * @example true
3749     */
3750    hoverPane: false,
3751    /**
3752     * Number of pixels between the dropdown pane and the triggering element on open.
3753     * @option
3754     * @example 1
3755     */
3756    vOffset: 1,
3757    /**
3758     * Number of pixels between the dropdown pane and the triggering element on open.
3759     * @option
3760     * @example 1
3761     */
3762    hOffset: 1,
3763    /**
3764     * Class applied to adjust open position. JS will test and fill this in.
3765     * @option
3766     * @example 'top'
3767     */
3768    positionClass: '',
3769    /**
3770     * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands.
3771     * @option
3772     * @example false
3773     */
3774    trapFocus: false,
3775    /**
3776     * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening.
3777     * @option
3778     * @example true
3779     */
3780    autoFocus: false,
3781    /**
3782     * Allows a click on the body to close the dropdown.
3783     * @option
3784     * @example false
3785     */
3786    closeOnClick: false
3787  };
3788
3789  // Window exports
3790  Foundation.plugin(Dropdown, 'Dropdown');
3791}(jQuery);
3792'use strict';
3793
3794var _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; }; }();
3795
3796function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3797
3798!function ($) {
3799
3800  /**
3801   * DropdownMenu module.
3802   * @module foundation.dropdown-menu
3803   * @requires foundation.util.keyboard
3804   * @requires foundation.util.box
3805   * @requires foundation.util.nest
3806   */
3807
3808  var DropdownMenu = function () {
3809    /**
3810     * Creates a new instance of DropdownMenu.
3811     * @class
3812     * @fires DropdownMenu#init
3813     * @param {jQuery} element - jQuery object to make into a dropdown menu.
3814     * @param {Object} options - Overrides to the default plugin settings.
3815     */
3816
3817    function DropdownMenu(element, options) {
3818      _classCallCheck(this, DropdownMenu);
3819
3820      this.$element = element;
3821      this.options = $.extend({}, DropdownMenu.defaults, this.$element.data(), options);
3822
3823      Foundation.Nest.Feather(this.$element, 'dropdown');
3824      this._init();
3825
3826      Foundation.registerPlugin(this, 'DropdownMenu');
3827      Foundation.Keyboard.register('DropdownMenu', {
3828        'ENTER': 'open',
3829        'SPACE': 'open',
3830        'ARROW_RIGHT': 'next',
3831        'ARROW_UP': 'up',
3832        'ARROW_DOWN': 'down',
3833        'ARROW_LEFT': 'previous',
3834        'ESCAPE': 'close'
3835      });
3836    }
3837
3838    /**
3839     * Initializes the plugin, and calls _prepareMenu
3840     * @private
3841     * @function
3842     */
3843
3844
3845    _createClass(DropdownMenu, [{
3846      key: '_init',
3847      value: function _init() {
3848        var subs = this.$element.find('li.is-dropdown-submenu-parent');
3849        this.$element.children('.is-dropdown-submenu-parent').children('.is-dropdown-submenu').addClass('first-sub');
3850
3851        this.$menuItems = this.$element.find('[role="menuitem"]');
3852        this.$tabs = this.$element.children('[role="menuitem"]');
3853        this.$tabs.find('ul.is-dropdown-submenu').addClass(this.options.verticalClass);
3854
3855        if (this.$element.hasClass(this.options.rightClass) || this.options.alignment === 'right' || Foundation.rtl() || this.$element.parents('.top-bar-right').is('*')) {
3856          this.options.alignment = 'right';
3857          subs.addClass('opens-left');
3858        } else {
3859          subs.addClass('opens-right');
3860        }
3861        this.changed = false;
3862        this._events();
3863      }
3864    }, {
3865      key: '_events',
3866
3867      /**
3868       * Adds event listeners to elements within the menu
3869       * @private
3870       * @function
3871       */
3872      value: function _events() {
3873        var _this = this,
3874            hasTouch = 'ontouchstart' in window || typeof window.ontouchstart !== 'undefined',
3875            parClass = 'is-dropdown-submenu-parent';
3876
3877        // used for onClick and in the keyboard handlers
3878        var handleClickFn = function (e) {
3879          var $elem = $(e.target).parentsUntil('ul', '.' + parClass),
3880              hasSub = $elem.hasClass(parClass),
3881              hasClicked = $elem.attr('data-is-click') === 'true',
3882              $sub = $elem.children('.is-dropdown-submenu');
3883
3884          if (hasSub) {
3885            if (hasClicked) {
3886              if (!_this.options.closeOnClick || !_this.options.clickOpen && !hasTouch || _this.options.forceFollow && hasTouch) {
3887                return;
3888              } else {
3889                e.stopImmediatePropagation();
3890                e.preventDefault();
3891                _this._hide($elem);
3892              }
3893            } else {
3894              e.preventDefault();
3895              e.stopImmediatePropagation();
3896              _this._show($elem.children('.is-dropdown-submenu'));
3897              $elem.add($elem.parentsUntil(_this.$element, '.' + parClass)).attr('data-is-click', true);
3898            }
3899          } else {
3900            return;
3901          }
3902        };
3903
3904        if (this.options.clickOpen || hasTouch) {
3905          this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', handleClickFn);
3906        }
3907
3908        if (!this.options.disableHover) {
3909          this.$menuItems.on('mouseenter.zf.dropdownmenu', function (e) {
3910            var $elem = $(this),
3911                hasSub = $elem.hasClass(parClass);
3912
3913            if (hasSub) {
3914              clearTimeout(_this.delay);
3915              _this.delay = setTimeout(function () {
3916                _this._show($elem.children('.is-dropdown-submenu'));
3917              }, _this.options.hoverDelay);
3918            }
3919          }).on('mouseleave.zf.dropdownmenu', function (e) {
3920            var $elem = $(this),
3921                hasSub = $elem.hasClass(parClass);
3922            if (hasSub && _this.options.autoclose) {
3923              if ($elem.attr('data-is-click') === 'true' && _this.options.clickOpen) {
3924                return false;
3925              }
3926
3927              clearTimeout(_this.delay);
3928              _this.delay = setTimeout(function () {
3929                _this._hide($elem);
3930              }, _this.options.closingTime);
3931            }
3932          });
3933        }
3934        this.$menuItems.on('keydown.zf.dropdownmenu', function (e) {
3935          var $element = $(e.target).parentsUntil('ul', '[role="menuitem"]'),
3936              isTab = _this.$tabs.index($element) > -1,
3937              $elements = isTab ? _this.$tabs : $element.siblings('li').add($element),
3938              $prevElement,
3939              $nextElement;
3940
3941          $elements.each(function (i) {
3942            if ($(this).is($element)) {
3943              $prevElement = $elements.eq(i - 1);
3944              $nextElement = $elements.eq(i + 1);
3945              return;
3946            }
3947          });
3948
3949          var nextSibling = function () {
3950            if (!$element.is(':last-child')) {
3951              $nextElement.children('a:first').focus();
3952              e.preventDefault();
3953            }
3954          },
3955              prevSibling = function () {
3956            $prevElement.children('a:first').focus();
3957            e.preventDefault();
3958          },
3959              openSub = function () {
3960            var $sub = $element.children('ul.is-dropdown-submenu');
3961            if ($sub.length) {
3962              _this._show($sub);
3963              $element.find('li > a:first').focus();
3964              e.preventDefault();
3965            } else {
3966              return;
3967            }
3968          },
3969              closeSub = function () {
3970            //if ($element.is(':first-child')) {
3971            var close = $element.parent('ul').parent('li');
3972            close.children('a:first').focus();
3973            _this._hide(close);
3974            e.preventDefault();
3975            //}
3976          };
3977          var functions = {
3978            open: openSub,
3979            close: function () {
3980              _this._hide(_this.$element);
3981              _this.$menuItems.find('a:first').focus(); // focus to first element
3982              e.preventDefault();
3983            },
3984            handled: function () {
3985              e.stopImmediatePropagation();
3986            }
3987          };
3988
3989          if (isTab) {
3990            if (_this.$element.hasClass(_this.options.verticalClass)) {
3991              // vertical menu
3992              if (_this.options.alignment === 'left') {
3993                // left aligned
3994                $.extend(functions, {
3995                  down: nextSibling,
3996                  up: prevSibling,
3997                  next: openSub,
3998                  previous: closeSub
3999                });
4000              } else {
4001                // right aligned
4002                $.extend(functions, {
4003                  down: nextSibling,
4004                  up: prevSibling,
4005                  next: closeSub,
4006                  previous: openSub
4007                });
4008              }
4009            } else {
4010              // horizontal menu
4011              $.extend(functions, {
4012                next: nextSibling,
4013                previous: prevSibling,
4014                down: openSub,
4015                up: closeSub
4016              });
4017            }
4018          } else {
4019            // not tabs -> one sub
4020            if (_this.options.alignment === 'left') {
4021              // left aligned
4022              $.extend(functions, {
4023                next: openSub,
4024                previous: closeSub,
4025                down: nextSibling,
4026                up: prevSibling
4027              });
4028            } else {
4029              // right aligned
4030              $.extend(functions, {
4031                next: closeSub,
4032                previous: openSub,
4033                down: nextSibling,
4034                up: prevSibling
4035              });
4036            }
4037          }
4038          Foundation.Keyboard.handleKey(e, 'DropdownMenu', functions);
4039        });
4040      }
4041
4042      /**
4043       * Adds an event handler to the body to close any dropdowns on a click.
4044       * @function
4045       * @private
4046       */
4047
4048    }, {
4049      key: '_addBodyHandler',
4050      value: function _addBodyHandler() {
4051        var $body = $(document.body),
4052            _this = this;
4053        $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu').on('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu', function (e) {
4054          var $link = _this.$element.find(e.target);
4055          if ($link.length) {
4056            return;
4057          }
4058
4059          _this._hide();
4060          $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu');
4061        });
4062      }
4063
4064      /**
4065       * Opens a dropdown pane, and checks for collisions first.
4066       * @param {jQuery} $sub - ul element that is a submenu to show
4067       * @function
4068       * @private
4069       * @fires DropdownMenu#show
4070       */
4071
4072    }, {
4073      key: '_show',
4074      value: function _show($sub) {
4075        var idx = this.$tabs.index(this.$tabs.filter(function (i, el) {
4076          return $(el).find($sub).length > 0;
4077        }));
4078        var $sibs = $sub.parent('li.is-dropdown-submenu-parent').siblings('li.is-dropdown-submenu-parent');
4079        this._hide($sibs, idx);
4080        $sub.css('visibility', 'hidden').addClass('js-dropdown-active').attr({ 'aria-hidden': false }).parent('li.is-dropdown-submenu-parent').addClass('is-active').attr({ 'aria-expanded': true });
4081        var clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
4082        if (!clear) {
4083          var oldClass = this.options.alignment === 'left' ? '-right' : '-left',
4084              $parentLi = $sub.parent('.is-dropdown-submenu-parent');
4085          $parentLi.removeClass('opens' + oldClass).addClass('opens-' + this.options.alignment);
4086          clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
4087          if (!clear) {
4088            $parentLi.removeClass('opens-' + this.options.alignment).addClass('opens-inner');
4089          }
4090          this.changed = true;
4091        }
4092        $sub.css('visibility', '');
4093        if (this.options.closeOnClick) {
4094          this._addBodyHandler();
4095        }
4096        /**
4097         * Fires when the new dropdown pane is visible.
4098         * @event DropdownMenu#show
4099         */
4100        this.$element.trigger('show.zf.dropdownmenu', [$sub]);
4101      }
4102
4103      /**
4104       * Hides a single, currently open dropdown pane, if passed a parameter, otherwise, hides everything.
4105       * @function
4106       * @param {jQuery} $elem - element with a submenu to hide
4107       * @param {Number} idx - index of the $tabs collection to hide
4108       * @private
4109       */
4110
4111    }, {
4112      key: '_hide',
4113      value: function _hide($elem, idx) {
4114        var $toClose;
4115        if ($elem && $elem.length) {
4116          $toClose = $elem;
4117        } else if (idx !== undefined) {
4118          $toClose = this.$tabs.not(function (i, el) {
4119            return i === idx;
4120          });
4121        } else {
4122          $toClose = this.$element;
4123        }
4124        var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0;
4125
4126        if (somethingToClose) {
4127          $toClose.find('li.is-active').add($toClose).attr({
4128            'aria-expanded': false,
4129            'data-is-click': false
4130          }).removeClass('is-active');
4131
4132          $toClose.find('ul.js-dropdown-active').attr({
4133            'aria-hidden': true
4134          }).removeClass('js-dropdown-active');
4135
4136          if (this.changed || $toClose.find('opens-inner').length) {
4137            var oldClass = this.options.alignment === 'left' ? 'right' : 'left';
4138            $toClose.find('li.is-dropdown-submenu-parent').add($toClose).removeClass('opens-inner opens-' + this.options.alignment).addClass('opens-' + oldClass);
4139            this.changed = false;
4140          }
4141          /**
4142           * Fires when the open menus are closed.
4143           * @event DropdownMenu#hide
4144           */
4145          this.$element.trigger('hide.zf.dropdownmenu', [$toClose]);
4146        }
4147      }
4148
4149      /**
4150       * Destroys the plugin.
4151       * @function
4152       */
4153
4154    }, {
4155      key: 'destroy',
4156      value: function destroy() {
4157        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');
4158        $(document.body).off('.zf.dropdownmenu');
4159        Foundation.Nest.Burn(this.$element, 'dropdown');
4160        Foundation.unregisterPlugin(this);
4161      }
4162    }]);
4163
4164    return DropdownMenu;
4165  }();
4166
4167  /**
4168   * Default settings for plugin
4169   */
4170
4171
4172  DropdownMenu.defaults = {
4173    /**
4174     * Disallows hover events from opening submenus
4175     * @option
4176     * @example false
4177     */
4178    disableHover: false,
4179    /**
4180     * Allow a submenu to automatically close on a mouseleave event, if not clicked open.
4181     * @option
4182     * @example true
4183     */
4184    autoclose: true,
4185    /**
4186     * Amount of time to delay opening a submenu on hover event.
4187     * @option
4188     * @example 50
4189     */
4190    hoverDelay: 50,
4191    /**
4192     * Allow a submenu to open/remain open on parent click event. Allows cursor to move away from menu.
4193     * @option
4194     * @example true
4195     */
4196    clickOpen: false,
4197    /**
4198     * Amount of time to delay closing a submenu on a mouseleave event.
4199     * @option
4200     * @example 500
4201     */
4202
4203    closingTime: 500,
4204    /**
4205     * Position of the menu relative to what direction the submenus should open. Handled by JS.
4206     * @option
4207     * @example 'left'
4208     */
4209    alignment: 'left',
4210    /**
4211     * Allow clicks on the body to close any open submenus.
4212     * @option
4213     * @example true
4214     */
4215    closeOnClick: true,
4216    /**
4217     * Class applied to vertical oriented menus, Foundation default is `vertical`. Update this if using your own class.
4218     * @option
4219     * @example 'vertical'
4220     */
4221    verticalClass: 'vertical',
4222    /**
4223     * Class applied to right-side oriented menus, Foundation default is `align-right`. Update this if using your own class.
4224     * @option
4225     * @example 'align-right'
4226     */
4227    rightClass: 'align-right',
4228    /**
4229     * Boolean to force overide the clicking of links to perform default action, on second touch event for mobile.
4230     * @option
4231     * @example false
4232     */
4233    forceFollow: true
4234  };
4235
4236  // Window exports
4237  Foundation.plugin(DropdownMenu, 'DropdownMenu');
4238}(jQuery);
4239'use strict';
4240
4241var _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; }; }();
4242
4243function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4244
4245!function ($) {
4246
4247  /**
4248   * Equalizer module.
4249   * @module foundation.equalizer
4250   */
4251
4252  var Equalizer = function () {
4253    /**
4254     * Creates a new instance of Equalizer.
4255     * @class
4256     * @fires Equalizer#init
4257     * @param {Object} element - jQuery object to add the trigger to.
4258     * @param {Object} options - Overrides to the default plugin settings.
4259     */
4260
4261    function Equalizer(element, options) {
4262      _classCallCheck(this, Equalizer);
4263
4264      this.$element = element;
4265      this.options = $.extend({}, Equalizer.defaults, this.$element.data(), options);
4266
4267      this._init();
4268
4269      Foundation.registerPlugin(this, 'Equalizer');
4270    }
4271
4272    /**
4273     * Initializes the Equalizer plugin and calls functions to get equalizer functioning on load.
4274     * @private
4275     */
4276
4277
4278    _createClass(Equalizer, [{
4279      key: '_init',
4280      value: function _init() {
4281        var eqId = this.$element.attr('data-equalizer') || '';
4282        var $watched = this.$element.find('[data-equalizer-watch="' + eqId + '"]');
4283
4284        this.$watched = $watched.length ? $watched : this.$element.find('[data-equalizer-watch]');
4285        this.$element.attr('data-resize', eqId || Foundation.GetYoDigits(6, 'eq'));
4286
4287        this.hasNested = this.$element.find('[data-equalizer]').length > 0;
4288        this.isNested = this.$element.parentsUntil(document.body, '[data-equalizer]').length > 0;
4289        this.isOn = false;
vendor: 4,716 bytes, lines 4290-4457
4290        this._bindHandler = {
4291          onResizeMeBound: this._onResizeMe.bind(this),
4292          onPostEqualizedBound: this._onPostEqualized.bind(this)
4293        };
4294
4295        var imgs = this.$element.find('img');
4296        var tooSmall;
4297        if (this.options.equalizeOn) {
4298          tooSmall = this._checkMQ();
4299          $(window).on('changed.zf.mediaquery', this._checkMQ.bind(this));
4300        } else {
4301          this._events();
4302        }
4303        if (tooSmall !== undefined && tooSmall === false || tooSmall === undefined) {
4304          if (imgs.length) {
4305            Foundation.onImagesLoaded(imgs, this._reflow.bind(this));
4306          } else {
4307            this._reflow();
4308          }
4309        }
4310      }
4311
4312      /**
4313       * Removes event listeners if the breakpoint is too small.
4314       * @private
4315       */
4316
4317    }, {
4318      key: '_pauseEvents',
4319      value: function _pauseEvents() {
4320        this.isOn = false;
4321        this.$element.off({
4322          '.zf.equalizer': this._bindHandler.onPostEqualizedBound,
4323          'resizeme.zf.trigger': this._bindHandler.onResizeMeBound
4324        });
4325      }
4326
4327      /**
4328       * function to handle $elements resizeme.zf.trigger, with bound this on _bindHandler.onResizeMeBound
4329       * @private
4330       */
4331
4332    }, {
4333      key: '_onResizeMe',
4334      value: function _onResizeMe(e) {
4335        this._reflow();
4336      }
4337
4338      /**
4339       * function to handle $elements postequalized.zf.equalizer, with bound this on _bindHandler.onPostEqualizedBound
4340       * @private
4341       */
4342
4343    }, {
4344      key: '_onPostEqualized',
4345      value: function _onPostEqualized(e) {
4346        if (e.target !== this.$element[0]) {
4347          this._reflow();
4348        }
4349      }
4350
4351      /**
4352       * Initializes events for Equalizer.
4353       * @private
4354       */
4355
4356    }, {
4357      key: '_events',
4358      value: function _events() {
4359        var _this = this;
4360        this._pauseEvents();
4361        if (this.hasNested) {
4362          this.$element.on('postequalized.zf.equalizer', this._bindHandler.onPostEqualizedBound);
4363        } else {
4364          this.$element.on('resizeme.zf.trigger', this._bindHandler.onResizeMeBound);
4365        }
4366        this.isOn = true;
4367      }
4368
4369      /**
4370       * Checks the current breakpoint to the minimum required size.
4371       * @private
4372       */
4373
4374    }, {
4375      key: '_checkMQ',
4376      value: function _checkMQ() {
4377        var tooSmall = !Foundation.MediaQuery.atLeast(this.options.equalizeOn);
4378        if (tooSmall) {
4379          if (this.isOn) {
4380            this._pauseEvents();
4381            this.$watched.css('height', 'auto');
4382          }
4383        } else {
4384          if (!this.isOn) {
4385            this._events();
4386          }
4387        }
4388        return tooSmall;
4389      }
4390
4391      /**
4392       * A noop version for the plugin
4393       * @private
4394       */
4395
4396    }, {
4397      key: '_killswitch',
4398      value: function _killswitch() {
4399        return;
4400      }
4401
4402      /**
4403       * Calls necessary functions to update Equalizer upon DOM change
4404       * @private
4405       */
4406
4407    }, {
4408      key: '_reflow',
4409      value: function _reflow() {
4410        if (!this.options.equalizeOnStack) {
4411          if (this._isStacked()) {
4412            this.$watched.css('height', 'auto');
4413            return false;
4414          }
4415        }
4416        if (this.options.equalizeByRow) {
4417          this.getHeightsByRow(this.applyHeightByRow.bind(this));
4418        } else {
4419          this.getHeights(this.applyHeight.bind(this));
4420        }
4421      }
4422
4423      /**
4424       * Manually determines if the first 2 elements are *NOT* stacked.
4425       * @private
4426       */
4427
4428    }, {
4429      key: '_isStacked',
4430      value: function _isStacked() {
4431        return this.$watched[0].getBoundingClientRect().top !== this.$watched[1].getBoundingClientRect().top;
4432      }
4433
4434      /**
4435       * Finds the outer heights of children contained within an Equalizer parent and returns them in an array
4436       * @param {Function} cb - A non-optional callback to return the heights array to.
4437       * @returns {Array} heights - An array of heights of children within Equalizer container
4438       */
4439
4440    }, {
4441      key: 'getHeights',
4442      value: function getHeights(cb) {
4443        var heights = [];
4444        for (var i = 0, len = this.$watched.length; i < len; i++) {
4445          this.$watched[i].style.height = 'auto';
4446          heights.push(this.$watched[i].offsetHeight);
4447        }
4448        cb(heights);
4449      }
4450
4451      /**
4452       * Finds the outer heights of children contained within an Equalizer parent and returns them in an array
4453       * @param {Function} cb - A non-optional callback to return the heights array to.
4454       * @returns {Array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child
4455       */
4456
4457    }, {
vendor: 6,408 bytes, lines 4458-4662
4458      key: 'getHeightsByRow',
4459      value: function getHeightsByRow(cb) {
4460        var lastElTopOffset = this.$watched.length ? this.$watched.first().offset().top : 0,
4461            groups = [],
4462            group = 0;
4463        //group by Row
4464        groups[group] = [];
4465        for (var i = 0, len = this.$watched.length; i < len; i++) {
4466          this.$watched[i].style.height = 'auto';
4467          //maybe could use this.$watched[i].offsetTop
4468          var elOffsetTop = $(this.$watched[i]).offset().top;
4469          if (elOffsetTop != lastElTopOffset) {
4470            group++;
4471            groups[group] = [];
4472            lastElTopOffset = elOffsetTop;
4473          }
4474          groups[group].push([this.$watched[i], this.$watched[i].offsetHeight]);
4475        }
4476
4477        for (var j = 0, ln = groups.length; j < ln; j++) {
4478          var heights = $(groups[j]).map(function () {
4479            return this[1];
4480          }).get();
4481          var max = Math.max.apply(null, heights);
4482          groups[j].push(max);
4483        }
4484        cb(groups);
4485      }
4486
4487      /**
4488       * Changes the CSS height property of each child in an Equalizer parent to match the tallest
4489       * @param {array} heights - An array of heights of children within Equalizer container
4490       * @fires Equalizer#preequalized
4491       * @fires Equalizer#postequalized
4492       */
4493
4494    }, {
4495      key: 'applyHeight',
4496      value: function applyHeight(heights) {
4497        var max = Math.max.apply(null, heights);
4498        /**
4499         * Fires before the heights are applied
4500         * @event Equalizer#preequalized
4501         */
4502        this.$element.trigger('preequalized.zf.equalizer');
4503
4504        this.$watched.css('height', max);
4505
4506        /**
4507         * Fires when the heights have been applied
4508         * @event Equalizer#postequalized
4509         */
4510        this.$element.trigger('postequalized.zf.equalizer');
4511      }
4512
4513      /**
4514       * Changes the CSS height property of each child in an Equalizer parent to match the tallest by row
4515       * @param {array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child
4516       * @fires Equalizer#preequalized
4517       * @fires Equalizer#preequalizedRow
4518       * @fires Equalizer#postequalizedRow
4519       * @fires Equalizer#postequalized
4520       */
4521
4522    }, {
4523      key: 'applyHeightByRow',
4524      value: function applyHeightByRow(groups) {
4525        /**
4526         * Fires before the heights are applied
4527         */
4528        this.$element.trigger('preequalized.zf.equalizer');
4529        for (var i = 0, len = groups.length; i < len; i++) {
4530          var groupsILength = groups[i].length,
4531              max = groups[i][groupsILength - 1];
4532          if (groupsILength <= 2) {
4533            $(groups[i][0][0]).css({ 'height': 'auto' });
4534            continue;
4535          }
4536          /**
4537            * Fires before the heights per row are applied
4538            * @event Equalizer#preequalizedRow
4539            */
4540          this.$element.trigger('preequalizedrow.zf.equalizer');
4541          for (var j = 0, lenJ = groupsILength - 1; j < lenJ; j++) {
4542            $(groups[i][j][0]).css({ 'height': max });
4543          }
4544          /**
4545            * Fires when the heights per row have been applied
4546            * @event Equalizer#postequalizedRow
4547            */
4548          this.$element.trigger('postequalizedrow.zf.equalizer');
4549        }
4550        /**
4551         * Fires when the heights have been applied
4552         */
4553        this.$element.trigger('postequalized.zf.equalizer');
4554      }
4555
4556      /**
4557       * Destroys an instance of Equalizer.
4558       * @function
4559       */
4560
4561    }, {
4562      key: 'destroy',
4563      value: function destroy() {
4564        this._pauseEvents();
4565        this.$watched.css('height', 'auto');
4566
4567        Foundation.unregisterPlugin(this);
4568      }
4569    }]);
4570
4571    return Equalizer;
4572  }();
4573
4574  /**
4575   * Default settings for plugin
4576   */
4577
4578
4579  Equalizer.defaults = {
4580    /**
4581     * Enable height equalization when stacked on smaller screens.
4582     * @option
4583     * @example true
4584     */
4585    equalizeOnStack: true,
4586    /**
4587     * Enable height equalization row by row.
4588     * @option
4589     * @example false
4590     */
4591    equalizeByRow: false,
4592    /**
4593     * String representing the minimum breakpoint size the plugin should equalize heights on.
4594     * @option
4595     * @example 'medium'
4596     */
4597    equalizeOn: ''
4598  };
4599
4600  // Window exports
4601  Foundation.plugin(Equalizer, 'Equalizer');
4602}(jQuery);
4603'use strict';
4604
4605var _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; }; }();
4606
4607function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4608
4609!function ($) {
4610
4611  /**
4612   * Interchange module.
4613   * @module foundation.interchange
4614   * @requires foundation.util.mediaQuery
4615   * @requires foundation.util.timerAndImageLoader
4616   */
4617
4618  var Interchange = function () {
4619    /**
4620     * Creates a new instance of Interchange.
4621     * @class
4622     * @fires Interchange#init
4623     * @param {Object} element - jQuery object to add the trigger to.
4624     * @param {Object} options - Overrides to the default plugin settings.
4625     */
4626
4627    function Interchange(element, options) {
4628      _classCallCheck(this, Interchange);
4629
4630      this.$element = element;
4631      this.options = $.extend({}, Interchange.defaults, options);
4632      this.rules = [];
4633      this.currentPath = '';
4634
4635      this._init();
4636      this._events();
4637
4638      Foundation.registerPlugin(this, 'Interchange');
4639    }
4640
4641    /**
4642     * Initializes the Interchange plugin and calls functions to get interchange functioning on load.
4643     * @function
4644     * @private
4645     */
4646
4647
4648    _createClass(Interchange, [{
4649      key: '_init',
4650      value: function _init() {
4651        this._addBreakpoints();
4652        this._generateRules();
4653        this._reflow();
4654      }
4655
4656      /**
4657       * Initializes events for Interchange.
4658       * @function
4659       * @private
4660       */
4661
4662    }, {
4663      key: '_events',
4664      value: function _events() {
4665        $(window).on('resize.zf.interchange', Foundation.util.throttle(this._reflow.bind(this), 50));
4666      }
4667
4668      /**
4669       * Calls necessary functions to update Interchange upon DOM change
4670       * @function
4671       * @private
4672       */
4673
4674    }, {
4675      key: '_reflow',
4676      value: function _reflow() {
4677        var match;
4678
4679        // Iterate through each rule, but only save the last match
4680        for (var i in this.rules) {
4681          if (this.rules.hasOwnProperty(i)) {
4682            var rule = this.rules[i];
4683
4684            if (window.matchMedia(rule.query).matches) {
4685              match = rule;
4686            }
4687          }
4688        }
4689
4690        if (match) {
4691          this.replace(match.path);
4692        }
4693      }
4694
4695      /**
4696       * Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object.
4697       * @function
4698       * @private
4699       */
4700
4701    }, {
4702      key: '_addBreakpoints',
4703      value: function _addBreakpoints() {
4704        for (var i in Foundation.MediaQuery.queries) {
4705          if (Foundation.MediaQuery.queries.hasOwnProperty(i)) {
4706            var query = Foundation.MediaQuery.queries[i];
4707            Interchange.SPECIAL_QUERIES[query.name] = query.value;
4708          }
4709        }
4710      }
4711
4712      /**
4713       * Checks the Interchange element for the provided media query + content pairings
4714       * @function
4715       * @private
4716       * @param {Object} element - jQuery object that is an Interchange instance
4717       * @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys
4718       */
4719
4720    }, {
4721      key: '_generateRules',
4722      value: function _generateRules(element) {
4723        var rulesList = [];
4724        var rules;
4725
4726        if (this.options.rules) {
4727          rules = this.options.rules;
4728        } else {
4729          rules = this.$element.data('interchange').match(/\[.*?\]/g);
4730        }
4731
4732        for (var i in rules) {
4733          if (rules.hasOwnProperty(i)) {
4734            var rule = rules[i].slice(1, -1).split(', ');
4735            var path = rule.slice(0, -1).join('');
4736            var query = rule[rule.length - 1];
4737
4738            if (Interchange.SPECIAL_QUERIES[query]) {
4739              query = Interchange.SPECIAL_QUERIES[query];
4740            }
4741
4742            rulesList.push({
4743              path: path,
4744              query: query
4745            });
4746          }
4747        }
4748
4749        this.rules = rulesList;
4750      }
4751
4752      /**
4753       * Update the `src` property of an image, or change the HTML of a container, to the specified path.
4754       * @function
4755       * @param {String} path - Path to the image or HTML partial.
4756       * @fires Interchange#replaced
4757       */
4758
4759    }, {
4760      key: 'replace',
4761      value: function replace(path) {
4762        if (this.currentPath === path) return;
4763
4764        var _this = this,
4765            trigger = 'replaced.zf.interchange';
4766
4767        // Replacing images
4768        if (this.$element[0].nodeName === 'IMG') {
4769          this.$element.attr('src', path).load(function () {
4770            _this.currentPath = path;
4771          }).trigger(trigger);
4772        }
4773        // Replacing background images
4774        else if (path.match(/\.(gif|jpg|jpeg|png|svg|tiff)([?#].*)?/i)) {
4775            this.$element.css({ 'background-image': 'url(' + path + ')' }).trigger(trigger);
4776          }
4777          // Replacing HTML
4778          else {
4779              $.get(path, function (response) {
4780                _this.$element.html(response).trigger(trigger);
4781                $(response).foundation();
4782                _this.currentPath = path;
4783              });
4784            }
4785
4786        /**
4787         * Fires when content in an Interchange element is done being loaded.
4788         * @event Interchange#replaced
4789         */
4790        // this.$element.trigger('replaced.zf.interchange');
4791      }
4792
4793      /**
4794       * Destroys an instance of interchange.
4795       * @function
4796       */
4797
4798    }, {
4799      key: 'destroy',
4800      value: function destroy() {
4801        //TODO this.
4802      }
4803    }]);
4804
4805    return Interchange;
4806  }();
4807
4808  /**
4809   * Default settings for plugin
4810   */
4811
4812
4813  Interchange.defaults = {
4814    /**
4815     * Rules to be applied to Interchange elements. Set with the `data-interchange` array notation.
4816     * @option
4817     */
4818    rules: null
4819  };
4820
4821  Interchange.SPECIAL_QUERIES = {
4822    'landscape': 'screen and (orientation: landscape)',
4823    'portrait': 'screen and (orientation: portrait)',
4824    '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)'
4825  };
4826
4827  // Window exports
4828  Foundation.plugin(Interchange, 'Interchange');
4829}(jQuery);
4830'use strict';
4831
4832var _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; }; }();
4833
4834function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4835
4836!function ($) {
4837
4838  /**
4839   * Magellan module.
4840   * @module foundation.magellan
4841   */
4842
4843  var Magellan = function () {
4844    /**
4845     * Creates a new instance of Magellan.
4846     * @class
4847     * @fires Magellan#init
4848     * @param {Object} element - jQuery object to add the trigger to.
4849     * @param {Object} options - Overrides to the default plugin settings.
4850     */
4851
4852    function Magellan(element, options) {
4853      _classCallCheck(this, Magellan);
4854
4855      this.$element = element;
4856      this.options = $.extend({}, Magellan.defaults, this.$element.data(), options);
4857
4858      this._init();
4859
4860      Foundation.registerPlugin(this, 'Magellan');
4861    }
4862
4863    /**
4864     * Initializes the Magellan plugin and calls functions to get equalizer functioning on load.
4865     * @private
4866     */
4867
4868
4869    _createClass(Magellan, [{
4870      key: '_init',
4871      value: function _init() {
4872        var id = this.$element[0].id || Foundation.GetYoDigits(6, 'magellan');
4873        var _this = this;
4874        this.$targets = $('[data-magellan-target]');
4875        this.$links = this.$element.find('a');
4876        this.$element.attr({
4877          'data-resize': id,
4878          'data-scroll': id,
4879          'id': id
4880        });
4881        this.$active = $();
4882        this.scrollPos = parseInt(window.pageYOffset, 10);
4883
4884        this._events();
4885      }
4886
4887      /**
4888       * Calculates an array of pixel values that are the demarcation lines between locations on the page.
4889       * Can be invoked if new elements are added or the size of a location changes.
4890       * @function
4891       */
4892
4893    }, {
4894      key: 'calcPoints',
4895      value: function calcPoints() {
4896        var _this = this,
4897            body = document.body,
4898            html = document.documentElement;
4899
4900        this.points = [];
4901        this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight));
4902        this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight));
4903
4904        this.$targets.each(function () {
4905          var $tar = $(this),
4906              pt = Math.round($tar.offset().top - _this.options.threshold);
4907          $tar.targetPoint = pt;
4908          _this.points.push(pt);
4909        });
4910      }
4911
4912      /**
4913       * Initializes events for Magellan.
4914       * @private
4915       */
4916
4917    }, {
4918      key: '_events',
4919      value: function _events() {
4920        var _this = this,
4921            $body = $('html, body'),
4922            opts = {
4923          duration: _this.options.animationDuration,
4924          easing: _this.options.animationEasing
4925        };
4926        $(window).one('load', function () {
4927          if (_this.options.deepLinking) {
4928            if (location.hash) {
4929              _this.scrollToLoc(location.hash);
4930            }
4931          }
4932          _this.calcPoints();
4933          _this._updateActive();
4934        });
4935
4936        this.$element.on({
4937          'resizeme.zf.trigger': this.reflow.bind(this),
4938          'scrollme.zf.trigger': this._updateActive.bind(this)
4939        }).on('click.zf.magellan', 'a[href^="#"]', function (e) {
4940          e.preventDefault();
4941          var arrival = this.getAttribute('href');
4942          _this.scrollToLoc(arrival);
4943        });
4944      }
4945
4946      /**
4947       * Function to scroll to a given location on the page.
4948       * @param {String} loc - a properly formatted jQuery id selector. Example: '#foo'
4949       * @function
4950       */
4951
4952    }, {
4953      key: 'scrollToLoc',
4954      value: function scrollToLoc(loc) {
4955        var scrollPos = Math.round($(loc).offset().top - this.options.threshold / 2 - this.options.barOffset);
4956
4957        $('html, body').stop(true).animate({ scrollTop: scrollPos }, this.options.animationDuration, this.options.animationEasing);
4958      }
4959
4960      /**
4961       * Calls necessary functions to update Magellan upon DOM change
4962       * @function
4963       */
4964
4965    }, {
4966      key: 'reflow',
4967      value: function reflow() {
4968        this.calcPoints();
4969        this._updateActive();
4970      }
4971
4972      /**
4973       * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled.
4974       * @private
4975       * @function
4976       * @fires Magellan#update
4977       */
4978
4979    }, {
4980      key: '_updateActive',
4981      value: function _updateActive() /*evt, elem, scrollPos*/{
4982        var winPos = /*scrollPos ||*/parseInt(window.pageYOffset, 10),
4983            curIdx;
4984
4985        if (winPos + this.winHeight === this.docHeight) {
4986          curIdx = this.points.length - 1;
4987        } else if (winPos < this.points[0]) {
4988          curIdx = 0;
4989        } else {
4990          var isDown = this.scrollPos < winPos,
4991              _this = this,
4992              curVisible = this.points.filter(function (p, i) {
4993            return isDown ? p - _this.options.barOffset <= winPos : p - _this.options.barOffset - _this.options.threshold <= winPos;
4994          });
4995          curIdx = curVisible.length ? curVisible.length - 1 : 0;
4996        }
4997
4998        this.$active.removeClass(this.options.activeClass);
4999        this.$active = this.$links.eq(curIdx).addClass(this.options.activeClass);
5000
5001        if (this.options.deepLinking) {
5002          var hash = this.$active[0].getAttribute('href');
5003          if (window.history.pushState) {
5004            window.history.pushState(null, null, hash);
5005          } else {
5006            window.location.hash = hash;
5007          }
5008        }
5009
5010        this.scrollPos = winPos;
5011        /**
5012         * Fires when magellan is finished updating to the new active element.
5013         * @event Magellan#update
5014         */
5015        this.$element.trigger('update.zf.magellan', [this.$active]);
5016      }
5017
5018      /**
5019       * Destroys an instance of Magellan and resets the url of the window.
5020       * @function
5021       */
5022
5023    }, {
5024      key: 'destroy',
5025      value: function destroy() {
5026        this.$element.off('.zf.trigger .zf.magellan').find('.' + this.options.activeClass).removeClass(this.options.activeClass);
5027
5028        if (this.options.deepLinking) {
5029          var hash = this.$active[0].getAttribute('href');
5030          window.location.hash.replace(hash, '');
5031        }
5032
5033        Foundation.unregisterPlugin(this);
5034      }
5035    }]);
5036
5037    return Magellan;
5038  }();
5039
5040  /**
5041   * Default settings for plugin
5042   */
5043
5044
5045  Magellan.defaults = {
5046    /**
5047     * Amount of time, in ms, the animated scrolling should take between locations.
5048     * @option
5049     * @example 500
5050     */
5051    animationDuration: 500,
5052    /**
5053     * Animation style to use when scrolling between locations.
5054     * @option
5055     * @example 'ease-in-out'
5056     */
5057    animationEasing: 'linear',
5058    /**
5059     * Number of pixels to use as a marker for location changes.
5060     * @option
5061     * @example 50
5062     */
5063    threshold: 50,
5064    /**
5065     * Class applied to the active locations link on the magellan container.
5066     * @option
5067     * @example 'active'
5068     */
5069    activeClass: 'active',
5070    /**
5071     * Allows the script to manipulate the url of the current page, and if supported, alter the history.
5072     * @option
5073     * @example true
5074     */
5075    deepLinking: false,
5076    /**
5077     * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
5078     * @option
5079     * @example 25
5080     */
5081    barOffset: 0
5082  };
5083
5084  // Window exports
5085  Foundation.plugin(Magellan, 'Magellan');
5086}(jQuery);
5087'use strict';
5088
5089var _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; }; }();
5090
5091function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5092
5093!function ($) {
5094
5095  /**
5096   * OffCanvas module.
5097   * @module foundation.offcanvas
5098   * @requires foundation.util.mediaQuery
5099   * @requires foundation.util.triggers
5100   * @requires foundation.util.motion
5101   */
5102
5103  var OffCanvas = function () {
5104    /**
5105     * Creates a new instance of an off-canvas wrapper.
5106     * @class
5107     * @fires OffCanvas#init
5108     * @param {Object} element - jQuery object to initialize.
5109     * @param {Object} options - Overrides to the default plugin settings.
5110     */
5111
5112    function OffCanvas(element, options) {
5113      _classCallCheck(this, OffCanvas);
5114
5115      this.$element = element;
5116      this.options = $.extend({}, OffCanvas.defaults, this.$element.data(), options);
5117      this.$lastTrigger = $();
5118      this.$triggers = $();
5119
5120      this._init();
5121      this._events();
5122
5123      Foundation.registerPlugin(this, 'OffCanvas');
5124    }
5125
5126    /**
5127     * Initializes the off-canvas wrapper by adding the exit overlay (if needed).
5128     * @function
5129     * @private
5130     */
5131
5132
5133    _createClass(OffCanvas, [{
5134      key: '_init',
5135      value: function _init() {
5136        var id = this.$element.attr('id');
5137
5138        this.$element.attr('aria-hidden', 'true');
5139
5140        // Find triggers that affect this element and add aria-expanded to them
5141        this.$triggers = $(document).find('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-expanded', 'false').attr('aria-controls', id);
5142
5143        // Add a close trigger over the body if necessary
5144        if (this.options.closeOnClick) {
5145          if ($('.js-off-canvas-exit').length) {
5146            this.$exiter = $('.js-off-canvas-exit');
5147          } else {
5148            var exiter = document.createElement('div');
5149            exiter.setAttribute('class', 'js-off-canvas-exit');
5150            $('[data-off-canvas-content]').append(exiter);
5151
5152            this.$exiter = $(exiter);
5153          }
5154        }
5155
5156        this.options.isRevealed = this.options.isRevealed || new RegExp(this.options.revealClass, 'g').test(this.$element[0].className);
5157
5158        if (this.options.isRevealed) {
5159          this.options.revealOn = this.options.revealOn || this.$element[0].className.match(/(reveal-for-medium|reveal-for-large)/g)[0].split('-')[2];
5160          this._setMQChecker();
5161        }
5162        if (!this.options.transitionTime) {
5163          this.options.transitionTime = parseFloat(window.getComputedStyle($('[data-off-canvas-wrapper]')[0]).transitionDuration) * 1000;
5164        }
5165      }
5166
5167      /**
5168       * Adds event handlers to the off-canvas wrapper and the exit overlay.
5169       * @function
5170       * @private
5171       */
5172
5173    }, {
5174      key: '_events',
5175      value: function _events() {
5176        this.$element.off('.zf.trigger .zf.offcanvas').on({
5177          'open.zf.trigger': this.open.bind(this),
5178          'close.zf.trigger': this.close.bind(this),
5179          'toggle.zf.trigger': this.toggle.bind(this),
5180          'keydown.zf.offcanvas': this._handleKeyboard.bind(this)
5181        });
5182
5183        if (this.options.closeOnClick && this.$exiter.length) {
5184          this.$exiter.on({ 'click.zf.offcanvas': this.close.bind(this) });
5185        }
5186      }
5187
5188      /**
5189       * Applies event listener for elements that will reveal at certain breakpoints.
5190       * @private
5191       */
5192
5193    }, {
5194      key: '_setMQChecker',
5195      value: function _setMQChecker() {
5196        var _this = this;
5197
5198        $(window).on('changed.zf.mediaquery', function () {
5199          if (Foundation.MediaQuery.atLeast(_this.options.revealOn)) {
5200            _this.reveal(true);
5201          } else {
5202            _this.reveal(false);
5203          }
5204        }).one('load.zf.offcanvas', function () {
5205          if (Foundation.MediaQuery.atLeast(_this.options.revealOn)) {
5206            _this.reveal(true);
5207          }
5208        });
5209      }
5210
5211      /**
5212       * Handles the revealing/hiding the off-canvas at breakpoints, not the same as open.
5213       * @param {Boolean} isRevealed - true if element should be revealed.
5214       * @function
5215       */
5216
5217    }, {
5218      key: 'reveal',
5219      value: function reveal(isRevealed) {
5220        var $closer = this.$element.find('[data-close]');
5221        if (isRevealed) {
5222          this.close();
5223          this.isRevealed = true;
5224          // if (!this.options.forceTop) {
5225          //   var scrollPos = parseInt(window.pageYOffset);
5226          //   this.$element[0].style.transform = 'translate(0,' + scrollPos + 'px)';
5227          // }
5228          // if (this.options.isSticky) { this._stick(); }
5229          this.$element.off('open.zf.trigger toggle.zf.trigger');
5230          if ($closer.length) {
5231            $closer.hide();
5232          }
5233        } else {
5234          this.isRevealed = false;
5235          // if (this.options.isSticky || !this.options.forceTop) {
5236          //   this.$element[0].style.transform = '';
5237          //   $(window).off('scroll.zf.offcanvas');
5238          // }
5239          this.$element.on({
5240            'open.zf.trigger': this.open.bind(this),
5241            'toggle.zf.trigger': this.toggle.bind(this)
5242          });
5243          if ($closer.length) {
5244            $closer.show();
5245          }
5246        }
5247      }
5248
5249      /**
5250       * Opens the off-canvas menu.
5251       * @function
5252       * @param {Object} event - Event object passed from listener.
5253       * @param {jQuery} trigger - element that triggered the off-canvas to open.
5254       * @fires OffCanvas#opened
5255       */
5256
5257    }, {
5258      key: 'open',
5259      value: function open(event, trigger) {
5260        if (this.$element.hasClass('is-open') || this.isRevealed) {
5261          return;
5262        }
5263        var _this = this,
5264            $body = $(document.body);
5265
5266        if (this.options.forceTop) {
5267          $('body').scrollTop(0);
5268        }
5269        // window.pageYOffset = 0;
5270
5271        // if (!this.options.forceTop) {
5272        //   var scrollPos = parseInt(window.pageYOffset);
5273        //   this.$element[0].style.transform = 'translate(0,' + scrollPos + 'px)';
5274        //   if (this.$exiter.length) {
5275        //     this.$exiter[0].style.transform = 'translate(0,' + scrollPos + 'px)';
5276        //   }
5277        // }
5278        /**
5279         * Fires when the off-canvas menu opens.
5280         * @event OffCanvas#opened
5281         */
5282        Foundation.Move(this.options.transitionTime, this.$element, function () {
5283          $('[data-off-canvas-wrapper]').addClass('is-off-canvas-open is-open-' + _this.options.position);
5284
5285          _this.$element.addClass('is-open');
5286
5287          // if (_this.options.isSticky) {
5288          //   _this._stick();
5289          // }
5290        });
5291
5292        this.$triggers.attr('aria-expanded', 'true');
5293        this.$element.attr('aria-hidden', 'false').trigger('opened.zf.offcanvas');
5294
5295        if (this.options.closeOnClick) {
5296          this.$exiter.addClass('is-visible');
5297        }
5298
5299        if (trigger) {
5300          this.$lastTrigger = trigger;
5301        }
5302
5303        if (this.options.autoFocus) {
5304          this.$element.one(Foundation.transitionend(this.$element), function () {
5305            _this.$element.find('a, button').eq(0).focus();
5306          });
5307        }
5308
5309        if (this.options.trapFocus) {
5310          $('[data-off-canvas-content]').attr('tabindex', '-1');
5311          this._trapFocus();
5312        }
5313      }
5314
5315      /**
5316       * Traps focus within the offcanvas on open.
5317       * @private
5318       */
5319
5320    }, {
5321      key: '_trapFocus',
5322      value: function _trapFocus() {
5323        var focusable = Foundation.Keyboard.findFocusable(this.$element),
5324            first = focusable.eq(0),
5325            last = focusable.eq(-1);
5326
5327        focusable.off('.zf.offcanvas').on('keydown.zf.offcanvas', function (e) {
5328          if (e.which === 9 || e.keycode === 9) {
5329            if (e.target === last[0] && !e.shiftKey) {
5330              e.preventDefault();
5331              first.focus();
5332            }
5333            if (e.target === first[0] && e.shiftKey) {
5334              e.preventDefault();
5335              last.focus();
5336            }
5337          }
5338        });
5339      }
5340
5341      /**
5342       * Allows the offcanvas to appear sticky utilizing translate properties.
5343       * @private
5344       */
5345      // OffCanvas.prototype._stick = function() {
5346      //   var elStyle = this.$element[0].style;
5347      //
5348      //   if (this.options.closeOnClick) {
5349      //     var exitStyle = this.$exiter[0].style;
5350      //   }
5351      //
5352      //   $(window).on('scroll.zf.offcanvas', function(e) {
5353      //     console.log(e);
5354      //     var pageY = window.pageYOffset;
5355      //     elStyle.transform = 'translate(0,' + pageY + 'px)';
5356      //     if (exitStyle !== undefined) { exitStyle.transform = 'translate(0,' + pageY + 'px)'; }
5357      //   });
5358      //   // this.$element.trigger('stuck.zf.offcanvas');
5359      // };
5360      /**
5361       * Closes the off-canvas menu.
5362       * @function
5363       * @param {Function} cb - optional cb to fire after closure.
5364       * @fires OffCanvas#closed
5365       */
5366
5367    }, {
5368      key: 'close',
5369      value: function close(cb) {
5370        if (!this.$element.hasClass('is-open') || this.isRevealed) {
5371          return;
5372        }
5373
5374        var _this = this;
5375
5376        //  Foundation.Move(this.options.transitionTime, this.$element, function() {
5377        $('[data-off-canvas-wrapper]').removeClass('is-off-canvas-open is-open-' + _this.options.position);
5378        _this.$element.removeClass('is-open');
5379        // Foundation._reflow();
5380        // });
5381        this.$element.attr('aria-hidden', 'true')
5382        /**
5383         * Fires when the off-canvas menu opens.
5384         * @event OffCanvas#closed
5385         */
5386        .trigger('closed.zf.offcanvas');
5387        // if (_this.options.isSticky || !_this.options.forceTop) {
5388        //   setTimeout(function() {
5389        //     _this.$element[0].style.transform = '';
5390        //     $(window).off('scroll.zf.offcanvas');
5391        //   }, this.options.transitionTime);
5392        // }
5393        if (this.options.closeOnClick) {
5394          this.$exiter.removeClass('is-visible');
5395        }
5396
5397        this.$triggers.attr('aria-expanded', 'false');
5398        if (this.options.trapFocus) {
5399          $('[data-off-canvas-content]').removeAttr('tabindex');
5400        }
5401      }
5402
5403      /**
5404       * Toggles the off-canvas menu open or closed.
5405       * @function
5406       * @param {Object} event - Event object passed from listener.
5407       * @param {jQuery} trigger - element that triggered the off-canvas to open.
5408       */
5409
5410    }, {
5411      key: 'toggle',
5412      value: function toggle(event, trigger) {
5413        if (this.$element.hasClass('is-open')) {
5414          this.close(event, trigger);
5415        } else {
5416          this.open(event, trigger);
5417        }
5418      }
5419
5420      /**
5421       * 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.
5422       * @function
5423       * @private
5424       */
5425
5426    }, {
5427      key: '_handleKeyboard',
5428      value: function _handleKeyboard(event) {
5429        if (event.which !== 27) return;
5430
5431        event.stopPropagation();
5432        event.preventDefault();
5433        this.close();
5434        this.$lastTrigger.focus();
5435      }
5436
5437      /**
5438       * Destroys the offcanvas plugin.
5439       * @function
5440       */
5441
5442    }, {
5443      key: 'destroy',
5444      value: function destroy() {
5445        this.close();
5446        this.$element.off('.zf.trigger .zf.offcanvas');
5447        this.$exiter.off('.zf.offcanvas');
5448
5449        Foundation.unregisterPlugin(this);
5450      }
5451    }]);
5452
5453    return OffCanvas;
5454  }();
5455
5456  OffCanvas.defaults = {
5457    /**
5458     * Allow the user to click outside of the menu to close it.
5459     * @option
5460     * @example true
5461     */
5462    closeOnClick: true,
5463
5464    /**
5465     * Amount of time in ms the open and close transition requires. If none selected, pulls from body style.
5466     * @option
5467     * @example 500
5468     */
5469    transitionTime: 0,
5470
5471    /**
5472     * Direction the offcanvas opens from. Determines class applied to body.
5473     * @option
5474     * @example left
5475     */
5476    position: 'left',
5477
5478    /**
5479     * Force the page to scroll to top on open.
5480     * @option
5481     * @example true
5482     */
5483    forceTop: true,
5484
5485    /**
5486     * Allow the offcanvas to remain open for certain breakpoints.
5487     * @option
5488     * @example false
5489     */
5490    isRevealed: false,
5491
5492    /**
5493     * Breakpoint at which to reveal. JS will use a RegExp to target standard classes, if changing classnames, pass your class with the `revealClass` option.
5494     * @option
5495     * @example reveal-for-large
5496     */
5497    revealOn: null,
5498
5499    /**
5500     * Force focus to the offcanvas on open. If true, will focus the opening trigger on close.
5501     * @option
5502     * @example true
5503     */
5504    autoFocus: true,
5505
5506    /**
5507     * Class used to force an offcanvas to remain open. Foundation defaults for this are `reveal-for-large` & `reveal-for-medium`.
5508     * @option
5509     * TODO improve the regex testing for this.
5510     * @example reveal-for-large
5511     */
5512    revealClass: 'reveal-for-',
5513
5514    /**
5515     * Triggers optional focus trapping when opening an offcanvas. Sets tabindex of [data-off-canvas-content] to -1 for accessibility purposes.
5516     * @option
5517     * @example true
5518     */
5519    trapFocus: false
5520  };
5521
5522  // Window exports
5523  Foundation.plugin(OffCanvas, 'OffCanvas');
5524}(jQuery);
5525'use strict';
5526
5527var _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; }; }();
5528
5529function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5530
5531!function ($) {
5532
5533  /**
5534   * Orbit module.
5535   * @module foundation.orbit
5536   * @requires foundation.util.keyboard
5537   * @requires foundation.util.motion
5538   * @requires foundation.util.timerAndImageLoader
5539   * @requires foundation.util.touch
5540   */
5541
5542  var Orbit = function () {
5543    /**
5544    * Creates a new instance of an orbit carousel.
5545    * @class
5546    * @param {jQuery} element - jQuery object to make into an Orbit Carousel.
5547    * @param {Object} options - Overrides to the default plugin settings.
5548    */
5549
5550    function Orbit(element, options) {
5551      _classCallCheck(this, Orbit);
5552
5553      this.$element = element;
5554      this.options = $.extend({}, Orbit.defaults, this.$element.data(), options);
5555
5556      this._init();
5557
5558      Foundation.registerPlugin(this, 'Orbit');
5559      Foundation.Keyboard.register('Orbit', {
5560        'ltr': {
5561          'ARROW_RIGHT': 'next',
5562          'ARROW_LEFT': 'previous'
5563        },
5564        'rtl': {
5565          'ARROW_LEFT': 'next',
5566          'ARROW_RIGHT': 'previous'
5567        }
5568      });
5569    }
5570
5571    /**
5572    * Initializes the plugin by creating jQuery collections, setting attributes, and starting the animation.
5573    * @function
5574    * @private
5575    */
5576
5577
5578    _createClass(Orbit, [{
5579      key: '_init',
5580      value: function _init() {
5581        this.$wrapper = this.$element.find('.' + this.options.containerClass);
5582        this.$slides = this.$element.find('.' + this.options.slideClass);
5583        var $images = this.$element.find('img'),
5584            initActive = this.$slides.filter('.is-active');
5585
5586        if (!initActive.length) {
5587          this.$slides.eq(0).addClass('is-active');
5588        }
5589
5590        if (!this.options.useMUI) {
5591          this.$slides.addClass('no-motionui');
5592        }
5593
5594        if ($images.length) {
5595          Foundation.onImagesLoaded($images, this._prepareForOrbit.bind(this));
5596        } else {
5597          this._prepareForOrbit(); //hehe
5598        }
5599
5600        if (this.options.bullets) {
5601          this._loadBullets();
5602        }
5603
5604        this._events();
5605
5606        if (this.options.autoPlay && this.$slides.length > 1) {
5607          this.geoSync();
5608        }
5609
5610        if (this.options.accessible) {
5611          // allow wrapper to be focusable to enable arrow navigation
5612          this.$wrapper.attr('tabindex', 0);
5613        }
5614      }
5615
5616      /**
5617      * Creates a jQuery collection of bullets, if they are being used.
5618      * @function
5619      * @private
5620      */
5621
5622    }, {
5623      key: '_loadBullets',
5624      value: function _loadBullets() {
5625        this.$bullets = this.$element.find('.' + this.options.boxOfBullets).find('button');
5626      }
5627
5628      /**
5629      * Sets a `timer` object on the orbit, and starts the counter for the next slide.
5630      * @function
5631      */
5632
5633    }, {
5634      key: 'geoSync',
5635      value: function geoSync() {
5636        var _this = this;
5637        this.timer = new Foundation.Timer(this.$element, {
5638          duration: this.options.timerDelay,
5639          infinite: false
5640        }, function () {
5641          _this.changeSlide(true);
5642        });
5643        this.timer.start();
5644      }
5645
5646      /**
5647      * Sets wrapper and slide heights for the orbit.
5648      * @function
5649      * @private
5650      */
5651
5652    }, {
5653      key: '_prepareForOrbit',
5654      value: function _prepareForOrbit() {
5655        var _this = this;
5656        this._setWrapperHeight(function (max) {
5657          _this._setSlideHeight(max);
5658        });
5659      }
5660
5661      /**
5662      * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height.
5663      * @function
5664      * @private
5665      * @param {Function} cb - a callback function to fire when complete.
5666      */
5667
5668    }, {
5669      key: '_setWrapperHeight',
5670      value: function _setWrapperHeight(cb) {
5671        //rewrite this to `for` loop
5672        var max = 0,
5673            temp,
5674            counter = 0;
5675
5676        this.$slides.each(function () {
5677          temp = this.getBoundingClientRect().height;
5678          $(this).attr('data-slide', counter);
5679
5680          if (counter) {
5681            //if not the first slide, set css position and display property
5682            $(this).css({ 'position': 'relative', 'display': 'none' });
5683          }
5684          max = temp > max ? temp : max;
5685          counter++;
5686        });
5687
5688        if (counter === this.$slides.length) {
5689          this.$wrapper.css({ 'height': max }); //only change the wrapper height property once.
5690          cb(max); //fire callback with max height dimension.
5691        }
5692      }
5693
5694      /**
5695      * Sets the max-height of each slide.
5696      * @function
5697      * @private
5698      */
5699
5700    }, {
5701      key: '_setSlideHeight',
5702      value: function _setSlideHeight(height) {
5703        this.$slides.each(function () {
5704          $(this).css('max-height', height);
5705        });
5706      }
5707
5708      /**
5709      * Adds event listeners to basically everything within the element.
5710      * @function
5711      * @private
5712      */
5713
5714    }, {
vendor: 6,343 bytes, lines 5715-5858
5715      key: '_events',
5716      value: function _events() {
5717        var _this = this;
5718
5719        //***************************************
5720        //**Now using custom event - thanks to:**
5721        //**      Yohai Ararat of Toronto      **
5722        //***************************************
5723        if (this.$slides.length > 1) {
5724
5725          if (this.options.swipe) {
5726            this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit').on('swipeleft.zf.orbit', function (e) {
5727              e.preventDefault();
5728              _this.changeSlide(true);
5729            }).on('swiperight.zf.orbit', function (e) {
5730              e.preventDefault();
5731              _this.changeSlide(false);
5732            });
5733          }
5734          //***************************************
5735
5736          if (this.options.autoPlay) {
5737            this.$slides.on('click.zf.orbit', function () {
5738              _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true);
5739              _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start']();
5740            });
5741
5742            if (this.options.pauseOnHover) {
5743              this.$element.on('mouseenter.zf.orbit', function () {
5744                _this.timer.pause();
5745              }).on('mouseleave.zf.orbit', function () {
5746                if (!_this.$element.data('clickedOn')) {
5747                  _this.timer.start();
5748                }
5749              });
5750            }
5751          }
5752
5753          if (this.options.navButtons) {
5754            var $controls = this.$element.find('.' + this.options.nextClass + ', .' + this.options.prevClass);
5755            $controls.attr('tabindex', 0)
5756            //also need to handle enter/return and spacebar key presses
5757            .on('click.zf.orbit touchend.zf.orbit', function (e) {
5758              e.preventDefault();
5759              _this.changeSlide($(this).hasClass(_this.options.nextClass));
5760            });
5761          }
5762
5763          if (this.options.bullets) {
5764            this.$bullets.on('click.zf.orbit touchend.zf.orbit', function () {
5765              if (/is-active/g.test(this.className)) {
5766                return false;
5767              } //if this is active, kick out of function.
5768              var idx = $(this).data('slide'),
5769                  ltr = idx > _this.$slides.filter('.is-active').data('slide'),
5770                  $slide = _this.$slides.eq(idx);
5771
5772              _this.changeSlide(ltr, $slide, idx);
5773            });
5774          }
5775
5776          this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function (e) {
5777            // handle keyboard event with keyboard util
5778            Foundation.Keyboard.handleKey(e, 'Orbit', {
5779              next: function () {
5780                _this.changeSlide(true);
5781              },
5782              previous: function () {
5783                _this.changeSlide(false);
5784              },
5785              handled: function () {
5786                // if bullet is focused, make sure focus moves
5787                if ($(e.target).is(_this.$bullets)) {
5788                  _this.$bullets.filter('.is-active').focus();
5789                }
5790              }
5791            });
5792          });
5793        }
5794      }
5795
5796      /**
5797      * Changes the current slide to a new one.
5798      * @function
5799      * @param {Boolean} isLTR - flag if the slide should move left to right.
5800      * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected.
5801      * @param {Number} idx - the index of the new slide in its collection, if one chosen.
5802      * @fires Orbit#slidechange
5803      */
5804
5805    }, {
5806      key: 'changeSlide',
5807      value: function changeSlide(isLTR, chosenSlide, idx) {
5808        var $curSlide = this.$slides.filter('.is-active').eq(0);
5809
5810        if (/mui/g.test($curSlide[0].className)) {
5811          return false;
5812        } //if the slide is currently animating, kick out of the function
5813
5814        var $firstSlide = this.$slides.first(),
5815            $lastSlide = this.$slides.last(),
5816            dirIn = isLTR ? 'Right' : 'Left',
5817            dirOut = isLTR ? 'Left' : 'Right',
5818            _this = this,
5819            $newSlide;
5820
5821        if (!chosenSlide) {
5822          //most of the time, this will be auto played or clicked from the navButtons.
5823          $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!!!!!
5824          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
5825          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
5826        } else {
5827            $newSlide = chosenSlide;
5828          }
5829
5830        if ($newSlide.length) {
5831          if (this.options.bullets) {
5832            idx = idx || this.$slides.index($newSlide); //grab index to update bullets
5833            this._updateBullets(idx);
5834          }
5835
5836          if (this.options.useMUI) {
5837            Foundation.Motion.animateIn($newSlide.addClass('is-active').css({ 'position': 'absolute', 'top': 0 }), this.options['animInFrom' + dirIn], function () {
5838              $newSlide.css({ 'position': 'relative', 'display': 'block' }).attr('aria-live', 'polite');
5839            });
5840
5841            Foundation.Motion.animateOut($curSlide.removeClass('is-active'), this.options['animOutTo' + dirOut], function () {
5842              $curSlide.removeAttr('aria-live');
5843              if (_this.options.autoPlay && !_this.timer.isPaused) {
5844                _this.timer.restart();
5845              }
5846              //do stuff?
5847            });
5848          } else {
5849              $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide();
5850              $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show();
5851              if (this.options.autoPlay && !this.timer.isPaused) {
5852                this.timer.restart();
5853              }
5854            }
5855          /**
5856          * Triggers when the slide has finished animating in.
5857          * @event Orbit#slidechange
5858          */
5859          this.$element.trigger('slidechange.zf.orbit', [$newSlide]);
5860        }
5861      }
5862
5863      /**
5864      * Updates the active state of the bullets, if displayed.
5865      * @function
5866      * @private
5867      * @param {Number} idx - the index of the current slide.
5868      */
5869
5870    }, {
5871      key: '_updateBullets',
5872      value: function _updateBullets(idx) {
5873        var $oldBullet = this.$element.find('.' + this.options.boxOfBullets).find('.is-active').removeClass('is-active').blur(),
5874            span = $oldBullet.find('span:last').detach(),
5875            $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span);
5876      }
5877
5878      /**
5879      * Destroys the carousel and hides the element.
5880      * @function
5881      */
5882
5883    }, {
5884      key: 'destroy',
5885      value: function destroy() {
5886        this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide();
5887        Foundation.unregisterPlugin(this);
5888      }
5889    }]);
5890
5891    return Orbit;
5892  }();
5893
5894  Orbit.defaults = {
5895    /**
5896    * Tells the JS to look for and loadBullets.
5897    * @option
5898    * @example true
5899    */
5900    bullets: true,
5901    /**
5902    * Tells the JS to apply event listeners to nav buttons
5903    * @option
5904    * @example true
5905    */
5906    navButtons: true,
5907    /**
5908    * motion-ui animation class to apply
5909    * @option
5910    * @example 'slide-in-right'
5911    */
5912    animInFromRight: 'slide-in-right',
5913    /**
5914    * motion-ui animation class to apply
5915    * @option
5916    * @example 'slide-out-right'
5917    */
5918    animOutToRight: 'slide-out-right',
5919    /**
5920    * motion-ui animation class to apply
5921    * @option
5922    * @example 'slide-in-left'
5923    *
5924    */
5925    animInFromLeft: 'slide-in-left',
5926    /**
5927    * motion-ui animation class to apply
5928    * @option
5929    * @example 'slide-out-left'
5930    */
5931    animOutToLeft: 'slide-out-left',
5932    /**
5933    * Allows Orbit to automatically animate on page load.
5934    * @option
5935    * @example true
5936    */
5937    autoPlay: true,
5938    /**
5939    * Amount of time, in ms, between slide transitions
5940    * @option
5941    * @example 5000
5942    */
5943    timerDelay: 5000,
5944    /**
5945    * Allows Orbit to infinitely loop through the slides
5946    * @option
5947    * @example true
5948    */
5949    infiniteWrap: true,
5950    /**
5951    * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library
5952    * @option
5953    * @example true
5954    */
5955    swipe: true,
5956    /**
5957    * Allows the timing function to pause animation on hover.
5958    * @option
5959    * @example true
5960    */
5961    pauseOnHover: true,
5962    /**
5963    * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys
5964    * @option
5965    * @example true
5966    */
5967    accessible: true,
5968    /**
5969    * Class applied to the container of Orbit
5970    * @option
5971    * @example 'orbit-container'
5972    */
5973    containerClass: 'orbit-container',
5974    /**
5975    * Class applied to individual slides.
5976    * @option
5977    * @example 'orbit-slide'
5978    */
5979    slideClass: 'orbit-slide',
5980    /**
5981    * Class applied to the bullet container. You're welcome.
5982    * @option
5983    * @example 'orbit-bullets'
5984    */
5985    boxOfBullets: 'orbit-bullets',
5986    /**
5987    * Class applied to the `next` navigation button.
5988    * @option
5989    * @example 'orbit-next'
5990    */
5991    nextClass: 'orbit-next',
5992    /**
5993    * Class applied to the `previous` navigation button.
5994    * @option
5995    * @example 'orbit-previous'
5996    */
5997    prevClass: 'orbit-previous',
5998    /**
5999    * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatability.
6000    * @option
6001    * @example true
6002    */
6003    useMUI: true
6004  };
6005
6006  // Window exports
6007  Foundation.plugin(Orbit, 'Orbit');
6008}(jQuery);
6009'use strict';
6010
6011var _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; }; }();
6012
6013function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6014
6015!function ($) {
6016
6017  /**
6018   * ResponsiveMenu module.
6019   * @module foundation.responsiveMenu
6020   * @requires foundation.util.triggers
6021   * @requires foundation.util.mediaQuery
6022   * @requires foundation.util.accordionMenu
6023   * @requires foundation.util.drilldown
6024   * @requires foundation.util.dropdown-menu
6025   */
6026
6027  var ResponsiveMenu = function () {
6028    /**
6029     * Creates a new instance of a responsive menu.
6030     * @class
6031     * @fires ResponsiveMenu#init
6032     * @param {jQuery} element - jQuery object to make into a dropdown menu.
6033     * @param {Object} options - Overrides to the default plugin settings.
6034     */
6035
6036    function ResponsiveMenu(element, options) {
6037      _classCallCheck(this, ResponsiveMenu);
6038
6039      this.$element = $(element);
6040      this.rules = this.$element.data('responsive-menu');
6041      this.currentMq = null;
6042      this.currentPlugin = null;
6043
6044      this._init();
6045      this._events();
6046
6047      Foundation.registerPlugin(this, 'ResponsiveMenu');
6048    }
6049
6050    /**
6051     * Initializes the Menu by parsing the classes from the 'data-ResponsiveMenu' attribute on the element.
6052     * @function
6053     * @private
6054     */
6055
6056
6057    _createClass(ResponsiveMenu, [{
6058      key: '_init',
6059      value: function _init() {
6060        // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules
6061        if (typeof this.rules === 'string') {
6062          var rulesTree = {};
6063
6064          // Parse rules from "classes" pulled from data attribute
6065          var rules = this.rules.split(' ');
6066
6067          // Iterate through every rule found
6068          for (var i = 0; i < rules.length; i++) {
6069            var rule = rules[i].split('-');
6070            var ruleSize = rule.length > 1 ? rule[0] : 'small';
6071            var rulePlugin = rule.length > 1 ? rule[1] : rule[0];
6072
6073            if (MenuPlugins[rulePlugin] !== null) {
6074              rulesTree[ruleSize] = MenuPlugins[rulePlugin];
6075            }
6076          }
6077
6078          this.rules = rulesTree;
6079        }
6080
6081        if (!$.isEmptyObject(this.rules)) {
6082          this._checkMediaQueries();
6083        }
6084      }
6085
6086      /**
6087       * Initializes events for the Menu.
6088       * @function
6089       * @private
6090       */
6091
6092    }, {
6093      key: '_events',
6094      value: function _events() {
6095        var _this = this;
6096
6097        $(window).on('changed.zf.mediaquery', function () {
6098          _this._checkMediaQueries();
6099        });
6100        // $(window).on('resize.zf.ResponsiveMenu', function() {
6101        //   _this._checkMediaQueries();
6102        // });
6103      }
6104
6105      /**
6106       * 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.
6107       * @function
6108       * @private
6109       */
6110
6111    }, {
6112      key: '_checkMediaQueries',
6113      value: function _checkMediaQueries() {
6114        var matchedMq,
6115            _this = this;
6116        // Iterate through each rule and find the last matching rule
6117        $.each(this.rules, function (key) {
6118          if (Foundation.MediaQuery.atLeast(key)) {
6119            matchedMq = key;
6120          }
6121        });
6122
6123        // No match? No dice
6124        if (!matchedMq) return;
6125
6126        // Plugin already initialized? We good
6127        if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return;
6128
6129        // Remove existing plugin-specific CSS classes
6130        $.each(MenuPlugins, function (key, value) {
6131          _this.$element.removeClass(value.cssClass);
6132        });
6133
6134        // Add the CSS class for the new plugin
6135        this.$element.addClass(this.rules[matchedMq].cssClass);
6136
6137        // Create an instance of the new plugin
6138        if (this.currentPlugin) this.currentPlugin.destroy();
6139        this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {});
6140      }
6141
6142      /**
6143       * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out.
6144       * @function
6145       */
6146
6147    }, {
6148      key: 'destroy',
6149      value: function destroy() {
6150        this.currentPlugin.destroy();
6151        $(window).off('.zf.ResponsiveMenu');
6152        Foundation.unregisterPlugin(this);
6153      }
6154    }]);
6155
6156    return ResponsiveMenu;
6157  }();
6158
6159  ResponsiveMenu.defaults = {};
6160
6161  // The plugin matches the plugin classes with these plugin instances.
6162  var MenuPlugins = {
6163    dropdown: {
6164      cssClass: 'dropdown',
6165      plugin: Foundation._plugins['dropdown-menu'] || null
6166    },
6167    drilldown: {
6168      cssClass: 'drilldown',
6169      plugin: Foundation._plugins['drilldown'] || null
6170    },
6171    accordion: {
6172      cssClass: 'accordion-menu',
6173      plugin: Foundation._plugins['accordion-menu'] || null
6174    }
6175  };
6176
6177  // Window exports
6178  Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu');
6179}(jQuery);
6180'use strict';
6181
6182var _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; }; }();
6183
6184function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6185
6186!function ($) {
6187
6188  /**
6189   * ResponsiveToggle module.
6190   * @module foundation.responsiveToggle
6191   * @requires foundation.util.mediaQuery
6192   */
6193
6194  var ResponsiveToggle = function () {
6195    /**
6196     * Creates a new instance of Tab Bar.
6197     * @class
6198     * @fires ResponsiveToggle#init
6199     * @param {jQuery} element - jQuery object to attach tab bar functionality to.
6200     * @param {Object} options - Overrides to the default plugin settings.
6201     */
6202
6203    function ResponsiveToggle(element, options) {
6204      _classCallCheck(this, ResponsiveToggle);
6205
6206      this.$element = $(element);
6207      this.options = $.extend({}, ResponsiveToggle.defaults, this.$element.data(), options);
6208
6209      this._init();
6210      this._events();
6211
6212      Foundation.registerPlugin(this, 'ResponsiveToggle');
6213    }
6214
6215    /**
6216     * Initializes the tab bar by finding the target element, toggling element, and running update().
6217     * @function
6218     * @private
6219     */
6220
6221
6222    _createClass(ResponsiveToggle, [{
6223      key: '_init',
6224      value: function _init() {
6225        var targetID = this.$element.data('responsive-toggle');
6226        if (!targetID) {
6227          console.error('Your tab bar needs an ID of a Menu as the value of data-tab-bar.');
6228        }
6229
6230        this.$targetMenu = $('#' + targetID);
6231        this.$toggler = this.$element.find('[data-toggle]');
6232
6233        this._update();
6234      }
6235
6236      /**
6237       * Adds necessary event handlers for the tab bar to work.
6238       * @function
6239       * @private
6240       */
6241
6242    }, {
6243      key: '_events',
6244      value: function _events() {
6245        var _this = this;
6246
6247        this._updateMqHandler = this._update.bind(this);
6248
6249        $(window).on('changed.zf.mediaquery', this._updateMqHandler);
6250
6251        this.$toggler.on('click.zf.responsiveToggle', this.toggleMenu.bind(this));
6252      }
6253
6254      /**
6255       * Checks the current media query to determine if the tab bar should be visible or hidden.
6256       * @function
6257       * @private
6258       */
6259
6260    }, {
6261      key: '_update',
6262      value: function _update() {
6263        // Mobile
6264        if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
6265          this.$element.show();
6266          this.$targetMenu.hide();
6267        }
6268
6269        // Desktop
6270        else {
6271            this.$element.hide();
6272            this.$targetMenu.show();
6273          }
6274      }
6275
6276      /**
6277       * Toggles the element attached to the tab bar. The toggle only happens if the screen is small enough to allow it.
6278       * @function
6279       * @fires ResponsiveToggle#toggled
6280       */
6281
6282    }, {
6283      key: 'toggleMenu',
6284      value: function toggleMenu() {
6285        if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
6286          this.$targetMenu.toggle(0);
6287
6288          /**
6289           * Fires when the element attached to the tab bar toggles.
6290           * @event ResponsiveToggle#toggled
6291           */
6292          this.$element.trigger('toggled.zf.responsiveToggle');
6293        }
6294      }
6295    }, {
6296      key: 'destroy',
6297      value: function destroy() {
6298        this.$element.off('.zf.responsiveToggle');
6299        this.$toggler.off('.zf.responsiveToggle');
6300
6301        $(window).off('changed.zf.mediaquery', this._updateMqHandler);
6302
6303        Foundation.unregisterPlugin(this);
6304      }
6305    }]);
6306
6307    return ResponsiveToggle;
6308  }();
6309
6310  ResponsiveToggle.defaults = {
6311    /**
6312     * The breakpoint after which the menu is always shown, and the tab bar is hidden.
6313     * @option
6314     * @example 'medium'
6315     */
6316    hideFor: 'medium'
6317  };
6318
6319  // Window exports
6320  Foundation.plugin(ResponsiveToggle, 'ResponsiveToggle');
6321}(jQuery);
6322'use strict';
6323
6324var _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; }; }();
6325
6326function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6327
6328!function ($) {
6329
6330  /**
6331   * Reveal module.
6332   * @module foundation.reveal
6333   * @requires foundation.util.keyboard
6334   * @requires foundation.util.box
6335   * @requires foundation.util.triggers
6336   * @requires foundation.util.mediaQuery
6337   * @requires foundation.util.motion if using animations
6338   */
6339
6340  var Reveal = function () {
6341    /**
6342     * Creates a new instance of Reveal.
6343     * @class
6344     * @param {jQuery} element - jQuery object to use for the modal.
6345     * @param {Object} options - optional parameters.
6346     */
6347
6348    function Reveal(element, options) {
6349      _classCallCheck(this, Reveal);
6350
6351      this.$element = element;
6352      this.options = $.extend({}, Reveal.defaults, this.$element.data(), options);
6353      this._init();
6354
6355      Foundation.registerPlugin(this, 'Reveal');
6356      Foundation.Keyboard.register('Reveal', {
6357        'ENTER': 'open',
6358        'SPACE': 'open',
6359        'ESCAPE': 'close',
6360        'TAB': 'tab_forward',
6361        'SHIFT_TAB': 'tab_backward'
6362      });
6363    }
6364
6365    /**
6366     * Initializes the modal by adding the overlay and close buttons, (if selected).
6367     * @private
6368     */
6369
6370
6371    _createClass(Reveal, [{
6372      key: '_init',
6373      value: function _init() {
6374        this.id = this.$element.attr('id');
6375        this.isActive = false;
6376        this.cached = { mq: Foundation.MediaQuery.current };
6377        this.isMobile = mobileSniff();
6378
6379        this.$anchor = $('[data-open="' + this.id + '"]').length ? $('[data-open="' + this.id + '"]') : $('[data-toggle="' + this.id + '"]');
6380        this.$anchor.attr({
6381          'aria-controls': this.id,
6382          'aria-haspopup': true,
6383          'tabindex': 0
6384        });
6385
6386        if (this.options.fullScreen || this.$element.hasClass('full')) {
6387          this.options.fullScreen = true;
vendor: 4,464 bytes, lines 6388-6533
6388          this.options.overlay = false;
6389        }
6390        if (this.options.overlay && !this.$overlay) {
6391          this.$overlay = this._makeOverlay(this.id);
6392        }
6393
6394        this.$element.attr({
6395          'role': 'dialog',
6396          'aria-hidden': true,
6397          'data-yeti-box': this.id,
6398          'data-resize': this.id
6399        });
6400
6401        if (this.$overlay) {
6402          this.$element.detach().appendTo(this.$overlay);
6403        } else {
6404          this.$element.detach().appendTo($('body'));
6405          this.$element.addClass('without-overlay');
6406        }
6407        this._events();
6408        if (this.options.deepLink && window.location.hash === '#' + this.id) {
6409          $(window).one('load.zf.reveal', this.open.bind(this));
6410        }
6411      }
6412
6413      /**
6414       * Creates an overlay div to display behind the modal.
6415       * @private
6416       */
6417
6418    }, {
6419      key: '_makeOverlay',
6420      value: function _makeOverlay(id) {
6421        var $overlay = $('<div></div>').addClass('reveal-overlay').appendTo('body');
6422        return $overlay;
6423      }
6424
6425      /**
6426       * Updates position of modal
6427       * TODO:  Figure out if we actually need to cache these values or if it doesn't matter
6428       * @private
6429       */
6430
6431    }, {
6432      key: '_updatePosition',
6433      value: function _updatePosition() {
6434        var width = this.$element.outerWidth();
6435        var outerWidth = $(window).width();
6436        var height = this.$element.outerHeight();
6437        var outerHeight = $(window).height();
6438        var left, top;
6439        if (this.options.hOffset === 'auto') {
6440          left = parseInt((outerWidth - width) / 2, 10);
6441        } else {
6442          left = parseInt(this.options.hOffset, 10);
6443        }
6444        if (this.options.vOffset === 'auto') {
6445          if (height > outerHeight) {
6446            top = parseInt(Math.min(100, outerHeight / 10), 10);
6447          } else {
6448            top = parseInt((outerHeight - height) / 4, 10);
6449          }
6450        } else {
6451          top = parseInt(this.options.vOffset, 10);
6452        }
6453        this.$element.css({ top: top + 'px' });
6454        // only worry about left if we don't have an overlay or we havea  horizontal offset,
6455        // otherwise we're perfectly in the middle
6456        if (!this.$overlay || this.options.hOffset !== 'auto') {
6457          this.$element.css({ left: left + 'px' });
6458          this.$element.css({ margin: '0px' });
6459        }
6460      }
6461
6462      /**
6463       * Adds event handlers for the modal.
6464       * @private
6465       */
6466
6467    }, {
6468      key: '_events',
6469      value: function _events() {
6470        var _this2 = this;
6471
6472        var _this = this;
6473
6474        this.$element.on({
6475          'open.zf.trigger': this.open.bind(this),
6476          'close.zf.trigger': function (event, $element) {
6477            if (event.target === _this.$element[0] || $(event.target).parents('[data-closable]')[0] === $element) {
6478              // only close reveal when it's explicitly called
6479              return _this2.close.apply(_this2);
6480            }
6481          },
6482          'toggle.zf.trigger': this.toggle.bind(this),
6483          'resizeme.zf.trigger': function () {
6484            _this._updatePosition();
6485          }
6486        });
6487
6488        if (this.$anchor.length) {
6489          this.$anchor.on('keydown.zf.reveal', function (e) {
6490            if (e.which === 13 || e.which === 32) {
6491              e.stopPropagation();
6492              e.preventDefault();
6493              _this.open();
6494            }
6495          });
6496        }
6497
6498        if (this.options.closeOnClick && this.options.overlay) {
6499          this.$overlay.off('.zf.reveal').on('click.zf.reveal', function (e) {
6500            if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
6501              return;
6502            }
6503            _this.close();
6504          });
6505        }
6506        if (this.options.deepLink) {
6507          $(window).on('popstate.zf.reveal:' + this.id, this._handleState.bind(this));
6508        }
6509      }
6510
6511      /**
6512       * Handles modal methods on back/forward button clicks or any other event that triggers popstate.
6513       * @private
6514       */
6515
6516    }, {
6517      key: '_handleState',
6518      value: function _handleState(e) {
6519        if (window.location.hash === '#' + this.id && !this.isActive) {
6520          this.open();
6521        } else {
6522          this.close();
6523        }
6524      }
6525
6526      /**
6527       * Opens the modal controlled by `this.$anchor`, and closes all others by default.
6528       * @function
6529       * @fires Reveal#closeme
6530       * @fires Reveal#open
6531       */
6532
6533    }, {
6534      key: 'open',
6535      value: function open() {
6536        var _this3 = this;
6537
6538        if (this.options.deepLink) {
6539          var hash = '#' + this.id;
6540
6541          if (window.history.pushState) {
6542            window.history.pushState(null, null, hash);
6543          } else {
6544            window.location.hash = hash;
6545          }
6546        }
6547
6548        this.isActive = true;
6549
6550        // Make elements invisible, but remove display: none so we can get size and positioning
6551        this.$element.css({ 'visibility': 'hidden' }).show().scrollTop(0);
6552        if (this.options.overlay) {
6553          this.$overlay.css({ 'visibility': 'hidden' }).show();
6554        }
6555
6556        this._updatePosition();
6557
6558        this.$element.hide().css({ 'visibility': '' });
6559
6560        if (this.$overlay) {
6561          this.$overlay.css({ 'visibility': '' }).hide();
6562          if (this.$element.hasClass('fast')) {
6563            this.$overlay.addClass('fast');
6564          } else if (this.$element.hasClass('slow')) {
6565            this.$overlay.addClass('slow');
6566          }
6567        }
6568
6569        if (!this.options.multipleOpened) {
6570          /**
6571           * Fires immediately before the modal opens.
6572           * Closes any other modals that are currently open
6573           * @event Reveal#closeme
6574           */
6575          this.$element.trigger('closeme.zf.reveal', this.id);
6576        }
6577        // Motion UI method of reveal
6578        if (this.options.animationIn) {
6579          var _this;
6580
6581          (function () {
6582            var afterAnimationFocus = function () {
6583              _this.$element.attr({
6584                'aria-hidden': false,
6585                'tabindex': -1
6586              }).focus();
6587              console.log('focus');
6588            };
6589
6590            _this = _this3;
6591
6592            if (_this3.options.overlay) {
6593              Foundation.Motion.animateIn(_this3.$overlay, 'fade-in');
6594            }
6595            Foundation.Motion.animateIn(_this3.$element, _this3.options.animationIn, function () {
6596              _this3.focusableElements = Foundation.Keyboard.findFocusable(_this3.$element);
6597              afterAnimationFocus();
6598            });
6599          })();
6600        }
6601        // jQuery method of reveal
6602        else {
6603            if (this.options.overlay) {
6604              this.$overlay.show(0);
6605            }
6606            this.$element.show(this.options.showDelay);
6607          }
6608
6609        // handle accessibility
6610        this.$element.attr({
6611          'aria-hidden': false,
6612          'tabindex': -1
6613        }).focus();
6614
6615        /**
6616         * Fires when the modal has successfully opened.
6617         * @event Reveal#open
6618         */
6619        this.$element.trigger('open.zf.reveal');
6620
6621        if (this.isMobile) {
6622          this.originalScrollPos = window.pageYOffset;
6623          $('html, body').addClass('is-reveal-open');
6624        } else {
6625          $('body').addClass('is-reveal-open');
6626        }
6627
6628        setTimeout(function () {
6629          _this3._extraHandlers();
6630        }, 0);
6631      }
6632
6633      /**
6634       * Adds extra event handlers for the body and window if necessary.
6635       * @private
6636       */
6637
6638    }, {
6639      key: '_extraHandlers',
6640      value: function _extraHandlers() {
6641        var _this = this;
6642        this.focusableElements = Foundation.Keyboard.findFocusable(this.$element);
6643
6644        if (!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen) {
6645          $('body').on('click.zf.reveal', function (e) {
6646            if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
6647              return;
6648            }
6649            _this.close();
6650          });
6651        }
6652
6653        if (this.options.closeOnEsc) {
6654          $(window).on('keydown.zf.reveal', function (e) {
6655            Foundation.Keyboard.handleKey(e, 'Reveal', {
6656              close: function () {
6657                if (_this.options.closeOnEsc) {
6658                  _this.close();
6659                  _this.$anchor.focus();
6660                }
6661              }
6662            });
6663          });
6664        }
6665
6666        // lock focus within modal while tabbing
6667        this.$element.on('keydown.zf.reveal', function (e) {
6668          var $target = $(this);
6669          // handle keyboard event with keyboard util
6670          Foundation.Keyboard.handleKey(e, 'Reveal', {
6671            tab_forward: function () {
6672              if (_this.$element.find(':focus').is(_this.focusableElements.eq(-1))) {
6673                // left modal downwards, setting focus to first element
6674                _this.focusableElements.eq(0).focus();
6675                return true;
6676              }
6677              if (_this.focusableElements.length === 0) {
6678                // no focusable elements inside the modal at all, prevent tabbing in general
6679                return true;
6680              }
6681            },
6682            tab_backward: function () {
6683              if (_this.$element.find(':focus').is(_this.focusableElements.eq(0)) || _this.$element.is(':focus')) {
6684                // left modal upwards, setting focus to last element
6685                _this.focusableElements.eq(-1).focus();
6686                return true;
6687              }
6688              if (_this.focusableElements.length === 0) {
6689                // no focusable elements inside the modal at all, prevent tabbing in general
6690                return true;
6691              }
6692            },
6693            open: function () {
6694              if (_this.$element.find(':focus').is(_this.$element.find('[data-close]'))) {
6695                setTimeout(function () {
6696                  // set focus back to anchor if close button has been activated
6697                  _this.$anchor.focus();
6698                }, 1);
6699              } else if ($target.is(_this.focusableElements)) {
6700                // dont't trigger if acual element has focus (i.e. inputs, links, ...)
6701                _this.open();
6702              }
6703            },
6704            close: function () {
6705              if (_this.options.closeOnEsc) {
6706                _this.close();
6707                _this.$anchor.focus();
6708              }
6709            },
6710            handled: function (preventDefault) {
6711              if (preventDefault) {
6712                e.preventDefault();
6713              }
6714            }
6715          });
6716        });
6717      }
6718
6719      /**
6720       * Closes the modal.
6721       * @function
6722       * @fires Reveal#closed
6723       */
6724
6725    }, {
6726      key: 'close',
6727      value: function close() {
6728        if (!this.isActive || !this.$element.is(':visible')) {
6729          return false;
6730        }
6731        var _this = this;
6732
6733        // Motion UI method of hiding
6734        if (this.options.animationOut) {
6735          if (this.options.overlay) {
6736            Foundation.Motion.animateOut(this.$overlay, 'fade-out', finishUp);
6737          } else {
6738            finishUp();
6739          }
6740
6741          Foundation.Motion.animateOut(this.$element, this.options.animationOut);
6742        }
6743        // jQuery method of hiding
6744        else {
6745            if (this.options.overlay) {
6746              this.$overlay.hide(0, finishUp);
6747            } else {
6748              finishUp();
6749            }
6750
6751            this.$element.hide(this.options.hideDelay);
6752          }
6753
6754        // Conditionals to remove extra event listeners added on open
6755        if (this.options.closeOnEsc) {
6756          $(window).off('keydown.zf.reveal');
6757        }
6758
6759        if (!this.options.overlay && this.options.closeOnClick) {
6760          $('body').off('click.zf.reveal');
6761        }
6762
6763        this.$element.off('keydown.zf.reveal');
6764
6765        function finishUp() {
6766          if (_this.isMobile) {
6767            $('html, body').removeClass('is-reveal-open');
6768            if (_this.originalScrollPos) {
6769              $('body').scrollTop(_this.originalScrollPos);
6770              _this.originalScrollPos = null;
6771            }
6772          } else {
6773            $('body').removeClass('is-reveal-open');
6774          }
6775
6776          _this.$element.attr('aria-hidden', true);
6777
6778          /**
6779          * Fires when the modal is done closing.
6780          * @event Reveal#closed
6781          */
6782          _this.$element.trigger('closed.zf.reveal');
6783        }
6784
6785        /**
6786        * Resets the modal content
6787        * This prevents a running video to keep going in the background
6788        */
6789        if (this.options.resetOnClose) {
6790          this.$element.html(this.$element.html());
6791        }
6792
6793        this.isActive = false;
6794        if (_this.options.deepLink) {
6795          if (window.history.replaceState) {
6796            window.history.replaceState("", document.title, window.location.pathname);
6797          } else {
6798            window.location.hash = '';
6799          }
6800        }
6801      }
6802
6803      /**
6804       * Toggles the open/closed state of a modal.
6805       * @function
6806       */
6807
6808    }, {
6809      key: 'toggle',
6810      value: function toggle() {
6811        if (this.isActive) {
6812          this.close();
6813        } else {
6814          this.open();
6815        }
6816      }
6817    }, {
6818      key: 'destroy',
6819
6820
6821      /**
6822       * Destroys an instance of a modal.
6823       * @function
6824       */
6825      value: function destroy() {
6826        if (this.options.overlay) {
6827          this.$element.appendTo($('body')); // move $element outside of $overlay to prevent error unregisterPlugin()
6828          this.$overlay.hide().off().remove();
6829        }
6830        this.$element.hide().off();
6831        this.$anchor.off('.zf');
6832        $(window).off('.zf.reveal:' + this.id);
6833
6834        Foundation.unregisterPlugin(this);
6835      }
6836    }]);
6837
6838    return Reveal;
6839  }();
6840
6841  Reveal.defaults = {
6842    /**
6843     * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
6844     * @option
6845     * @example 'slide-in-left'
6846     */
6847    animationIn: '',
6848    /**
6849     * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
6850     * @option
6851     * @example 'slide-out-right'
6852     */
6853    animationOut: '',
6854    /**
6855     * Time, in ms, to delay the opening of a modal after a click if no animation used.
6856     * @option
6857     * @example 10
6858     */
6859    showDelay: 0,
6860    /**
6861     * Time, in ms, to delay the closing of a modal after a click if no animation used.
6862     * @option
6863     * @example 10
6864     */
6865    hideDelay: 0,
6866    /**
6867     * Allows a click on the body/overlay to close the modal.
6868     * @option
6869     * @example true
6870     */
6871    closeOnClick: true,
6872    /**
6873     * Allows the modal to close if the user presses the `ESCAPE` key.
6874     * @option
6875     * @example true
6876     */
6877    closeOnEsc: true,
6878    /**
6879     * If true, allows multiple modals to be displayed at once.
6880     * @option
6881     * @example false
6882     */
6883    multipleOpened: false,
6884    /**
6885     * Distance, in pixels, the modal should push down from the top of the screen.
6886     * @option
6887     * @example auto
6888     */
6889    vOffset: 'auto',
6890    /**
6891     * Distance, in pixels, the modal should push in from the side of the screen.
6892     * @option
6893     * @example auto
6894     */
6895    hOffset: 'auto',
6896    /**
6897     * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well.
6898     * @option
6899     * @example false
6900     */
6901    fullScreen: false,
6902    /**
6903     * Percentage of screen height the modal should push up from the bottom of the view.
6904     * @option
6905     * @example 10
6906     */
6907    btmOffsetPct: 10,
6908    /**
6909     * Allows the modal to generate an overlay div, which will cover the view when modal opens.
6910     * @option
6911     * @example true
6912     */
6913    overlay: true,
6914    /**
6915     * 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.
6916     * @option
6917     * @example false
6918     */
6919    resetOnClose: false,
6920    /**
6921     * 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'
6921s user-set id.
6922     * @option
6923     * @example false
6924     */
6925    deepLink: false
6926  };
6927
6928  // Window exports
6929  Foundation.plugin(Reveal, 'Reveal');
6930
6931  function iPhoneSniff() {
6932    return (/iP(ad|hone|od).*OS/.test(window.navigator.userAgent)
6933    );
6934  }
6935
6936  function androidSniff() {
6937    return (/Android/.test(window.navigator.userAgent)
6938    );
6939  }
6940
6941  function mobileSniff() {
6942    return iPhoneSniff() || androidSniff();
6943  }
6944}(jQuery);
6945'use strict';
6946
6947var _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; }; }();
6948
6949function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6950
6951!function ($) {
6952
6953  /**
6954   * Slider module.
6955   * @module foundation.slider
6956   * @requires foundation.util.motion
6957   * @requires foundation.util.triggers
6958   * @requires foundation.util.keyboard
6959   * @requires foundation.util.touch
6960   */
6961
6962  var Slider = function () {
6963    /**
6964     * Creates a new instance of a drilldown menu.
6965     * @class
6966     * @param {jQuery} element - jQuery object to make into an accordion menu.
6967     * @param {Object} options - Overrides to the default plugin settings.
6968     */
6969
6970    function Slider(element, options) {
6971      _classCallCheck(this, Slider);
6972
6973      this.$element = element;
6974      this.options = $.extend({}, Slider.defaults, this.$element.data(), options);
6975
6976      this._init();
6977
6978      Foundation.registerPlugin(this, 'Slider');
6979      Foundation.Keyboard.register('Slider', {
6980        'ltr': {
6981          'ARROW_RIGHT': 'increase',
6982          'ARROW_UP': 'increase',
6983          'ARROW_DOWN': 'decrease',
6984          'ARROW_LEFT': 'decrease',
6985          'SHIFT_ARROW_RIGHT': 'increase_fast',
6986          'SHIFT_ARROW_UP': 'increase_fast',
6987          'SHIFT_ARROW_DOWN': 'decrease_fast',
6988          'SHIFT_ARROW_LEFT': 'decrease_fast'
6989        },
6990        'rtl': {
6991          'ARROW_LEFT': 'increase',
6992          'ARROW_RIGHT': 'decrease',
6993          'SHIFT_ARROW_LEFT': 'increase_fast',
6994          'SHIFT_ARROW_RIGHT': 'decrease_fast'
6995        }
6996      });
6997    }
6998
6999    /**
7000     * Initilizes the plugin by reading/setting attributes, creating collections and setting the initial position of the handle(s).
7001     * @function
7002     * @private
7003     */
7004
7005
7006    _createClass(Slider, [{
7007      key: '_init',
7008      value: function _init() {
7009        this.inputs = this.$element.find('input');
7010        this.handles = this.$element.find('[data-slider-handle]');
7011
7012        this.$handle = this.handles.eq(0);
7013        this.$input = this.inputs.length ? this.inputs.eq(0) : $('#' + this.$handle.attr('aria-controls'));
7014        this.$fill = this.$element.find('[data-slider-fill]').css(this.options.vertical ? 'height' : 'width', 0);
7015
7016        var isDbl = false,
7017            _this = this;
7018        if (this.options.disabled || this.$element.hasClass(this.options.disabledClass)) {
7019          this.options.disabled = true;
7020          this.$element.addClass(this.options.disabledClass);
7021        }
7022        if (!this.inputs.length) {
7023          this.inputs = $().add(this.$input);
7024          this.options.binding = true;
7025        }
7026        this._setInitAttr(0);
7027        this._events(this.$handle);
7028
7029        if (this.handles[1]) {
7030          this.options.doubleSided = true;
7031          this.$handle2 = this.handles.eq(1);
7032          this.$input2 = this.inputs.length > 1 ? this.inputs.eq(1) : $('#' + this.$handle2.attr('aria-controls'));
7033
7034          if (!this.inputs[1]) {
7035            this.inputs = this.inputs.add(this.$input2);
7036          }
7037          isDbl = true;
7038
7039          this._setHandlePos(this.$handle, this.options.initialStart, true, function () {
7040
7041            _this._setHandlePos(_this.$handle2, _this.options.initialEnd, true);
7042          });
7043          // this.$handle.triggerHandler('click.zf.slider');
7044          this._setInitAttr(1);
7045          this._events(this.$handle2);
7046        }
7047
7048        if (!isDbl) {
7049          this._setHandlePos(this.$handle, this.options.initialStart, true);
7050        }
7051      }
7052
7053      /**
7054       * Sets the position of the selected handle and fill bar.
7055       * @function
7056       * @private
7057       * @param {jQuery} $hndl - the selected handle to move.
7058       * @param {Number} location - floating point between the start and end values of the slider bar.
7059       * @param {Function} cb - callback function to fire on completion.
7060       * @fires Slider#moved
7061       * @fires Slider#changed
7062       */
7063
7064    }, {
vendor: 5,311 bytes, lines 7065-7165
7065      key: '_setHandlePos',
7066      value: function _setHandlePos($hndl, location, noInvert, cb) {
7067        // don't move if the slider has been disabled since its initialization
7068        if (this.$element.hasClass(this.options.disabledClass)) {
7069          return;
7070        }
7071        //might need to alter that slightly for bars that will have odd number selections.
7072        location = parseFloat(location); //on input change events, convert string to number...grumble.
7073
7074        // prevent slider from running out of bounds, if value exceeds the limits set through options, override the value to min/max
7075        if (location < this.options.start) {
7076          location = this.options.start;
7077        } else if (location > this.options.end) {
7078          location = this.options.end;
7079        }
7080
7081        var isDbl = this.options.doubleSided;
7082
7083        if (isDbl) {
7084          //this block is to prevent 2 handles from crossing eachother. Could/should be improved.
7085          if (this.handles.index($hndl) === 0) {
7086            var h2Val = parseFloat(this.$handle2.attr('aria-valuenow'));
7087            location = location >= h2Val ? h2Val - this.options.step : location;
7088          } else {
7089            var h1Val = parseFloat(this.$handle.attr('aria-valuenow'));
7090            location = location <= h1Val ? h1Val + this.options.step : location;
7091          }
7092        }
7093
7094        //this is for single-handled vertical sliders, it adjusts the value to account for the slider being "upside-down"
7095        //for click and drag events, it's weird due to the scale(-1, 1) css property
7096        if (this.options.vertical && !noInvert) {
7097          location = this.options.end - location;
7098        }
7099
7100        var _this = this,
7101            vert = this.options.vertical,
7102            hOrW = vert ? 'height' : 'width',
7103            lOrT = vert ? 'top' : 'left',
7104            handleDim = $hndl[0].getBoundingClientRect()[hOrW],
7105            elemDim = this.$element[0].getBoundingClientRect()[hOrW],
7106
7107        //percentage of bar min/max value based on click or drag point
7108        pctOfBar = percent(location - this.options.start, this.options.end - this.options.start).toFixed(2),
7109
7110        //number of actual pixels to shift the handle, based on the percentage obtained above
7111        pxToMove = (elemDim - handleDim) * pctOfBar,
7112
7113        //percentage of bar to shift the handle
7114        movement = (percent(pxToMove, elemDim) * 100).toFixed(this.options.decimal);
7115        //fixing the decimal value for the location number, is passed to other methods as a fixed floating-point value
7116        location = parseFloat(location.toFixed(this.options.decimal));
7117        // declare empty object for css adjustments, only used with 2 handled-sliders
7118        var css = {};
7119
7120        this._setValues($hndl, location);
7121
7122        // TODO update to calculate based on values set to respective inputs??
7123        if (isDbl) {
7124          var isLeftHndl = this.handles.index($hndl) === 0,
7125
7126          //empty variable, will be used for min-height/width for fill bar
7127          dim,
7128
7129          //percentage w/h of the handle compared to the slider bar
7130          handlePct = ~ ~(percent(handleDim, elemDim) * 100);
7131          //if left handle, the math is slightly different than if it's the right handle, and the left/top property needs to be changed for the fill bar
7132          if (isLeftHndl) {
7133            //left or top percentage value to apply to the fill bar.
7134            css[lOrT] = movement + '%';
7135            //calculate the new min-height/width for the fill bar.
7136            dim = parseFloat(this.$handle2[0].style[lOrT]) - movement + handlePct;
7137            //this callback is necessary to prevent errors and allow the proper placement and initialization of a 2-handled slider
7138            //plus, it means we don't care if 'dim' isNaN on init, it won't be in the future.
7139            if (cb && typeof cb === 'function') {
7140              cb();
7141            } //this is only needed for the initialization of 2 handled sliders
7142          } else {
7143              //just caching the value of the left/bottom handle's left/top property
7144              var handlePos = parseFloat(this.$handle[0].style[lOrT]);
7145              //calculate the new min-height/width for the fill bar. Use isNaN to prevent false positives for numbers <= 0
7146              //based on the percentage of movement of the handle being manipulated, less the opposing handle's left/top position, plus the percentage w/h of the handle itself
7147              dim = movement - (isNaN(handlePos) ? this.options.initialStart / ((this.options.end - this.options.start) / 100) : handlePos) + handlePct;
7148            }
7149          // assign the min-height/width to our css object
7150          css['min-' + hOrW] = dim + '%';
7151        }
7152
7153        this.$element.one('finished.zf.animate', function () {
7154          /**
7155           * Fires when the handle is done moving.
7156           * @event Slider#moved
7157           */
7158          _this.$element.trigger('moved.zf.slider', [$hndl]);
7159        });
7160
7161        //because we don't know exactly how the handle will be moved, check the amount of time it should take to move.
7162        var moveTime = this.$element.data('dragging') ? 1000 / 60 : this.options.moveTime;
7163
7164        Foundation.Move(moveTime, $hndl, function () {
7165          //adjusting the left/top property of the handle, based on the percentage c
7165alculated above
7166          $hndl.css(lOrT, movement + '%');
7167
7168          if (!_this.options.doubleSided) {
7169            //if single-handled, a simple method to expand the fill bar
7170            _this.$fill.css(hOrW, pctOfBar * 100 + '%');
7171          } else {
7172            //otherwise, use the css object we created above
7173            _this.$fill.css(css);
7174          }
7175        });
7176
7177        /**
7178         * Fires when the value has not been change for a given time.
7179         * @event Slider#changed
7180         */
7181        clearTimeout(_this.timeout);
7182        _this.timeout = setTimeout(function () {
7183          _this.$element.trigger('changed.zf.slider', [$hndl]);
7184        }, _this.options.changedDelay);
7185      }
7186
7187      /**
7188       * Sets the initial attribute for the slider element.
7189       * @function
7190       * @private
7191       * @param {Number} idx - index of the current handle/input to use.
7192       */
7193
7194    }, {
7195      key: '_setInitAttr',
7196      value: function _setInitAttr(idx) {
7197        var id = this.inputs.eq(idx).attr('id') || Foundation.GetYoDigits(6, 'slider');
7198        this.inputs.eq(idx).attr({
7199          'id': id,
7200          'max': this.options.end,
7201          'min': this.options.start,
7202          'step': this.options.step
7203        });
7204        this.handles.eq(idx).attr({
7205          'role': 'slider',
7206          'aria-controls': id,
7207          'aria-valuemax': this.options.end,
7208          'aria-valuemin': this.options.start,
7209          'aria-valuenow': idx === 0 ? this.options.initialStart : this.options.initialEnd,
7210          'aria-orientation': this.options.vertical ? 'vertical' : 'horizontal',
7211          'tabindex': 0
7212        });
7213      }
7214
7215      /**
7216       * Sets the input and `aria-valuenow` values for the slider element.
7217       * @function
7218       * @private
7219       * @param {jQuery} $handle - the currently selected handle.
7220       * @param {Number} val - floating point of the new value.
7221       */
7222
7223    }, {
7224      key: '_setValues',
7225      value: function _setValues($handle, val) {
7226        var idx = this.options.doubleSided ? this.handles.index($handle) : 0;
7227        this.inputs.eq(idx).val(val);
7228        $handle.attr('aria-valuenow', val);
7229      }
7230
7231      /**
7232       * Handles events on the slider element.
7233       * Calculates the new location of the current handle.
7234       * If there are two handles and the bar was clicked, it determines which handle to move.
7235       * @function
7236       * @private
7237       * @param {Object} e - the `event` object passed from the listener.
7238       * @param {jQuery} $handle - the current handle to calculate for, if selected.
7239       * @param {Number} val - floating point number for the new value of the slider.
7240       * TODO clean this up, there's a lot of repeated code between this and the _setHandlePos fn.
7241       */
7242
7243    }, {
7244      key: '_handleEvent',
7245      value: function _handleEvent(e, $handle, val) {
7246        var value, hasVal;
7247        if (!val) {
7248          //click or drag events
7249          e.preventDefault();
7250          var _this = this,
7251              vertical = this.options.vertical,
7252              param = vertical ? 'height' : 'width',
7253              direction = vertical ? 'top' : 'left',
7254              eventOffset = vertical ? e.pageY : e.pageX,
7255              halfOfHandle = this.$handle[0].getBoundingClientRect()[param] / 2,
7256              barDim = this.$element[0].getBoundingClientRect()[param],
7257              windowScroll = vertical ? $(window).scrollTop() : $(window).scrollLeft();
7258
7259          var elemOffset = this.$element.offset()[direction];
7260
7261          // touch events emulated by the touch util give position relative to screen, add window.scroll to event coordinates...
7262          // best way to guess this is simulated is if clientY == pageY
7263          if (e.clientY === e.pageY) {
7264            eventOffset = eventOffset + windowScroll;
7265          }
7266          var eventFromBar = eventOffset - elemOffset;
7267          var barXY;
7268          if (eventFromBar < 0) {
7269            barXY = 0;
7270          } else if (eventFromBar > barDim) {
7271            barXY = barDim;
7272          } else {
7273            barXY = eventFromBar;
7274          }
7275          offsetPct = percent(barXY, barDim);
7276
7277          value = (this.options.end - this.options.start) * offsetPct + this.options.start;
7278
7279          // turn everything around for RTL, yay math!
7280          if (Foundation.rtl() && !this.options.vertical) {
7281            value = this.options.end - value;
7282          }
7283
7284          value = _this._adjustValue(null, value);
7285          //boolean flag for the setHandlePos fn, specifically for vertical sliders
7286          hasVal = false;
7287
7288          if (!$handle) {
7289            //figure out which handle it is, pass it to the next function.
7290            var firstHndlPos = absPosition(this.$handle, direction, barXY, param),
7291                secndHndlPos = absPosition(this.$handle2, direction, barXY, param);
7292            $handle = firstHndlPos <= secndHndlPos ? this.$handle : this.$handle2;
7293          }
7294        } else {
7295          //change event on input
7296          value = this._adjustValue(null, val);
7297          hasVal = true;
7298        }
7299
7300        this._setHandlePos($handle, value, hasVal);
7301      }
7302
7303      /**
7304       * Adjustes value for handle in regard to step value. returns adjusted value
7305       * @function
7306       * @private
7307       * @param {jQuery} $handle - the selected handle.
7308       * @param {Number} value - value to adjust. used if $handle is falsy
7309       */
7310
7311    }, {
7312      key: '_adjustValue',
7313      value: function _adjustValue($handle, value) {
7314        var val,
7315            step = this.options.step,
7316            div = parseFloat(step / 2),
7317            left,
7318            prev_val,
7319            next_val;
7320        if (!!$handle) {
7321          val = parseFloat($handle.attr('aria-valuenow'));
7322        } else {
7323          val = value;
7324        }
7325        left = val % step;
7326        prev_val = val - left;
7327        next_val = prev_val + step;
7328        if (left === 0) {
7329          return val;
7330        }
7331        val = val >= prev_val + div ? next_val : prev_val;
7332        return val;
7333      }
7334
7335      /**
7336       * Adds event listeners to the slider elements.
7337       * @function
7338       * @private
7339       * @param {jQuery} $handle - the current handle to apply listeners to.
7340       */
7341
7342    }, {
7343      key: '_events',
7344      value: function _events($handle) {
7345        var _this = this,
7346            curHandle,
7347            timer;
7348
7349        this.inputs.off('change.zf.slider').on('change.zf.slider', function (e) {
7350          var idx = _this.inputs.index($(this));
7351          _this._handleEvent(e, _this.handles.eq(idx), $(this).val());
7352        });
7353
7354        if (this.options.clickSelect) {
7355          this.$element.off('click.zf.slider').on('click.zf.slider', function (e) {
7356            if (_this.$element.data('dragging')) {
7357              return false;
7358            }
7359
7360            if (!$(e.target).is('[data-slider-handle]')) {
7361              if (_this.options.doubleSided) {
7362                _this._handleEvent(e);
7363              } else {
7364                _this._handleEvent(e, _this.$handle);
7365              }
7366            }
7367          });
7368        }
7369
7370        if (this.options.draggable) {
7371          this.handles.addTouch();
7372
7373          var $body = $('body');
7374          $handle.off('mousedown.zf.slider').on('mousedown.zf.slider', function (e) {
7375            $handle.addClass('is-dragging');
7376            _this.$fill.addClass('is-dragging'); //
7377            _this.$element.data('dragging', true);
7378
7379            curHandle = $(e.currentTarget);
7380
7381            $body.on('mousemove.zf.slider', function (e) {
7382              e.preventDefault();
7383              _this._handleEvent(e, curHandle);
7384            }).on('mouseup.zf.slider', function (e) {
7385              _this._handleEvent(e, curHandle);
7386
7387              $handle.removeClass('is-dragging');
7388              _this.$fill.removeClass('is-dragging');
7389              _this.$element.data('dragging', false);
7390
7391              $body.off('mousemove.zf.slider mouseup.zf.slider');
7392            });
7393          })
7394          // prevent events triggered by touch
7395          .on('selectstart.zf.slider touchmove.zf.slider', function (e) {
7396            e.preventDefault();
7397          });
7398        }
7399
7400        $handle.off('keydown.zf.slider').on('keydown.zf.slider', function (e) {
7401          var _$handle = $(this),
7402              idx = _this.options.doubleSided ? _this.handles.index(_$handle) : 0,
7403              oldValue = parseFloat(_this.inputs.eq(idx).val()),
7404              newValue;
7405
7406          // handle keyboard event with keyboard util
7407          Foundation.Keyboard.handleKey(e, 'Slider', {
7408            decrease: function () {
7409              newValue = oldValue - _this.options.step;
7410            },
7411            increase: function () {
7412              newValue = oldValue + _this.options.step;
7413            },
7414            decrease_fast: function () {
7415              newValue = oldValue - _this.options.step * 10;
7416            },
7417            increase_fast: function () {
7418              newValue = oldValue + _this.options.step * 10;
7419            },
7420            handled: function () {
7421              // only set handle pos when event was handled specially
7422              e.preventDefault();
7423              _this._setHandlePos(_$handle, newValue, true);
7424            }
7425          });
7426          /*if (newValue) { // if pressed key has special function, update value
7427            e.preventDefault();
7428            _this._setHandlePos(_$handle, newValue);
7429          }*/
7430        });
7431      }
7432
7433      /**
7434       * Destroys the slider plugin.
7435       */
7436
7437    }, {
7438      key: 'destroy',
7439      value: function destroy() {
7440        this.handles.off('.zf.slider');
7441        this.inputs.off('.zf.slider');
7442        this.$element.off('.zf.slider');
7443
7444        Foundation.unregisterPlugin(this);
7445      }
7446    }]);
7447
7448    return Slider;
7449  }();
7450
7451  Slider.defaults = {
7452    /**
7453     * Minimum value for the slider scale.
7454     * @option
7455     * @example 0
7456     */
7457    start: 0,
7458    /**
7459     * Maximum value for the slider scale.
7460     * @option
7461     * @example 100
7462     */
7463    end: 100,
7464    /**
7465     * Minimum value change per change event.
7466     * @option
7467     * @example 1
7468     */
7469    step: 1,
7470    /**
7471     * Value at which the handle/input *(left handle/first input)* should be set to on initialization.
7472     * @option
7473     * @example 0
7474     */
7475    initialStart: 0,
7476    /**
7477     * Value at which the right handle/second input should be set to on initialization.
7478     * @option
7479     * @example 100
7480     */
7481    initialEnd: 100,
7482    /**
7483     * Allows the input to be located outside the container and visible. Set to by the JS
7484     * @option
7485     * @example false
7486     */
7487    binding: false,
7488    /**
7489     * Allows the user to click/tap on the slider bar to select a value.
7490     * @option
7491     * @example true
7492     */
7493    clickSelect: true,
7494    /**
7495     * Set to true and use the `vertical` class to change alignment to vertical.
7496     * @option
7497     * @example false
7498     */
7499    vertical: false,
7500    /**
7501     * Allows the user to drag the slider handle(s) to select a value.
7502     * @option
7503     * @example true
7504     */
7505    draggable: true,
7506    /**
7507     * Disables the slider and prevents event listeners from being applied. Double checked by JS with `disabledClass`.
7508     * @option
7509     * @example false
7510     */
7511    disabled: false,
7512    /**
7513     * Allows the use of two handles. Double checked by the JS. Changes some logic handling.
7514     * @option
7515     * @example false
7516     */
7517    doubleSided: false,
7518    /**
7519     * Potential future feature.
7520     */
7521    // steps: 100,
7522    /**
7523     * Number of decimal places the plugin should go to for floating point precision.
7524     * @option
7525     * @example 2
7526     */
7527    decimal: 2,
7528    /**
7529     * Time delay for dragged elements.
7530     */
7531    // dragDelay: 0,
7532    /**
7533     * Time, in ms, to animate the movement of a slider handle if user clicks/taps on the bar. Needs to be manually set if updating the transition time in the Sass settings.
7534     * @option
7535     * @example 200
7536     */
7537    moveTime: 200, //update this if changing the transition time in the sass
7538    /**
7539     * Class applied to disabled sliders.
7540     * @option
7541     * @example 'disabled'
7542     */
7543    disabledClass: 'disabled',
7544    /**
7545     * Will invert the default layout for a vertical<span data-tooltip title="who would do this???"> </span>slider.
7546     * @option
7547     * @example false
7548     */
7549    invertVertical: false,
7550    /**
7551     * Milliseconds before the `changed.zf-slider` event is triggered after value change.
7552     * @option
7553     * @example 500
7554     */
7555    changedDelay: 500
7556  };
7557
7558  function percent(frac, num) {
7559    return frac / num;
7560  }
7561  function absPosition($handle, dir, clickPos, param) {
7562    return Math.abs($handle.position()[dir] + $handle[param]() / 2 - clickPos);
7563  }
7564
7565  // Window exports
7566  Foundation.plugin(Slider, 'Slider');
7567}(jQuery);
7568
7569//*********this is in case we go to static, absolute positions instead of dynamic positioning********
7570// this.setSteps(function() {
7571//   _this._events();
7572//   var initStart = _this.options.positions[_this.options.initialStart - 1] || null;
7573//   var initEnd = _this.options.initialEnd ? _this.options.position[_this.options.initialEnd - 1] : null;
7574//   if (initStart || initEnd) {
7575//     _this._handleEvent(initStart, initEnd);
7576//   }
7577// });
7578
7579//***********the other part of absolute positions*************
7580// Slider.prototype.setSteps = function(cb) {
7581//   var posChange = this.$element.outerWidth() / this.options.steps;
7582//   var counter = 0
7583//   while(counter < this.options.steps) {
7584//     if (counter) {
7585//       this.options.positions.push(this.options.positions[counter - 1] + posChange);
7586//     } else {
7587//       this.options.positions.push(posChange);
7588//     }
7589//     counter++;
7590//   }
7591//   cb();
7592// };
7593'use strict';
7594
7595var _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; }; }();
7596
7597function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7598
7599!function ($) {
7600
7601  /**
7602   * Sticky module.
7603   * @module foundation.sticky
7604   * @requires foundation.util.triggers
7605   * @requires foundation.util.mediaQuery
7606   */
7607
7608  var Sticky = function () {
7609    /**
7610     * Creates a new instance of a sticky thing.
7611     * @class
7612     * @param {jQuery} element - jQuery object to make sticky.
7613     * @param {Object} options - options object passed when creating the element programmatically.
7614     */
7615
7616    function Sticky(element, options) {
7617      _classCallCheck(this, Sticky);
7618
7619      this.$element = element;
7620      this.options = $.extend({}, Sticky.defaults, this.$element.data(), options);
7621
7622      this._init();
7623
7624      Foundation.registerPlugin(this, 'Sticky');
7625    }
7626
7627    /**
7628     * Initializes the sticky element by adding classes, getting/setting dimensions, breakpoints and attributes
7629     * @function
7630     * @private
7631     */
7632
7633
7634    _createClass(Sticky, [{
7635      key: '_init',
7636      value: function _init() {
7637        var $parent = this.$element.parent('[data-sticky-container]'),
7638            id = this.$element[0].id || Foundation.GetYoDigits(6, 'sticky'),
7639            _this = this;
7640
7641        if (!$parent.length) {
7642          this.wasWrapped = true;
7643        }
7644        this.$container = $parent.length ? $parent : $(this.options.container).wrapInner(this.$element);
7645        this.$container.addClass(this.options.containerClass);
7646
7647        this.$element.addClass(this.options.stickyClass).attr({ 'data-resize': id });
7648
7649        this.scrollCount = this.options.checkEvery;
7650        this.isStuck = false;
vendor: 4,703 bytes, lines 7651-7811
7651        $(window).one('load.zf.sticky', function () {
7652          if (_this.options.anchor !== '') {
7653            _this.$anchor = $('#' + _this.options.anchor);
7654          } else {
7655            _this._parsePoints();
7656          }
7657
7658          _this._setSizes(function () {
7659            _this._calc(false);
7660          });
7661          _this._events(id.split('-').reverse().join('-'));
7662        });
7663      }
7664
7665      /**
7666       * If using multiple elements as anchors, calculates the top and bottom pixel values the sticky thing should stick and unstick on.
7667       * @function
7668       * @private
7669       */
7670
7671    }, {
7672      key: '_parsePoints',
7673      value: function _parsePoints() {
7674        var top = this.options.topAnchor == "" ? 1 : this.options.topAnchor,
7675            btm = this.options.btmAnchor == "" ? document.documentElement.scrollHeight : this.options.btmAnchor,
7676            pts = [top, btm],
7677            breaks = {};
7678        for (var i = 0, len = pts.length; i < len && pts[i]; i++) {
7679          var pt;
7680          if (typeof pts[i] === 'number') {
7681            pt = pts[i];
7682          } else {
7683            var place = pts[i].split(':'),
7684                anchor = $('#' + place[0]);
7685
7686            pt = anchor.offset().top;
7687            if (place[1] && place[1].toLowerCase() === 'bottom') {
7688              pt += anchor[0].getBoundingClientRect().height;
7689            }
7690          }
7691          breaks[i] = pt;
7692        }
7693
7694        this.points = breaks;
7695        return;
7696      }
7697
7698      /**
7699       * Adds event handlers for the scrolling element.
7700       * @private
7701       * @param {String} id - psuedo-random id for unique scroll event listener.
7702       */
7703
7704    }, {
7705      key: '_events',
7706      value: function _events(id) {
7707        var _this = this,
7708            scrollListener = this.scrollListener = 'scroll.zf.' + id;
7709        if (this.isOn) {
7710          return;
7711        }
7712        if (this.canStick) {
7713          this.isOn = true;
7714          $(window).off(scrollListener).on(scrollListener, function (e) {
7715            if (_this.scrollCount === 0) {
7716              _this.scrollCount = _this.options.checkEvery;
7717              _this._setSizes(function () {
7718                _this._calc(false, window.pageYOffset);
7719              });
7720            } else {
7721              _this.scrollCount--;
7722              _this._calc(false, window.pageYOffset);
7723            }
7724          });
7725        }
7726
7727        this.$element.off('resizeme.zf.trigger').on('resizeme.zf.trigger', function (e, el) {
7728          _this._setSizes(function () {
7729            _this._calc(false);
7730            if (_this.canStick) {
7731              if (!_this.isOn) {
7732                _this._events(id);
7733              }
7734            } else if (_this.isOn) {
7735              _this._pauseListeners(scrollListener);
7736            }
7737          });
7738        });
7739      }
7740
7741      /**
7742       * Removes event handlers for scroll and change events on anchor.
7743       * @fires Sticky#pause
7744       * @param {String} scrollListener - unique, namespaced scroll listener attached to `window`
7745       */
7746
7747    }, {
7748      key: '_pauseListeners',
7749      value: function _pauseListeners(scrollListener) {
7750        this.isOn = false;
7751        $(window).off(scrollListener);
7752
7753        /**
7754         * Fires when the plugin is paused due to resize event shrinking the view.
7755         * @event Sticky#pause
7756         * @private
7757         */
7758        this.$element.trigger('pause.zf.sticky');
7759      }
7760
7761      /**
7762       * Called on every `scroll` event and on `_init`
7763       * fires functions based on booleans and cached values
7764       * @param {Boolean} checkSizes - true if plugin should recalculate sizes and breakpoints.
7765       * @param {Number} scroll - current scroll position passed from scroll event cb function. If not passed, defaults to `window.pageYOffset`.
7766       */
7767
7768    }, {
7769      key: '_calc',
7770      value: function _calc(checkSizes, scroll) {
7771        if (checkSizes) {
7772          this._setSizes();
7773        }
7774
7775        if (!this.canStick) {
7776          if (this.isStuck) {
7777            this._removeSticky(true);
7778          }
7779          return false;
7780        }
7781
7782        if (!scroll) {
7783          scroll = window.pageYOffset;
7784        }
7785
7786        if (scroll >= this.topPoint) {
7787          if (scroll <= this.bottomPoint) {
7788            if (!this.isStuck) {
7789              this._setSticky();
7790            }
7791          } else {
7792            if (this.isStuck) {
7793              this._removeSticky(false);
7794            }
7795          }
7796        } else {
7797          if (this.isStuck) {
7798            this._removeSticky(true);
7799          }
7800        }
7801      }
7802
7803      /**
7804       * Causes the $element to become stuck.
7805       * Adds `position: fixed;`, and helper classes.
7806       * @fires Sticky#stuckto
7807       * @function
7808       * @private
7809       */
7810
7811    }, {
7812      key: '_setSticky',
7813      value: function _setSticky() {
7814        var _this = this,
7815            stickTo = this.options.stickTo,
7816            mrgn = stickTo === 'top' ? 'marginTop' : 'marginBottom',
7817            notStuckTo = stickTo === 'top' ? 'bottom' : 'top',
7818            css = {};
7819
7820        css[mrgn] = this.options[mrgn] + 'em';
7821        css[stickTo] = 0;
7822        css[notStuckTo] = 'auto';
7823        css['left'] = this.$container.offset().left + parseInt(window.getComputedStyle(this.$container[0])["padding-left"], 10);
7824        this.isStuck = true;
7825        this.$element.removeClass('is-anchored is-at-' + notStuckTo).addClass('is-stuck is-at-' + stickTo).css(css)
7826        /**
7827         * Fires when the $element has become `position: fixed;`
7828         * Namespaced to `top` or `bottom`, e.g. `sticky.zf.stuckto:top`
7829         * @event Sticky#stuckto
7830         */
7831        .trigger('sticky.zf.stuckto:' + stickTo);
7832        this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () {
7833          _this._setSizes();
7834        });
7835      }
7836
7837      /**
7838       * Causes the $element to become unstuck.
7839       * Removes `position: fixed;`, and helper classes.
7840       * Adds other helper classes.
7841       * @param {Boolean} isTop - tells the function if the $element should anchor to the top or bottom of its $anchor element.
7842       * @fires Sticky#unstuckfrom
7843       * @private
7844       */
7845
7846    }, {
7847      key: '_removeSticky',
7848      value: function _removeSticky(isTop) {
7849        var stickTo = this.options.stickTo,
7850            stickToTop = stickTo === 'top',
7851            css = {},
7852            anchorPt = (this.points ? this.points[1] - this.points[0] : this.anchorHeight) - this.elemHeight,
7853            mrgn = stickToTop ? 'marginTop' : 'marginBottom',
7854            notStuckTo = stickToTop ? 'bottom' : 'top',
7855            topOrBottom = isTop ? 'top' : 'bottom';
7856
7857        css[mrgn] = 0;
7858
7859        css['bottom'] = 'auto';
7860        if (isTop) {
7861          css['top'] = 0;
7862        } else {
7863          css['top'] = anchorPt;
7864        }
7865
7866        css['left'] = '';
7867        this.isStuck = false;
7868        this.$element.removeClass('is-stuck is-at-' + stickTo).addClass('is-anchored is-at-' + topOrBottom).css(css)
7869        /**
7870         * Fires when the $element has become anchored.
7871         * Namespaced to `top` or `bottom`, e.g. `sticky.zf.unstuckfrom:bottom`
7872         * @event Sticky#unstuckfrom
7873         */
7874        .trigger('sticky.zf.unstuckfrom:' + topOrBottom);
7875      }
7876
7877      /**
7878       * Sets the $element and $container sizes for plugin.
7879       * Calls `_setBreakPoints`.
7880       * @param {Function} cb - optional callback function to fire on completion of `_setBreakPoints`.
7881       * @private
7882       */
7883
7884    }, {
7885      key: '_setSizes',
7886      value: function _setSizes(cb) {
7887        this.canStick = Foundation.MediaQuery.atLeast(this.options.stickyOn);
7888        if (!this.canStick) {
7889          cb();
7890        }
7891        var _this = this,
7892            newElemWidth = this.$container[0].getBoundingClientRect().width,
7893            comp = window.getComputedStyle(this.$container[0]),
7894            pdng = parseInt(comp['padding-right'], 10);
7895
7896        if (this.$anchor && this.$anchor.length) {
7897          this.anchorHeight = this.$anchor[0].getBoundingClientRect().height;
7898        } else {
7899          this._parsePoints();
7900        }
7901
7902        this.$element.css({
7903          'max-width': newElemWidth - pdng + 'px'
7904        });
7905
7906        var newContainerHeight = this.$element[0].getBoundingClientRect().height || this.containerHeight;
7907        if (this.$element.css("display") == "none") {
7908          newContainerHeight = 0;
7909        }
7910        this.containerHeight = newContainerHeight;
7911        this.$container.css({
7912          height: newContainerHeight
7913        });
7914        this.elemHeight = newContainerHeight;
7915
7916        if (this.isStuck) {
7917          this.$element.css({ "left": this.$container.offset().left + parseInt(comp['padding-left'], 10) });
7918        }
7919
7920        this._setBreakPoints(newContainerHeight, function () {
7921          if (cb) {
7922            cb();
7923          }
7924        });
7925      }
7926
7927      /**
7928       * Sets the upper and lower breakpoints for the element to become sticky/unsticky.
7929       * @param {Number} elemHeight - px value for sticky.$element height, calculated by `_setSizes`.
7930       * @param {Function} cb - optional callback function to be called on completion.
7931       * @private
7932       */
7933
7934    }, {
7935      key: '_setBreakPoints',
7936      value: function _setBreakPoints(elemHeight, cb) {
7937        if (!this.canStick) {
7938          if (cb) {
7939            cb();
7940          } else {
7941            return false;
7942          }
7943        }
7944        var mTop = emCalc(this.options.marginTop),
7945            mBtm = emCalc(this.options.marginBottom),
7946            topPoint = this.points ? this.points[0] : this.$anchor.offset().top,
7947            bottomPoint = this.points ? this.points[1] : topPoint + this.anchorHeight,
7948
7949        // topPoint = this.$anchor.offset().top || this.points[0],
7950        // bottomPoint = topPoint + this.anchorHeight || this.points[1],
7951        winHeight = window.innerHeight;
7952
7953        if (this.options.stickTo === 'top') {
7954          topPoint -= mTop;
7955          bottomPoint -= elemHeight + mTop;
7956        } else if (this.options.stickTo === 'bottom') {
7957          topPoint -= winHeight - (elemHeight + mBtm);
7958          bottomPoint -= winHeight - mBtm;
7959        } else {
7960          //this would be the stickTo: both option... tricky
7961        }
7962
7963        this.topPoint = topPoint;
7964        this.bottomPoint = bottomPoint;
7965
7966        if (cb) {
7967          cb();
7968        }
7969      }
7970
7971      /**
7972       * Destroys the current sticky element.
7973       * Resets the element to the top position first.
7974       * Removes event listeners, JS-added css properties and classes, and unwraps the $element if the JS added the $container.
7975       * @function
7976       */
7977
7978    }, {
7979      key: 'destroy',
7980      value: function destroy() {
7981        this._removeSticky(true);
7982
7983        this.$element.removeClass(this.options.stickyClass + ' is-anchored is-at-top').css({
7984          height: '',
7985          top: '',
7986          bottom: '',
7987          'max-width': ''
7988        }).off('resizeme.zf.trigger');
7989        if (this.$anchor && this.$anchor.length) {
7990          this.$anchor.off('change.zf.sticky');
7991        }
7992        $(window).off(this.scrollListener);
7993
7994        if (this.wasWrapped) {
7995          this.$element.unwrap();
7996        } else {
7997          this.$container.removeClass(this.options.containerClass).css({
7998            height: ''
7999          });
8000        }
8001        Foundation.unregisterPlugin(this);
8002      }
8003    }]);
8004
8005    return Sticky;
8006  }();
8007
8008  Sticky.defaults = {
8009    /**
8010     * Customizable container template. Add your own classes for styling and sizing.
8011     * @option
8012     * @example '&lt;div data-sticky-container class="small-6 columns"&gt;&lt;/div&gt;'
8013     */
8014    container: '<div data-sticky-container></div>',
8015    /**
8016     * Location in the view the element sticks to.
8017     * @option
8018     * @example 'top'
8019     */
8020    stickTo: 'top',
8021    /**
8022     * If anchored to a single element, the id of that element.
8023     * @option
8024     * @example 'exampleId'
8025     */
8026    anchor: '',
8027    /**
8028     * If using more than one element as anchor points, the id of the top anchor.
8029     * @option
8030     * @example 'exampleId:top'
8031     */
8032    topAnchor: '',
8033    /**
8034     * If using more than one element as anchor points, the id of the bottom anchor.
8035     * @option
8036     * @example 'exampleId:bottom'
8037     */
8038    btmAnchor: '',
8039    /**
8040     * Margin, in `em`'s to apply to the top of the element when it becomes sticky.
8041     * @option
8042     * @example 1
8043     */
8044    marginTop: 1,
8045    /**
8046     * Margin, in `em`'s to apply to the bottom of the element when it becomes sticky.
8047     * @option
8048     * @example 1
8049     */
8050    marginBottom: 1,
8051    /**
8052     * Breakpoint string that is the minimum screen size an element should become sticky.
8053     * @option
8054     * @example 'medium'
8055     */
8056    stickyOn: 'medium',
8057    /**
8058     * Class applied to sticky element, and removed on destruction. Foundation defaults to `sticky`.
8059     * @option
8060     * @example 'sticky'
8061     */
8062    stickyClass: 'sticky',
8063    /**
8064     * Class applied to sticky container. Foundation defaults to `sticky-container`.
8065     * @option
8066     * @example 'sticky-container'
8067     */
8068    containerClass: 'sticky-container',
8069    /**
8070     * 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.
8071     * @option
8072     * @example 50
8073     */
8074    checkEvery: -1
8075  };
8076
8077  /**
8078   * Helper function to calculate em values
8079   * @param Number {em} - number of em's to calculate into pixels
8080   */
8081  function emCalc(em) {
8082    return parseInt(window.getComputedStyle(document.body, null).fontSize, 10) * em;
8083  }
8084
8085  // Window exports
8086  Foundation.plugin(Sticky, 'Sticky');
8087}(jQuery);
8088'use strict';
8089
8090var _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; }; }();
8091
8092function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8093
8094!function ($) {
8095
8096  /**
8097   * Tabs module.
8098   * @module foundation.tabs
8099   * @requires foundation.util.keyboard
8100   * @requires foundation.util.timerAndImageLoader if tabs contain images
8101   */
8102
8103  var Tabs = function () {
8104    /**
8105     * Creates a new instance of tabs.
8106     * @class
8107     * @fires Tabs#init
8108     * @param {jQuery} element - jQuery object to make into tabs.
8109     * @param {Object} options - Overrides to the default plugin settings.
8110     */
8111
8112    function Tabs(element, options) {
8113      _classCallCheck(this, Tabs);
8114
8115      this.$element = element;
8116      this.options = $.extend({}, Tabs.defaults, this.$element.data(), options);
8117
8118      this._init();
8119      Foundation.registerPlugin(this, 'Tabs');
8120      Foundation.Keyboard.register('Tabs', {
8121        'ENTER': 'open',
8122        'SPACE': 'open',
8123        'ARROW_RIGHT': 'next',
8124        'ARROW_UP': 'previous',
8125        'ARROW_DOWN': 'next',
8126        'ARROW_LEFT': 'previous'
8127        // 'TAB': 'next',
8128        // 'SHIFT_TAB': 'previous'
8129      });
8130    }
8131
8132    /**
8133     * Initializes the tabs by showing and focusing (if autoFocus=true) the preset active tab.
8134     * @private
8135     */
8136
8137
8138    _createClass(Tabs, [{
8139      key: '_init',
8140      value: function _init() {
8141        var _this = this;
8142
8143        this.$tabTitles = this.$element.find('.' + this.options.linkClass);
8144        this.$tabContent = $('[data-tabs-content="' + this.$element[0].id + '"]');
8145
8146        this.$tabTitles.each(function () {
8147          var $elem = $(this),
8148              $link = $elem.find('a'),
8149              isActive = $elem.hasClass('is-active'),
8150              hash = $link[0].hash.slice(1),
8151              linkId = $link[0].id ? $link[0].id : hash + '-label',
8152              $tabContent = $('#' + hash);
8153
8154          $elem.attr({ 'role': 'presentation' });
8155
8156          $link.attr({
8157            'role': 'tab',
8158            'aria-controls': hash,
8159            'aria-selected': isActive,
8160            'id': linkId
8161          });
8162
8163          $tabContent.attr({
8164            'role': 'tabpanel',
8165            'aria-hidden': !isActive,
8166            'aria-labelledby': linkId
8167          });
8168
8169          if (isActive && _this.options.autoFocus) {
8170            $link.focus();
8171          }
8172        });
8173
8174        if (this.options.matchHeight) {
8175          var $images = this.$tabContent.find('img');
8176
8177          if ($images.length) {
8178            Foundation.onImagesLoaded($images, this._setHeight.bind(this));
8179          } else {
8180            this._setHeight();
8181          }
8182        }
8183
8184        this._events();
8185      }
8186
8187      /**
8188       * Adds event handlers for items within the tabs.
8189       * @private
8190       */
8191
8192    }, {
8193      key: '_events',
8194      value: function _events() {
8195        this._addKeyHandler();
8196        this._addClickHandler();
8197        this._setHeightMqHandler = null;
8198
8199        if (this.options.matchHeight) {
8200          this._setHeightMqHandler = this._setHeight.bind(this);
8201
8202          $(window).on('changed.zf.mediaquery', this._setHeightMqHandler);
8203        }
8204      }
8205
8206      /**
8207       * Adds click handlers for items within the tabs.
8208       * @private
8209       */
8210
8211    }, {
8212      key: '_addClickHandler',
8213      value: function _addClickHandler() {
8214        var _this = this;
8215
8216        this.$element.off('click.zf.tabs').on('click.zf.tabs', '.' + this.options.linkClass, function (e) {
8217          e.preventDefault();
8218          e.stopPropagation();
8219          if ($(this).hasClass('is-active')) {
8220            return;
8221          }
8222          _this._handleTabChange($(this));
8223        });
8224      }
8225
8226      /**
8227       * Adds keyboard event handlers for items within the tabs.
8228       * @private
8229       */
8230
8231    }, {
8232      key: '_addKeyHandler',
8233      value: function _addKeyHandler() {
8234        var _this = this;
8235        var $firstTab = _this.$element.find('li:first-of-type');
8236        var $lastTab = _this.$element.find('li:last-of-type');
8237
8238        this.$tabTitles.off('keydown.zf.tabs').on('keydown.zf.tabs', function (e) {
8239          if (e.which === 9) return;
8240
8241          var $element = $(this),
8242              $elements = $element.parent('ul').children('li'),
8243              $prevElement,
8244              $nextElement;
8245
8246          $elements.each(function (i) {
8247            if ($(this).is($element)) {
8248              if (_this.options.wrapOnKeys) {
8249                $prevElement = i === 0 ? $elements.last() : $elements.eq(i - 1);
8250                $nextElement = i === $elements.length - 1 ? $elements.first() : $elements.eq(i + 1);
8251              } else {
8252                $prevElement = $elements.eq(Math.max(0, i - 1));
8253                $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1));
8254              }
8255              return;
8256            }
8257          });
8258
8259          // handle keyboard event with keyboard util
8260          Foundation.Keyboard.handleKey(e, 'Tabs', {
8261            open: function () {
8262              $element.find('[role="tab"]').focus();
8263              _this._handleTabChange($element);
8264            },
8265            previous: function () {
8266              $prevElement.find('[role="tab"]').focus();
8267              _this._handleTabChange($prevElement);
8268            },
8269            next: function () {
8270              $nextElement.find('[role="tab"]').focus();
8271              _this._handleTabChange($nextElement);
8272            },
8273            handled: function () {
8274              e.stopPropagation();
8275              e.preventDefault();
8276            }
8277          });
8278        });
8279      }
8280
8281      /**
8282       * Opens the tab `$targetContent` defined by `$target`.
8283       * @param {jQuery} $target - Tab to open.
8284       * @fires Tabs#change
8285       * @function
8286       */
8287
8288    }, {
8289      key: '_handleTabChange',
8290      value: function _handleTabChange($target) {
8291        var $tabLink = $target.find('[role="tab"]'),
8292            hash = $tabLink[0].hash,
8293            $targetContent = this.$tabContent.find(hash),
8294            $oldTab = this.$element.find('.' + this.options.linkClass + '.is-active').removeClass('is-active').find('[role="tab"]').attr({ 'aria-selected': 'false' });
8295
8296        $('#' + $oldTab.attr('aria-controls')).removeClass('is-active').attr({ 'aria-hidden': 'true' });
8297
8298        $target.addClass('is-active');
8299
8300        $tabLink.attr({ 'aria-selected': 'true' });
8301
8302        $targetContent.addClass('is-active').attr({ 'aria-hidden': 'false' });
8303
8304        /**
8305         * Fires when the plugin has successfully changed tabs.
8306         * @event Tabs#change
8307         */
8308        this.$element.trigger('change.zf.tabs', [$target]);
8309      }
8310
8311      /**
8312       * Public method for selecting a content pane to display.
8313       * @param {jQuery | String} elem - jQuery object or string of the id of the pane to display.
8314       * @function
8315       */
8316
8317    }, {
8318      key: 'selectTab',
8319      value: function selectTab(elem) {
8320        var idStr;
8321
8322        if (typeof elem === 'object') {
8323          idStr = elem[0].id;
8324        } else {
8325          idStr = elem;
8326        }
8327
8328        if (idStr.indexOf('#') < 0) {
8329          idStr = '#' + idStr;
8330        }
8331
8332        var $target = this.$tabTitles.find('[href="' + idStr + '"]').parent('.' + this.options.linkClass);
8333
8334        this._handleTabChange($target);
8335      }
8336    }, {
8337      key: '_setHeight',
8338
8339      /**
8340       * Sets the height of each panel to the height of the tallest panel.
8341       * If enabled in options, gets called on media query change.
8342       * If loading content via external source, can be called directly or with _reflow.
8343       * @function
8344       * @private
8345       */
8346      value: function _setHeight() {
8347        var max = 0;
8348        this.$tabContent.find('.' + this.options.panelClass).css('height', '').each(function () {
8349          var panel = $(this),
8350              isActive = panel.hasClass('is-active');
8351
8352          if (!isActive) {
8353            panel.css({ 'visibility': 'hidden', 'display': 'block' });
8354          }
8355
8356          var temp = this.getBoundingClientRect().height;
8357
8358          if (!isActive) {
8359            panel.css({
8360              'visibility': '',
8361              'display': ''
8362            });
8363          }
8364
8365          max = temp > max ? temp : max;
8366        }).css('height', max + 'px');
8367      }
8368
8369      /**
8370       * Destroys an instance of an tabs.
8371       * @fires Tabs#destroyed
8372       */
8373
8374    }, {
8375      key: 'destroy',
8376      value: function destroy() {
8377        this.$element.find('.' + this.options.linkClass).off('.zf.tabs').hide().end().find('.' + this.options.panelClass).hide();
8378
8379        if (this.options.matchHeight) {
8380          if (this._setHeightMqHandler != null) {
8381            $(window).off('changed.zf.mediaquery', this._setHeightMqHandler);
8382          }
8383        }
8384
8385        Foundation.unregisterPlugin(this);
8386      }
8387    }]);
8388
8389    return Tabs;
8390  }();
8391
8392  Tabs.defaults = {
8393    /**
8394     * Allows the window to scroll to content of active pane on load if set to true.
8395     * @option
8396     * @example false
8397     */
8398    autoFocus: false,
8399
8400    /**
8401     * Allows keyboard input to 'wrap' around the tab links.
8402     * @option
8403     * @example true
8404     */
8405    wrapOnKeys: true,
8406
8407    /**
8408     * Allows the tab content panes to match heights if set to true.
8409     * @option
8410     * @example false
8411     */
8412    matchHeight: false,
8413
8414    /**
8415     * Class applied to `li`'s in tab link list.
8416     * @option
8417     * @example 'tabs-title'
8418     */
8419    linkClass: 'tabs-title',
8420
8421    /**
8422     * Class applied to the content containers.
8423     * @option
8424     * @example 'tabs-panel'
8425     */
8426    panelClass: 'tabs-panel'
8427  };
8428
8429  function checkClass($elem) {
8430    return $elem.hasClass('is-active');
8431  }
8432
8433  // Window exports
8434  Foundation.plugin(Tabs, 'Tabs');
8435}(jQuery);
8436'use strict';
8437
8438var _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; }; }();
8439
8440function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8441
8442!function ($) {
8443
8444  /**
8445   * Toggler module.
8446   * @module foundation.toggler
8447   * @requires foundation.util.motion
8448   * @requires foundation.util.triggers
8449   */
8450
8451  var Toggler = function () {
8452    /**
8453     * Creates a new instance of Toggler.
8454     * @class
8455     * @fires Toggler#init
8456     * @param {Object} element - jQuery object to add the trigger to.
8457     * @param {Object} options - Overrides to the default plugin settings.
8458     */
8459
8460    function Toggler(element, options) {
8461      _classCallCheck(this, Toggler);
8462
8463      this.$element = element;
8464      this.options = $.extend({}, Toggler.defaults, element.data(), options);
8465      this.className = '';
8466
8467      this._init();
8468      this._events();
8469
8470      Foundation.registerPlugin(this, 'Toggler');
8471    }
8472
8473    /**
8474     * Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate.
8475     * @function
8476     * @private
8477     */
8478
8479
8480    _createClass(Toggler, [{
8481      key: '_init',
8482      value: function _init() {
8483        var input;
8484        // Parse animation classes if they were set
8485        if (this.options.animate) {
8486          input = this.options.animate.split(' ');
8487
8488          this.animationIn = input[0];
8489          this.animationOut = input[1] || null;
8490        }
8491        // Otherwise, parse toggle class
8492        else {
8493            input = this.$element.data('toggler');
8494            // Allow for a . at the beginning of the string
8495            this.className = input[0] === '.' ? input.slice(1) : input;
8496          }
8497
8498        // Add ARIA attributes to triggers
8499        var id = this.$element[0].id;
8500        $('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-controls', id);
8501        // If the target is hidden, add aria-hidden
8502        this.$element.attr('aria-expanded', this.$element.is(':hidden') ? false : true);
8503      }
8504
8505      /**
8506       * Initializes events for the toggle trigger.
8507       * @function
8508       * @private
8509       */
8510
8511    }, {
8512      key: '_events',
8513      value: function _events() {
8514        this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this));
8515      }
8516
8517      /**
8518       * 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".
8519       * @function
8520       * @fires Toggler#on
8521       * @fires Toggler#off
8522       */
8523
8524    }, {
8525      key: 'toggle',
8526      value: function toggle() {
8527        this[this.options.animate ? '_toggleAnimate' : '_toggleClass']();
8528      }
8529    }, {
8530      key: '_toggleClass',
8531      value: function _toggleClass() {
8532        this.$element.toggleClass(this.className);
8533
8534        var isOn = this.$element.hasClass(this.className);
8535        if (isOn) {
8536          /**
8537           * Fires if the target element has the class after a toggle.
8538           * @event Toggler#on
8539           */
8540          this.$element.trigger('on.zf.toggler');
8541        } else {
8542          /**
8543           * Fires if the target element does not have the class after a toggle.
8544           * @event Toggler#off
8545           */
8546          this.$element.trigger('off.zf.toggler');
8547        }
8548
8549        this._updateARIA(isOn);
8550      }
8551    }, {
8552      key: '_toggleAnimate',
8553      value: function _toggleAnimate() {
8554        var _this = this;
8555
8556        if (this.$element.is(':hidden')) {
8557          Foundation.Motion.animateIn(this.$element, this.animationIn, function () {
8558            _this._updateARIA(true);
8559            this.trigger('on.zf.toggler');
8560          });
8561        } else {
8562          Foundation.Motion.animateOut(this.$element, this.animationOut, function () {
8563            _this._updateARIA(false);
8564            this.trigger('off.zf.toggler');
8565          });
8566        }
8567      }
8568    }, {
8569      key: '_updateARIA',
8570      value: function _updateARIA(isOn) {
8571        this.$element.attr('aria-expanded', isOn ? true : false);
8572      }
8573
8574      /**
8575       * Destroys the instance of Toggler on the element.
8576       * @function
8577       */
8578
8579    }, {
8580      key: 'destroy',
8581      value: function destroy() {
8582        this.$element.off('.zf.toggler');
8583        Foundation.unregisterPlugin(this);
8584      }
8585    }]);
8586
8587    return Toggler;
8588  }();
8589
8590  Toggler.defaults = {
8591    /**
8592     * Tells the plugin if the element should animated when toggled.
8593     * @option
8594     * @example false
8595     */
8596    animate: false
8597  };
8598
8599  // Window exports
8600  Foundation.plugin(Toggler, 'Toggler');
8601}(jQuery);
8602'use strict';
8603
8604var _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; }; }();
8605
8606function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8607
8608!function ($) {
8609
8610  /**
8611   * Tooltip module.
8612   * @module foundation.tooltip
8613   * @requires foundation.util.box
8614   * @requires foundation.util.triggers
8615   */
8616
8617  var Tooltip = function () {
8618    /**
8619     * Creates a new instance of a Tooltip.
8620     * @class
8621     * @fires Tooltip#init
8622     * @param {jQuery} element - jQuery object to attach a tooltip to.
8623     * @param {Object} options - object to extend the default configuration.
8624     */
8625
8626    function Tooltip(element, options) {
8627      _classCallCheck(this, Tooltip);
8628
8629      this.$element = element;
8630      this.options = $.extend({}, Tooltip.defaults, this.$element.data(), options);
8631
8632      this.isActive = false;
8633      this.isClick = false;
8634      this._init();
8635
8636      Foundation.registerPlugin(this, 'Tooltip');
8637    }
8638
8639    /**
8640     * Initializes the tooltip by setting the creating the tip element, adding it's text, setting private variables and setting attributes on the anch
8640or.
8641     * @private
8642     */
8643
8644
8645    _createClass(Tooltip, [{
8646      key: '_init',
8647      value: function _init() {
8648        var elemId = this.$element.attr('aria-describedby') || Foundation.GetYoDigits(6, 'tooltip');
8649
8650        this.options.positionClass = this.options.positionClass || this._getPositionClass(this.$element);
8651        this.options.tipText = this.options.tipText || this.$element.attr('title');
8652        this.template = this.options.template ? $(this.options.template) : this._buildTemplate(elemId);
8653
8654        this.template.appendTo(document.body).text(this.options.tipText).hide();
8655
8656        this.$element.attr({
8657          'title': '',
8658          'aria-describedby': elemId,
8659          'data-yeti-box': elemId,
8660          'data-toggle': elemId,
8661          'data-resize': elemId
8662        }).addClass(this.triggerClass);
8663
8664        //helper variables to track movement on collisions
8665        this.usedPositions = [];
8666        this.counter = 4;
8667        this.classChanged = false;
8668
8669        this._events();
8670      }
8671
8672      /**
8673       * Grabs the current positioning class, if present, and returns the value or an empty string.
8674       * @private
8675       */
8676
8677    }, {
8678      key: '_getPositionClass',
8679      value: function _getPositionClass(element) {
8680        if (!element) {
8681          return '';
8682        }
8683        // var position = element.attr('class').match(/top|left|right/g);
8684        var position = element[0].className.match(/\b(top|left|right)\b/g);
8685        position = position ? position[0] : '';
8686        return position;
8687      }
8688    }, {
8689      key: '_buildTemplate',
8690
8691      /**
8692       * builds the tooltip element, adds attributes, and returns the template.
8693       * @private
8694       */
8695      value: function _buildTemplate(id) {
8696        var templateClasses = (this.options.tooltipClass + ' ' + this.options.positionClass + ' ' + this.options.templateClasses).trim();
8697        var $template = $('<div></div>').addClass(templateClasses).attr({
8698          'role': 'tooltip',
8699          'aria-hidden': true,
8700          'data-is-active': false,
8701          'data-is-focus': false,
8702          'id': id
8703        });
8704        return $template;
8705      }
8706
8707      /**
8708       * Function that gets called if a collision event is detected.
8709       * @param {String} position - positioning class to try
8710       * @private
8711       */
8712
8713    }, {
8714      key: '_reposition',
8715      value: function _reposition(position) {
8716        this.usedPositions.push(position ? position : 'bottom');
8717
8718        //default, try switching to opposite side
8719        if (!position && this.usedPositions.indexOf('top') < 0) {
8720          this.template.addClass('top');
8721        } else if (position === 'top' && this.usedPositions.indexOf('bottom') < 0) {
8722          this.template.removeClass(position);
8723        } else if (position === 'left' && this.usedPositions.indexOf('right') < 0) {
8724          this.template.removeClass(position).addClass('right');
8725        } else if (position === 'right' && this.usedPositions.indexOf('left') < 0) {
8726          this.template.removeClass(position).addClass('left');
8727        }
8728
8729        //if default change didn't work, try bottom or left first
8730        else if (!position && this.usedPositions.indexOf('top') > -1 && this.usedPositions.indexOf('left') < 0) {
8731            this.template.addClass('left');
8732          } else if (position === 'top' && this.usedPositions.indexOf('bottom') > -1 && this.usedPositions.indexOf('left') < 0) {
8733            this.template.removeClass(position).addClass('left');
8734          } else if (position === 'left' && this.usedPositions.indexOf('right') > -1 && this.usedPositions.indexOf('bottom') < 0) {
8735            this.template.removeClass(position);
8736          } else if (position === 'right' && this.usedPositions.indexOf('left') > -1 && this.usedPositions.indexOf('bottom') < 0) {
8737            this.template.removeClass(position);
8738          }
8739          //if nothing cleared, set to bottom
8740          else {
8741              this.template.removeClass(position);
8742            }
8743        this.classChanged = true;
8744        this.counter--;
8745      }
8746
8747      /**
8748       * sets the position class of an element and recursively calls itself until there are no more possible positions to attempt, or the tooltip element is no longer colliding.
8749       * if the tooltip is larger than the screen width, default to full width - any user selected margin
8750       * @private
8751       */
8752
8753    }, {
8754      key: '_setPosition',
8755      value: function _setPosition() {
8756        var position = this._getPositionClass(this.template),
8757            $tipDims = Foundation.Box.GetDimensions(this.template),
8758            $anchorDims = Foundation.Box.GetDimensions(this.$element),
8759            direction = position === 'left' ? 'left' : position === 'right' ? 'left' : 'top',
8760            param = direction === 'top' ? 'height' : 'width',
8761            offset = param === 'height' ? this.options.vOffset : this.options.hOffset,
8762            _this = this;
8763
8764        if ($tipDims.width >= $tipDims.windowDims.width || !this.counter && !Foundation.Box.ImNotTouchingYou(this.template)) {
8765          this.template.offset(Foundation.Box.GetOffsets(this.template, this.$element, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
8766            // this.$element.offset(Foundation.GetOffsets(this.template, this.$element, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
8767            'width': $anchorDims.windowDims.width - this.options.hOffset * 2,
8768            'height': 'auto'
8769          });
8770          return false;
8771        }
8772
8773        this.template.offset(Foundation.Box.GetOffsets(this.template, this.$element, 'center ' + (position || 'bottom'), this.options.vOffset, this.options.hOffset));
8774
8775        while (!Foundation.Box.ImNotTouchingYou(this.template) && this.counter) {
8776          this._reposition(position);
8777          this._setPosition();
8778        }
8779      }
8780
8781      /**
8782       * reveals the tooltip, and fires an event to close any other open tooltips on the page
8783       * @fires Tooltip#closeme
8784       * @fires Tooltip#show
8785       * @function
8786       */
8787
8788    }, {
8789      key: 'show',
8790      value: function show() {
8791        if (this.options.showOn !== 'all' && !Foundation.MediaQuery.atLeast(this.options.showOn)) {
8792          // console.error('The screen is too small to display this tooltip');
8793          return false;
8794        }
8795
8796        var _this = this;
8797        this.template.css('visibility', 'hidden').show();
8798        this._setPosition();
8799
8800        /**
8801         * Fires to close all other open tooltips on the page
8802         * @event Closeme#tooltip
8803         */
8804        this.$element.trigger('closeme.zf.tooltip', this.template.attr('id'));
8805
8806        this.template.attr({
8807          'data-is-active': true,
8808          'aria-hidden': false
8809        });
8810        _this.isActive = true;
8811        // console.log(this.template);
8812        this.template.stop().hide().css('visibility', '').fadeIn(this.options.fadeInDuration, function () {
8813          //maybe do stuff?
8814        });
8815        /**
8816         * Fires when the tooltip is shown
8817         * @event Tooltip#show
8818         */
8819        this.$element.trigger('show.zf.tooltip');
8820      }
8821
8822      /**
8823       * Hides the current tooltip, and resets the positioning class if it was changed due to collision
8824       * @fires Tooltip#hide
8825       * @function
8826       */
8827
8828    }, {
8829      key: 'hide',
8830      value: function hide() {
8831        // console.log('hiding', this.$element.data('yeti-box'));
8832        var _this = this;
8833        this.template.stop().attr({
8834          'aria-hidden': true,
8835          'data-is-active': false
8836        }).fadeOut(this.options.fadeOutDuration, function () {
8837          _this.isActive = false;
8838          _this.isClick = false;
8839          if (_this.classChanged) {
8840            _this.template.removeClass(_this._getPositionClass(_this.template)).addClass(_this.options.positionClass);
8841
8842            _this.usedPositions = [];
8843            _this.counter = 4;
8844            _this.classChanged = false;
8845          }
8846        });
8847        /**
8848         * fires when the tooltip is hidden
8849         * @event Tooltip#hide
8850         */
8851        this.$element.trigger('hide.zf.tooltip');
8852      }
8853
8854      /**
8855       * adds event listeners for the tooltip and its anchor
8856       * TODO combine some of the listeners like focus and mouseenter, etc.
8857       * @private
8858       */
8859
8860    }, {
8861      key: '_events',
8862      value: function _events() {
8863        var _this = this;
8864        var $template = this.template;
8865        var isFocus = false;
8866
8867        if (!this.options.disableHover) {
8868
8869          this.$element.on('mouseenter.zf.tooltip', function (e) {
8870            if (!_this.isActive) {
8871              _this.timeout = setTimeout(function () {
8872                _this.show();
8873              }, _this.options.hoverDelay);
8874            }
8875          }).on('mouseleave.zf.tooltip', function (e) {
8876            clearTimeout(_this.timeout);
8877            if (!isFocus || _this.isClick && !_this.options.clickOpen) {
8878              _this.hide();
8879            }
8880          });
8881        }
8882
8883        if (this.options.clickOpen) {
8884          this.$element.on('mousedown.zf.tooltip', function (e) {
8885            e.stopImmediatePropagation();
8886            if (_this.isClick) {
8887              //_this.hide();
8888              // _this.isClick = false;
8889            } else {
8890                _this.isClick = true;
8891                if ((_this.options.disableHover || !_this.$element.attr('tabindex')) && !_this.isActive) {
8892                  _this.show();
8893                }
8894              }
8895          });
8896        } else {
8897          this.$element.on('mousedown.zf.tooltip', function (e) {
8898            e.stopImmediatePropagation();
8899            _this.isClick = true;
8900          });
8901        }
8902
8903        if (!this.options.disableForTouch) {
8904          this.$element.on('tap.zf.tooltip touchend.zf.tooltip', function (e) {
8905            _this.isActive ? _this.hide() : _this.show();
8906          });
8907        }
8908
8909        this.$element.on({
8910          // 'toggle.zf.trigger': this.toggle.bind(this),
8911          // 'close.zf.trigger': this.hide.bind(this)
8912          'close.zf.trigger': this.hide.bind(this)
8913        });
8914
8915        this.$element.on('focus.zf.tooltip', function (e) {
8916          isFocus = true;
8917          if (_this.isClick) {
8918            // If we're not showing open on clicks, we need to pretend a click-launched focus isn't
8919            // a real focus, otherwise on hover and come back we get bad behavior
8920            if (!_this.options.clickOpen) {
8921              isFocus = false;
8922            }
8923            return false;
8924          } else {
8925            _this.show();
8926          }
8927        }).on('focusout.zf.tooltip', function (e) {
8928          isFocus = false;
8929          _this.isClick = false;
8930          _this.hide();
8931        }).on('resizeme.zf.trigger', function () {
8932          if (_this.isActive) {
8933            _this._setPosition();
8934          }
8935        });
8936      }
8937
8938      /**
8939       * adds a toggle method, in addition to the static show() & hide() functions
8940       * @function
8941       */
8942
8943    }, {
8944      key: 'toggle',
8945      value: function toggle() {
8946        if (this.isActive) {
8947          this.hide();
8948        } else {
8949          this.show();
8950        }
8951      }
8952
8953      /**
8954       * Destroys an instance of tooltip, removes template element from the view.
8955       * @function
8956       */
8957
8958    }, {
8959      key: 'destroy',
8960      value: function destroy() {
8961        this.$element.attr('title', this.template.text()).off('.zf.trigger .zf.tootip')
8962        //  .removeClass('has-tip')
8963        .removeAttr('aria-describedby').removeAttr('data-yeti-box').removeAttr('data-toggle').removeAttr('data-resize');
8964
8965        this.template.remove();
8966
8967        Foundation.unregisterPlugin(this);
8968      }
8969    }]);
8970
8971    return Tooltip;
8972  }();
8973
8974  Tooltip.defaults = {
8975    disableForTouch: false,
8976    /**
8977     * Time, in ms, before a tooltip should open on hover.
8978     * @option
8979     * @example 200
8980     */
8981    hoverDelay: 200,
8982    /**
8983     * Time, in ms, a tooltip should take to fade into view.
8984     * @option
8985     * @example 150
8986     */
8987    fadeInDuration: 150,
8988    /**
8989     * Time, in ms, a tooltip should take to fade out of view.
8990     * @option
8991     * @example 150
8992     */
8993    fadeOutDuration: 150,
8994    /**
8995     * Disables hover events from opening the tooltip if set to true
8996     * @option
8997     * @example false
8998     */
8999    disableHover: false,
9000    /**
9001     * Optional addtional classes to apply to the tooltip template on init.
9002     * @option
9003     * @example 'my-cool-tip-class'
9004     */
9005    templateClasses: '',
9006    /**
9007     * Non-optional class added to tooltip templates. Foundation default is 'tooltip'.
9008     * @option
9009     * @example 'tooltip'
9010     */
9011    tooltipClass: 'tooltip',
9012    /**
9013     * Class applied to the tooltip anchor element.
9014     * @option
9015     * @example 'has-tip'
9016     */
9017    triggerClass: 'has-tip',
9018    /**
9019     * Minimum breakpoint size at which to open the tooltip.
9020     * @option
9021     * @example 'small'
9022     */
9023    showOn: 'small',
9024    /**
9025     * Custom template to be used to generate markup for tooltip.
9026     * @option
9027     * @example '&lt;div class="tooltip"&gt;&lt;/div&gt;'
9028     */
9029    template: '',
9030    /**
9031     * Text displayed in the tooltip template on open.
9032     * @option
9033     * @example 'Some cool space fact here.'
9034     */
9035    tipText: '',
9036    touchCloseText: 'Tap to close.',
9037    /**
9038     * Allows the tooltip to remain open if triggered with a click or touch event.
9039     * @option
9040     * @example true
9041     */
9042    clickOpen: true,
9043    /**
9044     * Additional positioning classes, set by the JS
9045     * @option
9046     * @example 'top'
9047     */
9048    positionClass: '',
9049    /**
9050     * Distance, in pixels, the template should push away from the anch
9050or on the Y axis.
9051     * @option
9052     * @example 10
9053     */
9054    vOffset: 10,
9055    /**
9056     * Distance, in pixels, the template should push away from the anchor on the X axis, if aligned to a side.
9057     * @option
9058     * @example 12
9059     */
9060    hOffset: 12
9061  };
9062
9063  /**
9064   * TODO utilize resize event trigger
9065   */
9066
9067  // Window exports
9068  Foundation.plugin(Tooltip, 'Tooltip');
9069}(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.