PageSourceSearch

https://www.westernrailyardinfrastructure.com/js/foundation.js

js westernrailyardinfrastructure.com collected 2026-10-05 07:05:21 UTC 297,777 bytes, 9,143 lines download raw bytes

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