PageSourceSearch

https://activerain.com/assets/foundation/vendor/foundation-b427e46…43c7f47d6e93536f8d6fd4b59e8e13766b3883b1.js

js activerain.com collected 2026-09-24 08:49:22 UTC 93,086 bytes, 2,785 lines download raw bytes

1!function ($) {
2
3  "use strict";
4
5  var FOUNDATION_VERSION = '6.2.1';
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 repeditive 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 repeditive 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        self.queries.push({
418          name: key,
419          value: 'only screen and (min-width: ' + namedQueries[key] + ')'
420        });
421      }
422
423      this.current = this._getCurrentSize();
424
425      this._watcher();
426    },
427
428
429    /**
430     * Checks if the screen is at least as wide as a breakpoint.
431     * @function
432     * @param {String} size - Name of the breakpoint to check.
433     * @returns {Boolean} `true` if the breakpoint matches, `false` if it's smaller.
434     */
435    atLeast: function (size) {
436      var query = this.get(size);
437
438      if (query) {
439        return window.matchMedia(query).matches;
440      }
441
442      return false;
443    },
444
445
446    /**
447     * Gets the media query of a breakpoint.
448     * @function
449     * @param {String} size - Name of the breakpoint to get.
450     * @returns {String|null} - The media query of the breakpoint, or `null` if the breakpoint doesn't exist.
451     */
452    get: function (size) {
453      for (var i in this.queries) {
454        var query = this.queries[i];
455        if (size === query.name) return query.value;
456      }
457
458      return null;
459    },
460
461
462    /**
463     * Gets the current breakpoint name by testing every breakpoint and returning the last one to match (the biggest one).
464     * @function
465     * @private
466     * @returns {String} Name of the current breakpoint.
467     */
468    _getCurrentSize: function () {
469      var matched;
470
471      for (var i = 0; i < this.queries.length; i++) {
472        var query = this.queries[i];
473
474        if (window.matchMedia(query.value).matches) {
475          matched = query;
476        }
477      }
478
479      if (typeof matched === 'object') {
480        return matched.name;
481      } else {
482        return matched;
483      }
484    },
485
486
487    /**
488     * Activates the breakpoint watcher, which fires an event on the window whenever the breakpoint changes.
489     * @function
490     * @private
491     */
492    _watcher: function () {
493      var _this = this;
494
495      $(window).on('resize.zf.mediaquery', function () {
496        var newSize = _this._getCurrentSize();
497
498        if (newSize !== _this.current) {
499          // Broadcast the media query change on the window
500          $(window).trigger('changed.zf.mediaquery', [newSize, _this.current]);
501
502          // Change the current media query
503          _this.current = newSize;
504        }
505      });
506    }
507  };
508
509  Foundation.MediaQuery = MediaQuery;
510
511  // matchMedia() polyfill - Test a CSS media type/query in JS.
512  // Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license
513  window.matchMedia || (window.matchMedia = function () {
514    'use strict';
515
516    // For browsers that support matchMedium api such as IE 9 and webkit
517
518    var styleMedia = window.styleMedia || window.media;
519
520    // For those that don't support matchMedium
521    if (!styleMedia) {
522      var style = document.createElement('style'),
523          script = document.getElementsByTagName('script')[0],
524          info = null;
525
526      style.type = 'text/css';
527      style.id = 'matchmediajs-test';
528
529      script.parentNode.insertBefore(style, script);
530
531      // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
532      info = 'getComputedStyle' in window && window.getComputedStyle(style, null) || style.currentStyle;
533
534      styleMedia = {
535        matchMedium: function (media) {
536          var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
537
538          // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
539          if (style.styleSheet) {
540            style.styleSheet.cssText = text;
541          } else {
542            style.textContent = text;
543          }
544
545          // Test if media query is true or false
546          return info.width === '1px';
547        }
548      };
549    }
550
551    return function (media) {
552      return {
553        matches: styleMedia.matchMedium(media || 'all'),
554        media: media || 'all'
555      };
556    };
557  }());
558
559  // Thank you: https://github.com/sindresorhus/query-string
560  function parseStyleToObject(str) {
561    var styleObject = {};
562
563    if (typeof str !== 'string') {
564      return styleObject;
565    }
566
567    str = str.trim().slice(1, -1);
567 // browsers re-quote string style values
568
569    if (!str) {
570      return styleObject;
571    }
572
573    styleObject = str.split('&').reduce(function (ret, param) {
574      var parts = param.replace(/\+/g, ' ').split('=');
575      var key = parts[0];
576      var val = parts[1];
577      key = decodeURIComponent(key);
578
579      // missing `=` should be `null`:
580      // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
581      val = val === undefined ? null : decodeURIComponent(val);
582
583      if (!ret.hasOwnProperty(key)) {
584        ret[key] = val;
585      } else if (Array.isArray(ret[key])) {
586        ret[key].push(val);
587      } else {
588        ret[key] = [ret[key], val];
589      }
590      return ret;
591    }, {});
592
593    return styleObject;
594  }
595
596  Foundation.MediaQuery = MediaQuery;
597}(jQuery);
598/*******************************************
599 *                                         *
600 * This util was created by Marius Olbertz *
601 * Please thank Marius on GitHub /owlbertz *
602 * or the web http://www.mariusolbertz.de/ *
603 *                                         *
604 ******************************************/
605
606'use strict';
607
608!function ($) {
609
610  var keyCodes = {
611    9: 'TAB',
612    13: 'ENTER',
613    27: 'ESCAPE',
614    32: 'SPACE',
615    37: 'ARROW_LEFT',
616    38: 'ARROW_UP',
617    39: 'ARROW_RIGHT',
618    40: 'ARROW_DOWN'
619  };
620
621  var commands = {};
622
623  var Keyboard = {
624    keys: getKeyCodes(keyCodes),
625
626    /**
627     * Parses the (keyboard) event and returns a String that represents its key
628     * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
629     * @param {Event} event - the event generated by the event handler
630     * @return String key - String that represents the key pressed
631     */
632    parseKey: function (event) {
633      var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase();
634      if (event.shiftKey) key = 'SHIFT_' + key;
635      if (event.ctrlKey) key = 'CTRL_' + key;
636      if (event.altKey) key = 'ALT_' + key;
637      return key;
638    },
639
640
641    /**
642     * Handles the given (keyboard) event
643     * @param {Event} event - the event generated by the event handler
644     * @param {String} component - Foundation component's name, e.g. Slider or Reveal
645     * @param {Objects} functions - collection of functions that are to be executed
646     */
647    handleKey: function (event, component, functions) {
648      var commandList = commands[component],
649          keyCode = this.parseKey(event),
650          cmds,
651          command,
652          fn;
653
654      if (!commandList) return console.warn('Component not defined!');
655
656      if (typeof commandList.ltr === 'undefined') {
657        // this component does not differentiate between ltr and rtl
658        cmds = commandList; // use plain list
659      } else {
660          // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa
661          if (Foundation.rtl()) cmds = $.extend({}, commandList.ltr, commandList.rtl);else cmds = $.extend({}, commandList.rtl, commandList.ltr);
662        }
663      command = cmds[keyCode];
664
665      fn = functions[command];
666      if (fn && typeof fn === 'function') {
667        // execute function  if exists
668        fn.apply();
669        if (functions.handled || typeof functions.handled === 'function') {
670          // execute function when event was handled
671          functions.handled.apply();
672        }
673      } else {
674        if (functions.unhandled || typeof functions.unhandled === 'function') {
675          // execute function when event was not handled
676          functions.unhandled.apply();
677        }
678      }
679    },
680
681
682    /**
683     * Finds all focusable elements within the given `$element`
684     * @param {jQuery} $element - jQuery object to search within
685     * @return {jQuery} $focusable - all focusable elements within `$element`
686     */
687    findFocusable: function ($element) {
688      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 () {
689        if (!$(this).is(':visible') || $(this).attr('tabindex') < 0) {
690          return false;
691        } //only have visible elements and those that have a tabindex greater or equal 0
692        return true;
693      });
694    },
695
696
697    /**
698     * Returns the component name name
699     * @param {Object} component - Foundation component, e.g. Slider or Reveal
700     * @return String componentName
701     */
702
703    register: function (componentName, cmds) {
704      commands[componentName] = cmds;
705    }
706  };
707
708  /*
709   * Constants for easier comparing.
710   * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
711   */
712  function getKeyCodes(kcs) {
713    var k = {};
714    for (var kc in kcs) {
715      k[kcs[kc]] = kcs[kc];
716    }return k;
717  }
718
719  Foundation.Keyboard = Keyboard;
720}(jQuery);
721'use strict';
722
723!function ($) {
724
725  /**
726   * Motion module.
727   * @module foundation.motion
728   */
729
730  var initClasses = ['mui-enter', 'mui-leave'];
731  var activeClasses = ['mui-enter-active', 'mui-leave-active'];
732
733  var Motion = {
734    animateIn: function (element, animation, cb) {
735      animate(true, element, animation, cb);
736    },
737
738    animateOut: function (element, animation, cb) {
739      animate(false, element, animation, cb);
740    }
741  };
742
743  function Move(duration, elem, fn) {
744    var anim,
745        prog,
746        start = null;
747    // console.log('called');
748
749    function move(ts) {
750      if (!start) start = window.performance.now();
751      // console.log(start, ts);
752      prog = ts - start;
753      fn.apply(elem);
754
755      if (prog < duration) {
756        anim = window.requestAnimationFrame(move, elem);
757      } else {
758        window.cancelAnimationFrame(anim);
759        elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
760      }
761    }
762    anim = window.requestAnimationFrame(move);
763  }
764
765  /**
766   * Animates an element in or out using a CSS transition class.
767   * @function
768   * @private
769   * @param {Boolean} isIn - Defines if the animation is in or out.
770   * @param {Object} element - jQuery or HTML object to animate.
771   * @param {String} animation - CSS class to use.
772   * @param {Function} cb - Callback to run when animation is finished.
773   */
774  function animate(isIn, element, animation, cb) {
775    element = $(element).eq(0);
776
777    if (!element.length) return;
778
779    var initClass = isIn ? initClasses[0] : initClasses[1];
780    var activeClass = isIn ? activeClasses[0] : activeClasses[1];
781
782    // Set up the animation
783    reset();
784
785    element.addClass(animation).css('transition', 'none');
786
787    requestAnimationFrame(function () {
788      element.addClass(initClass);
789      if (isIn) element.show();
790    });
791
792    // Start the animation
793    requestAnimationFrame(function () {
794      element[0].offsetWidth;
795      element.css('transition', '').addClass(activeClass);
796    });
797
798    // Clean up the animation when it finishes
799    element.one(Foundation.transitionend(element), finish);
800
801    // Hides the element (for out animations), resets the element, and runs a callback
802    function finish() {
803      if (!isIn) element.hide();
804      reset();
805      if (cb) cb.apply(element);
806    }
807
808    // Resets transitions and removes motion-specific classes
809    function reset() {
810      element[0].style.transitionDuration = 0;
811      element.removeClass(initClass + ' ' + activeClass + ' ' + animation);
812    }
813  }
814
815  Foundation.Move = Move;
816  Foundation.Motion = Motion;
817}(jQuery);
818'use strict';
819
820!function ($) {
821
822  var Nest = {
823    Feather: function (menu) {
824      var type = arguments.length <= 1 || arguments[1] === undefined ? 'zf' : arguments[1];
825
826      menu.attr('role', 'menubar');
827
828      var items = menu.find('li').attr({ 'role': 'menuitem' }),
829          subMenuClass = 'is-' + type + '-submenu',
830          subItemClass = subMenuClass + '-item',
831          hasSubClass = 'is-' + type + '-submenu-parent';
832
833      menu.find('a:first').attr('tabindex', 0);
834
835      items.each(function () {
836        var $item = $(this),
837            $sub = $item.children('ul');
838
839        if ($sub.length) {
840          $item.addClass(hasSubClass).attr({
841            'aria-haspopup': true,
842            'aria-expanded': false,
843            'aria-label': $item.children('a:first').text()
844          });
845
846          $sub.addClass('submenu ' + subMenuClass).attr({
847            'data-submenu': '',
848            'aria-hidden': true,
849            'role': 'menu'
850          });
851        }
852
853        if ($item.parent('[data-submenu]').length) {
854          $item.addClass('is-submenu-item ' + subItemClass);
855        }
856      });
857
858      return;
859    },
860    Burn: function (menu, type) {
861      var items = menu.find('li').removeAttr('tabindex'),
862          subMenuClass = 'is-' + type + '-submenu',
863          subItemClass = subMenuClass + '-item',
864          hasSubClass = 'is-' + type + '-submenu-parent';
865
866      menu.find('*').removeClass(subMenuClass + ' ' + subItemClass + ' ' + hasSubClass + ' is-submenu-item submenu is-active').removeAttr('data-submenu').css('display', '');
867
868      // console.log(      menu.find('.' + subMenuClass + ', .' + subItemClass + ', .has-submenu, .is-submenu-item, .submenu, [data-submenu]')
869      //           .removeClass(subMenuClass + ' ' + subItemClass + ' has-submenu is-submenu-item submenu')
870      //           .removeAttr('data-submenu'));
871      // items.each(function(){
872      //   var $item = $(this),
873      //       $sub = $item.children('ul');
874      //   if($item.parent('[data-submenu]').length){
875      //     $item.removeClass('is-submenu-item ' + subItemClass);
876      //   }
877      //   if($sub.length){
878      //     $item.removeClass('has-submenu');
879      //     $sub.removeClass('submenu ' + subMenuClass).removeAttr('data-submenu');
880      //   }
881      // });
882    }
883  };
884
885  Foundation.Nest = Nest;
886}(jQuery);
887'use strict';
888
889!function ($) {
890
891  Foundation.Box = {
892    ImNotTouchingYou: ImNotTouchingYou,
893    GetDimensions: GetDimensions,
894    GetOffsets: GetOffsets
895  };
896
897  /**
898   * Compares the dimensions of an element to a container and determines collision events with container.
899   * @function
900   * @param {jQuery} element - jQuery object to test for collisions.
901   * @param {jQuery}
901 parent - jQuery object to use as bounding container.
902   * @param {Boolean} lrOnly - set to true to check left and right values only.
903   * @param {Boolean} tbOnly - set to true to check top and bottom values only.
904   * @default if no parent object passed, detects collisions with `window`.
905   * @returns {Boolean} - true if collision free, false if a collision in any direction.
906   */
907  function ImNotTouchingYou(element, parent, lrOnly, tbOnly) {
908    var eleDims = GetDimensions(element),
909        top,
910        bottom,
911        left,
912        right;
913
914    if (parent) {
915      var parDims = GetDimensions(parent);
916
917      bottom = eleDims.offset.top + eleDims.height <= parDims.height + parDims.offset.top;
918      top = eleDims.offset.top >= parDims.offset.top;
919      left = eleDims.offset.left >= parDims.offset.left;
920      right = eleDims.offset.left + eleDims.width <= parDims.width;
921    } else {
922      bottom = eleDims.offset.top + eleDims.height <= eleDims.windowDims.height + eleDims.windowDims.offset.top;
923      top = eleDims.offset.top >= eleDims.windowDims.offset.top;
924      left = eleDims.offset.left >= eleDims.windowDims.offset.left;
925      right = eleDims.offset.left + eleDims.width <= eleDims.windowDims.width;
926    }
927
928    var allDirs = [bottom, top, left, right];
929
930    if (lrOnly) {
931      return left === right === true;
932    }
933
934    if (tbOnly) {
935      return top === bottom === true;
936    }
937
938    return allDirs.indexOf(false) === -1;
939  };
940
941  /**
942   * Uses native methods to return an object of dimension values.
943   * @function
944   * @param {jQuery || HTML} element - jQuery object or DOM element for which to get the dimensions. Can be any element other that document or window.
945   * @returns {Object} - nested object of integer pixel values
946   * TODO - if element is window, return only those values.
947   */
948  function GetDimensions(elem, test) {
949    elem = elem.length ? elem[0] : elem;
950
951    if (elem === window || elem === document) {
952      throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");
953    }
954
955    var rect = elem.getBoundingClientRect(),
956        parRect = elem.parentNode.getBoundingClientRect(),
957        winRect = document.body.getBoundingClientRect(),
958        winY = window.pageYOffset,
959        winX = window.pageXOffset;
960
961    return {
962      width: rect.width,
963      height: rect.height,
964      offset: {
965        top: rect.top + winY,
966        left: rect.left + winX
967      },
968      parentDims: {
969        width: parRect.width,
970        height: parRect.height,
971        offset: {
972          top: parRect.top + winY,
973          left: parRect.left + winX
974        }
975      },
976      windowDims: {
977        width: winRect.width,
978        height: winRect.height,
979        offset: {
980          top: winY,
981          left: winX
982        }
983      }
984    };
985  }
986
987  /**
988   * Returns an object of top and left integer pixel values for dynamically rendered elements,
989   * such as: Tooltip, Reveal, and Dropdown
990   * @function
991   * @param {jQuery} element - jQuery object for the element being positioned.
992   * @param {jQuery} anchor - jQuery object for the element's anchor point.
993   * @param {String} position - a string relating to the desired position of the element, relative to it's anchor
994   * @param {Number} vOffset - integer pixel value of desired vertical separation between anchor and element.
995   * @param {Number} hOffset - integer pixel value of desired horizontal separation between anchor and element.
996   * @param {Boolean} isOverflow - if a collision event is detected, sets to true to default the element to full width - any desired offset.
997   * TODO alter/rewrite to work with `em` values as well/instead of pixels
998   */
999  function GetOffsets(element, anchor, position, vOffset, hOffset, isOverflow) {
1000    var $eleDims = GetDimensions(element),
1001        $anchorDims = anchor ? GetDimensions(anchor) : null;
1002
1003    switch (position) {
1004      case 'top':
1005        return {
1006          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
1007          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
1008        };
1009        break;
1010      case 'left':
1011        return {
1012          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
1013          top: $anchorDims.offset.top
1014        };
1015        break;
1016      case 'right':
1017        return {
1018          left: $anchorDims.offset.left + $anchorDims.width + hOffset,
1019          top: $anchorDims.offset.top
1020        };
1021        break;
1022      case 'center top':
1023        return {
1024          left: $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
1025          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
1026        };
1027        break;
1028      case 'center bottom':
1029        return {
1030          left: isOverflow ? hOffset : $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
1031          top: $anchorDims.offset.top + $anchorDims.height + vOffset
1032        };
1033        break;
1034      case 'center left':
1035        return {
1036          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
1037          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
1038        };
1039        break;
1040      case 'center right':
1041        return {
1042          left: $anchorDims.offset.left + $anchorDims.width + hOffset + 1,
1043          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
1044        };
1045        break;
1046      case 'center':
1047        return {
1048          left: $eleDims.windowDims.offset.left + $eleDims.windowDims.width / 2 - $eleDims.width / 2,
1049          top: $eleDims.windowDims.offset.top + $eleDims.windowDims.height / 2 - $eleDims.height / 2
1050        };
1051        break;
1052      case 'reveal':
1053        return {
1054          left: ($eleDims.windowDims.width - $eleDims.width) / 2,
1055          top: $eleDims.windowDims.offset.top + vOffset
1056        };
1057      case 'reveal full':
1058        return {
1059          left: $eleDims.windowDims.offset.left,
1060          top: $eleDims.windowDims.offset.top
1061        };
1062        break;
1063      case 'left bottom':
1064        return {
1065          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
1066          top: $anchorDims.offset.top + $anchorDims.height
1067        };
1068        break;
1069      case 'right bottom':
1070        return {
1071          left: $anchorDims.offset.left + $anchorDims.width + hOffset - $eleDims.width,
1072          top: $anchorDims.offset.top + $anchorDims.height
1073        };
1074        break;
1075      default:
1076        return {
1077          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
1078          top: $anchorDims.offset.top + $anchorDims.height + vOffset
1079        };
1080    }
1081  }
1082}(jQuery);
1083'use strict';
1084
1085!function ($) {
1086
1087  var MutationObserver = function () {
1088    var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
1089    for (var i = 0; i < prefixes.length; i++) {
1090      if (prefixes[i] + 'MutationObserver' in window) {
1091        return window[prefixes[i] + 'MutationObserver'];
1092      }
1093    }
1094    return false;
1095  }();
1096
1097  var triggers = function (el, type) {
1098    el.data(type).split(' ').forEach(function (id) {
1099      $('#' + id)[type === 'close' ? 'trigger' : 'triggerHandler'](type + '.zf.trigger', [el]);
1100    });
1101  };
1102  // Elements with [data-open] will reveal a plugin that supports it when clicked.
1103  $(document).on('click.zf.trigger', '[data-open]', function () {
1104    triggers($(this), 'open');
1105  });
1106
1107  // Elements with [data-close] will close a plugin that supports it when clicked.
1108  // If used without a value on [data-close], the event will bubble, allowing it to close a parent component.
1109  $(document).on('click.zf.trigger', '[data-close]', function () {
1110    var id = $(this).data('close');
1111    if (id) {
1112      triggers($(this), 'close');
1113    } else {
1114      $(this).trigger('close.zf.trigger');
1115    }
1116  });
1117
1118  // Elements with [data-toggle] will toggle a plugin that supports it when clicked.
1119  $(document).on('click.zf.trigger', '[data-toggle]', function () {
1120    triggers($(this), 'toggle');
1121  });
1122
1123  // Elements with [data-closable] will respond to close.zf.trigger events.
1124  $(document).on('close.zf.trigger', '[data-closable]', function (e) {
1125    e.stopPropagation();
1126    var animation = $(this).data('closable');
1127
1128    if (animation !== '') {
1129      Foundation.Motion.animateOut($(this), animation, function () {
1130        $(this).trigger('closed.zf');
1131      });
1132    } else {
1133      $(this).fadeOut().trigger('closed.zf');
1134    }
1135  });
1136
1137  $(document).on('focus.zf.trigger blur.zf.trigger', '[data-toggle-focus]', function () {
1138    var id = $(this).data('toggle-focus');
1139    $('#' + id).triggerHandler('toggle.zf.trigger', [$(this)]);
1140  });
1141
1142  /**
1143  * Fires once after all other scripts have loaded
1144  * @function
1145  * @private
1146  */
1147  $(window).load(function () {
1148    checkListeners();
1149  });
1150
1151  function checkListeners() {
1152    eventsListener();
1153    resizeListener();
1154    scrollListener();
1155    closemeListener();
1156  }
1157
1158  //******** only fires this function once on load, if there's something to watch ********
1159  function closemeListener(pluginName) {
1160    var yetiBoxes = $('[data-yeti-box]'),
1161        plugNames = ['dropdown', 'tooltip', 'reveal'];
1162
1163    if (pluginName) {
1164      if (typeof pluginName === 'string') {
1165        plugNames.push(pluginName);
1166      } else if (typeof pluginName === 'object' && typeof pluginName[0] === 'string') {
1167        plugNames.concat(pluginName);
1168      } else {
1169        console.error('Plugin names must be strings');
1170      }
1171    }
1172    if (yetiBoxes.length) {
1173      var listeners = plugNames.map(function (name) {
1174        return 'closeme.zf.' + name;
1175      }).join(' ');
1176
1177      $(window).off(listeners).on(listeners, function (e, pluginId) {
1178        var plugin = e.namespace.split('.')[0];
1179        var plugins = $('[data-' + plugin + ']').not('[data-yeti-box="' + pluginId + '"]');
1180
1181        plugins.each(function () {
1182          var _this = $(this);
1183
1184          _this.triggerHandler('close.zf.trigger', [_this]);
1185        });
1186      });
1187    }
1188  }
1189
1190  function resizeListener(debounce) {
1191    var timer = void 0,
1192        $nodes = $('[data-resize]');
1193    if ($nodes.length) {
1194      $(window).off('resize.zf.trigger').on('resize.zf.trigger', function (e) {
1195        if (timer) {
1196          clearTimeout(timer);
1197        }
1198
1199        timer = setTimeout(function () {
1200
1201          if (!MutationObserver) {
1202            //fallback for IE 9
1203            $nodes.each(function () {
1204              $(this).triggerHandler('resizeme.zf.trigger');
1205            });
1206          }
1207          //trigger all listening elements and signal a resize event
1208          $nodes.attr('data-events', "resize");
1209        }, debounce || 10); //default time to emit resize event
1210      });
1211    }
1212  }
1213
1214  function scrollListener(debounce) {
1215    var timer = void 0,
1216        $nodes = $('[data-scroll]');
1217    if ($nodes.length) {
1218      $(window).off('scroll.zf.trigger').on('scroll.zf.trigger', function (e) {
1219        if (timer) {
1220          clearTimeout(timer);
1221        }
1222
1223        timer = setTimeout(function () {
1224
1225          if (!MutationObserver) {
1226            //fallback for IE 9
1227            $nodes.each(function () {
1228              $(this).triggerHandler('scrollme.zf.trigger');
1229            });
1230          }
1231          //trigger all listening elements and signal a scroll event
1232          $nodes.attr('data-events', "scroll");
1233        }, debounce || 10); //default time to emit scroll event
1234      });
1235    }
1236  }
1237
1238  function eventsListener() {
1239    if (!MutationObserver) {
1240      return false;
1241    }
1242    var nodes = document.querySelectorAll('[data-resize], [data-scroll], [data-mutate]');
1243
1244    //element callback
1245    var listeningElementsMutation = function (mutationRecordsList) {
1246      var $target = $(mutationRecordsList[0].target);
1247      //trigger the event handler for the element depending on type
1248      switch ($target.attr("data-events")) {
1249
1250        case "resize":
1251          $target.triggerHandler('resizeme.zf.trigger', [$target]);
1252          break;
1253
1254        case "scroll":
1255          $target.triggerHandler('scrollme.zf.trigger', [$target, window.pageYOffset]);
1256          break;
1257
1258        // case "mutate" :
1259        // console.log('mutate', $target);
1260        // $target.triggerHandler('mutate.zf.trigger');
1261        //
1262        // //make sure we don't get stuck in an infinite loop from sloppy codeing
1263        // if ($target.index('[data-mutate]') == $("[data-mutate]").length-1) {
1264        //   domMutationObserver();
1265        // }
1266        // break;
1267
1268        default:
1269          return false;
1270        //nothing
1271      }
1272    };
1273
1274    if (nodes.length) {
1275      //for each element that needs to listen for resizing, scrolling, (or coming soon mutation) add a single observer
1276      for (var i = 0; i <= nodes.length - 1; i++) {
1277        var elementObserver = new MutationObserver(listeningElementsMutation);
1278        elementObserver.observe(nodes[i], { attributes: true, childList: false, characterData: false, subtree: false, attributeFilter: ["data-events"] });
1279      }
1280    }
1281  }
1282
1283  // ------------------------------------
1284
1285  // [PH]
1286  // Foundation.CheckWatchers = checkWatchers;
1287  Foundation.IHearYou = checkListeners;
1288  // Foundation.ISeeYou = scrollListener;
1289  // Foundation.IFeelYou = closemeListener;
1290}(jQuery);
1291
1292// function domMutationObserver(debounce) {
1293//   // !!! This is coming soon and needs more work; not active  !!! //
1294//   var timer,
1295//   nodes = document.querySelectorAll('[data-mutate]');
1296//   //
1297//   if (nodes.length) {
1298//     // var MutationObserver = (function () {
1299//     //   var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
1300//     //   for (var i=0; i < prefixes.length; i++) {
1301//     //     if (prefixes[i] + 'MutationObserver' in window) {
1302//     //       return window[prefixes[i] + 'MutationObserver'];
1303//     //     }
1304//     //   }
1305//     //   return false;
1306//     // }());
1307//
1308//
1309//     //for the body, we need to listen for all changes effecting the style and class attributes
1310//     var bodyObserver = new MutationObserver(bodyMutation);
1311//     bodyObserver.observe(document.body, { attributes: true, childList: true, characterData: false, subtree:true, attributeFilter:["style", "class"]});
1312//
1313//
1314//     //body callback
1315//     function bodyMutation(mutate) {
1316//       //trigger all listening elements and signal a mutation event
1317//       if (timer) { clearTimeout(timer); }
1318//
1319//       timer = setTimeout(function() {
1320//         bodyObserver.disconnect();
1321//         $('[data-mutate]').attr('data-events',"mutate");
1322//       }, debounce || 150);
1323//     }
1324//   }
1325// }
1326'use strict';
1327
1328var _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; }; }();
1329
1330function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1331
1332!function ($) {
1333
1334  /**
1335   * Drilldown module.
1336   * @module foundation.drilldown
1337   * @requires foundation.util.keyboard
1338   * @requires foundation.util.motion
1339   * @requires foundation.util.nest
1340   */
1341
1342  var Drilldown = function () {
1343    /**
1344     * Creates a new instance of a drilldown menu.
1345     * @class
1346     * @param {jQuery} element - jQuery object to make into an accordion menu.
1347     * @param {Object} options - Overrides to the default plugin settings.
1348     */
1349
1350    function Drilldown(element, options) {
1351      _classCallCheck(this, Drilldown);
1352
1353      this.$element = element;
1354      this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);
1355
1356      Foundation.Nest.Feather(this.$element, 'drilldown');
1357
1358      this._init();
1359
1360      Foundation.registerPlugin(this, 'Drilldown');
1361      Foundation.Keyboard.register('Drilldown', {
1362        'ENTER': 'open',
1363        'SPACE': 'open',
1364        'ARROW_RIGHT': 'next',
1365        'ARROW_UP': 'up',
1366        'ARROW_DOWN': 'down',
1367        'ARROW_LEFT': 'previous',
1368        'ESCAPE': 'close',
1369        'TAB': 'down',
1370        'SHIFT_TAB': 'up'
1371      });
1372    }
1373
1374    /**
1375     * Initializes the drilldown by creating jQuery collections of elements
1376     * @private
1377     */
1378
1379
1380    _createClass(Drilldown, [{
1381      key: '_init',
1382      value: function _init() {
1383        this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
1384        this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]');
1385        this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem').find('a');
1386
1387        this._prepareMenu();
1388
1389        this._keyboardEvents();
1390      }
1391
1392      /**
1393       * prepares drilldown menu by setting attributes to links and elements
1394       * sets a min height to prevent content jumping
1395       * wraps the element if not already wrapped
1396       * @private
1397       * @function
1398       */
1399
1400    }, {
1401      key: '_prepareMenu',
1402      value: function _prepareMenu() {
1403        var _this = this;
1404        // if(!this.options.holdOpen){
1405        //   this._menuLinkEvents();
1406        // }
1407        this.$submenuAnchors.each(function () {
1408          var $sub = $(this);
1409          var $link = $sub.find('a:first');
1410          if (_this.options.parentLink) {
1411            $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>');
1412          }
1413          $link.data('savedHref', $link.attr('href')).removeAttr('href');
1414          $sub.children('[data-submenu]').attr({
1415            'aria-hidden': true,
1416            'tabindex': 0,
1417            'role': 'menu'
1418          });
1419          _this._events($sub);
1420        });
1421        this.$submenus.each(function () {
1422          var $menu = $(this),
1423              $back = $menu.find('.js-drilldown-back');
1424          if (!$back.length) {
1425            $menu.prepend(_this.options.backButton);
1426          }
1427          _this._back($menu);
1428        });
1429        if (!this.$element.parent().hasClass('is-drilldown')) {
1430          this.$wrapper = $(this.options.wrapper).addClass('is-drilldown').css(this._getMaxDims());
1431          this.$element.wrap(this.$wrapper);
1432        }
1433      }
1434
1435      /**
1436       * Adds event handlers to elements in the menu.
1437       * @function
1438       * @private
1439       * @param {jQuery} $elem - the current menu item to add handlers to.
1440       */
1441
1442    }, {
1443      key: '_events',
1444      value: function _events($elem) {
1445        var _this = this;
1446
1447        $elem.off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
1448          if ($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')) {
1449            e.stopImmediatePropagation();
1450            e.preventDefault();
1451          }
1452
1453          // if(e.target !== e.currentTarget.firstElementChild){
1454          //   return false;
1455          // }
1456          _this._show($elem.parent('li'));
1457
1458          if (_this.options.closeOnClick) {
1459            var $body = $('body').not(_this.$wrapper);
1460            $body.off('.zf.drilldown').on('click.zf.drilldown', function (e) {
1461              e.preventDefault();
1462              _this._hideAll();
1463              $body.off('.zf.drilldown');
1464            });
1465          }
1466        });
1467      }
1468
1469      /**
1470       * Adds keydown event listener to `li`'s in the menu.
1471       * @private
1472       */
1473
1474    }, {
1475      key: '_keyboardEvents',
1476      value: function _keyboardEvents() {
1477        var _this = this;
1478
1479        this.$menuItems.add(this.$element.find('.js-drilldown-back > a')).on('keydown.zf.drilldown', function (e) {
1480
1481          var $element = $(this),
1482              $elements = $element.parent('li').parent('ul').children('li').children('a'),
1483              $prevElement,
1484              $nextElement;
1485
1486          $elements.each(function (i) {
1487            if ($(this).is($element)) {
1488              $prevElement = $elements.eq(Math.max(0, i - 1));
1489              $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1));
1490              return;
1491            }
1492          });
1493
1494          Foundation.Keyboard.handleKey(e, 'Drilldown', {
1495            next: function () {
1496              if ($element.is(_this.$submenuAnchors)) {
1497                _this._show($element.parent('li'));
1498                $element.parent('li').one(Foundation.transitionend($element), function () {
1499                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
1500                });
1501                e.preventDefault();
1502              }
1503            },
1504            previous: function () {
1505              _this._hide($element.parent('li').parent('ul'));
1506              $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
1507                setTimeout(function () {
1508                  $element.parent('li').parent('ul').parent('li').children('a').first().focus();
1509                }, 1);
1510              });
1511              e.preventDefault();
1512            },
1513            up: function () {
1514              $prevElement.focus();
1515              e.preventDefault();
1516            },
1517            down: function () {
1518              $nextElement.focus();
1519              e.preventDefault();
1520            },
1521            close: function () {
1522              _this._back();
1523              //_this.$menuItems.first().focus(); // focus to first element
1524            },
1525            open: function () {
1526              if (!$element.is(_this.$menuItems)) {
1527                // not menu item means back button
1528                _this._hide($element.parent('li').parent('ul'));
1529                $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
1530                  setTimeout(function () {
1531                    $element.parent('li').parent('ul').parent('li').children('a').first().focus();
1532                  }, 1);
1533                });
1534                e.preventDefault();
1535              } else if ($element.is(_this.$submenuAnchors)) {
1536                _this._show($element.parent('li'));
1537                $element.parent('li').one(Foundation.transitionend($element), function () {
1538                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
1539                });
1540                e.preventDefault();
1541              }
1542            },
1543            handled: function () {
1544              e.stopImmediatePropagation();
1545            }
1546          });
1547        }); // end keyboardAccess
1548      }
1549
1550      /**
1551       * Closes all open elements, and returns to root menu.
1552       * @function
1553       * @fires Drilldown#closed
1554       */
1555
1556    }, {
1557      key: '_hideAll',
1558      value: function _hideAll() {
1559        var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing');
1560        $elem.one(Foundation.transitionend($elem), function (e) {
1561          $elem.removeClass('is-active is-closing');
1562        });
1563        /**
1564         * Fires when the menu is fully closed.
1565         * @event Drilldown#closed
1566         */
1567        this.$element.trigger('closed.zf.drilldown');
1568      }
1569
1570      /**
1571       * Adds event listener for each `back` button, and closes open menus.
1572       * @function
1573       * @fires Drilldown#back
1574       * @param {jQuery} $elem - the current sub-menu to add `back` event.
1575       */
1576
1577    }, {
1578      key: '_back',
1579      value: function _back($elem) {
1580        var _this = this;
1581        $elem.off('click.zf.drilldown');
1582        $elem.children('.js-drilldown-back').on('click.zf.drilldown', function (e) {
1583          e.stopImmediatePropagation();
1584          // console.log('mouseup on back');
1585          _this._hide($elem);
1586        });
1587      }
1588
1589      /**
1590       * Adds event listener to menu items w/o submenus to close open menus on click.
1591       * @function
1592       * @private
1593       */
1594
1595    }, {
1596      key: '_menuLinkEvents',
1597      value: function _menuLinkEvents() {
1598        var _this = this;
1599        this.$menuItems.not('.is-drilldown-submenu-parent').off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
1600          // e.stopImmediatePropagation();
1601          setTimeout(function () {
1602            _this._hideAll();
1603          }, 0);
1604        });
1605      }
1606
1607      /**
1608       * Opens a submenu.
1609       * @function
1610       * @fires Drilldown#open
1611       * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
1612       */
1613
1614    }, {
1615      key: '_show',
1616      value: function _show($elem) {
1617        $elem.children('[data-submenu]').addClass('is-active');
1618
1619        this.$element.trigger('open.zf.drilldown', [$elem]);
1620      }
1621    }, {
1622      key: '_hide',
1623
1624
1625      /**
1626       * Hides a submenu
1627       * @function
1628       * @fires Drilldown#hide
1629       * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
1630       */
1631      value: function _hide($elem) {
1632        var _this = this;
1633        $elem.addClass('is-closing').one(Foundation.transitionend($elem), function () {
1634          $elem.removeClass('is-active is-closing');
1635          $elem.blur();
1636        });
1637        /**
1638         * Fires when the submenu is has closed.
1639         * @event Drilldown#hide
1640         */
1641        $elem.trigger('hide.zf.drilldown', [$elem]);
1642      }
1643
1644      /**
1645       * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
1646       * Prevents content jumping.
1647       * @function
1648       * @private
1649       */
1650
1651    }, {
1652      key: '_getMaxDims',
1653      value: function _getMaxDims() {
1654        var max = 0,
1655            result = {};
1656        this.$submenus.add(this.$element).each(function () {
1657          var numOfElems = $(this).children('li').length;
1658          max = numOfElems > max ? numOfElems : max;
1659        });
1660
1661        result['min-height'] = max * this.$menuItems[0].getBoundingClientRect().height + 'px';
1662        result['max-width'] = this.$element[0].getBoundingClientRect().width + 'px';
1663
1664        return result;
1665      }
1666
1667      /**
1668       * Destroys the Drilldown Menu
1669       * @function
1670       */
1671
1672    }, {
1673      key: 'destroy',
1674      value: function destroy() {
1675        this._hideAll();
1676        Foundation.Nest.Burn(this.$element, 'drilldown');
1677        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').off('.zf.drilldown').end().off('zf.drilldown');
1678        this.$element.find('a').each(function () {
1679          var $link = $(this);
1680          if ($link.data('savedHref')) {
1681            $link.attr('href', $link.data('savedHref')).removeData('savedHref');
1682          } else {
1683            return;
1684          }
1685        });
1686        Foundation.unregisterPlugin(this);
1687      }
1688    }]);
1689
1690    return Drilldown;
1691  }();
1692
1693  Drilldown.defaults = {
1694    /**
1695     * 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.
1696     * @option
1697     * @example '<\li><\a>Back<\/a><\/li>'
1698     */
1699    backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
1700    /**
1701     * 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.
1702     * @option
1703     * @example '<\div class="is-drilldown"><\/div>'
1704     */
1705    wrapper: '<div></div>',
1706    /**
1707     * Adds the parent link to the submenu.
1708     * @option
1709     * @example false
1710     */
1711    parentLink: false,
1712    /**
1713     * Allow the menu to return to root list on body click.
1714     * @option
1715     * @example false
1716     */
1717    closeOnClick: false
1718    // holdOpen: false
1719  };
1720
1721  // Window exports
1722  Foundation.plugin(Drilldown, 'Drilldown');
1723}(jQuery);
1724'use strict';
1725
1726var _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; }; }();
1727
1728function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1729
1730!function ($) {
1731
1732  /**
1733   * DropdownMenu module.
1734   * @module foundation.dropdown-menu
1735   * @requires foundation.util.keyboard
1736   * @requires foundation.util.box
1737   * @requires foundation.util.nest
1738   */
1739
1740  var DropdownMenu = function () {
1741    /**
1742     * Creates a new instance of DropdownMenu.
1743     * @class
1744     * @fires DropdownMenu#init
1745     * @param {jQuery} element - jQuery object to make into a dropdown menu.
1746     * @param {Object} options - Overrides to the default plugin settings.
1747     */
1748
1749    function DropdownMenu(element, options) {
1750      _classCallCheck(this, DropdownMenu);
1751
1752      this.$element = element;
1753      this.options = $.extend({}, DropdownMenu.defaults, this.$element.data(), options);
1754
1755      Foundation.Nest.Feather(this.$element, 'dropdown');
1756      this._init();
1757
1758      Foundation.registerPlugin(this, 'DropdownMenu');
1759      Foundation.Keyboard.register('DropdownMenu', {
1760        'ENTER': 'open',
1761        'SPACE': 'open',
1762        'ARROW_RIGHT': 'next',
1763        'ARROW_UP': 'up',
1764        'ARROW_DOWN': 'down',
1765        'ARROW_LEFT': 'previous',
1766        'ESCAPE': 'close'
1767      });
1768    }
1769
1770    /**
1771     * Initializes the plugin, and calls _prepareMenu
1772     * @private
1773     * @function
1774     */
1775
1776
1777    _createClass(DropdownMenu, [{
1778      key: '_init',
1779      value: function _init() {
1780        var subs = this.$element.find('li.is-dropdown-submenu-parent');
1781        this.$element.children('.is-dropdown-submenu-parent').children('.is-dropdown-submenu').addClass('first-sub');
1782
1783        this.$menuItems = this.$element.find('[role="menuitem"]');
1784        this.$tabs = this.$element.children('[role="menuitem"]');
1785        this.$tabs.find('ul.is-dropdown-submenu').addClass(this.options.verticalClass);
1786
1787        if (this.$element.hasClass(this.options.rightClass) || this.options.alignment === 'right' || Foundation.rtl() || this.$element.parents('.top-bar-right').is('*')) {
1788          this.options.alignment = 'right';
1789          subs.addClass('opens-left');
1790        } else {
1791          subs.addClass('opens-right');
1792        }
1793        this.changed = false;
1794        this._events();
1795      }
1796    }, {
1797      key: '_events',
1798
1799      /**
1800       * Adds event listeners to elements within the menu
1801       * @private
1802       * @function
1803       */
1804      value: function _events() {
1805        var _this = this,
1806            hasTouch = 'ontouchstart' in window || typeof window.ontouchstart !== 'undefined',
1807            parClass = 'is-dropdown-submenu-parent';
1808
1809        if (this.options.clickOpen || hasTouch) {
1810          this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', function (e) {
1811            var $elem = $(e.target).parentsUntil('ul', '.' + parClass),
1812                hasSub = $elem.hasClass(parClass),
1813                hasClicked = $elem.attr('data-is-click') === 'true',
1814                $sub = $elem.children('.is-dropdown-submenu');
1815
1816            if (hasSub) {
1817              if (hasClicked) {
1818                if (!_this.options.closeOnClick || !_this.options.clickOpen && !hasTouch || _this.options.forceFollow && hasTouch) {
1819                  return;
1820                } else {
1821                  e.stopImmediatePropagation();
1822                  e.preventDefault();
1823                  _this._hide($elem);
1824                }
1825              } else {
1826                e.preventDefault();
1827                e.stopImmediatePropagation();
1828                _this._show($elem.children('.is-dropdown-submenu'));
1829                $elem.add($elem.parentsUntil(_this.$element, '.' + parClass)).attr('data-is-click', true);
1830              }
1831            } else {
1832              return;
1833            }
1834          });
1835        }
1836
1837        if (!this.options.disableHover) {
1838          this.$menuItems.on('mouseenter.zf.dropdownmenu', function (e) {
1839            e.stopImmediatePropagation();
1840            var $elem = $(this),
1841                hasSub = $elem.hasClass(parClass);
1842
1843            if (hasSub) {
1844              clearTimeout(_this.delay);
1845              _this.delay = setTimeout(function () {
1846                _this._show($elem.children('.is-dropdown-submenu'));
1847              }, _this.options.hoverDelay);
1848            }
1849          }).on('mouseleave.zf.dropdownmenu', function (e) {
1850            var $elem = $(this),
1851                hasSub = $elem.hasClass(parClass);
1852            if (hasSub && _this.options.autoclose) {
1853              if ($elem.attr('data-is-click') === 'true' && _this.options.clickOpen) {
1854                return false;
1855              }
1856
1857              clearTimeout(_this.delay);
1858              _this.delay = setTimeout(function () {
1859                _this._hide($elem);
1860              }, _this.options.closingTime);
1861            }
1862          });
1863        }
1864        this.$menuItems.on('keydown.zf.dropdownmenu', function (e) {
1865          var $element = $(e.target).parentsUntil('ul', '[role="menuitem"]'),
1866              isTab = _this.$tabs.index($element) > -1,
1867              $elements = isTab ? _this.$tabs : $element.siblings('li').add($element),
1868              $prevElement,
1869              $nextElement;
1870
1871          $elements.each(function (i) {
1872            if ($(this).is($element)) {
1873              $prevElement = $elements.eq(i - 1);
1874              $nextElement = $elements.eq(i + 1);
1875              return;
1876            }
1877          });
1878
1879          var nextSibling = function () {
1880            if (!$element.is(':last-child')) $nextElement.children('a:first').focus();
1881          },
1882              prevSibling = function () {
1883            $prevElement.children('a:first').focus();
1884          },
1885              openSub = function () {
1886            var $sub = $element.children('ul.is-dropdown-submenu');
1887            if ($sub.length) {
1888              _this._show($sub);
1889              $element.find('li > a:first').focus();
1890            } else {
1891              return;
1892            }
1893          },
1894              closeSub = function () {
1895            //if ($element.is(':first-child')) {
1896            var close = $element.parent('ul').parent('li');
1897            close.children('a:first').focus();
1898            _this._hide(close);
1899            //}
1900          };
1901          var functions = {
1902            open: openSub,
1903            close: function () {
1904              _this._hide(_this.$element);
1905              _this.$menuItems.find('a:first').focus(); // focus to first element
1906            },
1907            handled: function () {
1908              e.preventDefault();
1909              e.stopImmediatePropagation();
1910            }
1911          };
1912
1913          if (isTab) {
1914            if (_this.vertical) {
1915              // vertical menu
1916              if (_this.options.alignment === 'left') {
1917                // left aligned
1918                $.extend(functions, {
1919                  down: nextSibling,
1920                  up: prevSibling,
1921                  next: openSub,
1922                  previous: closeSub
1923                });
1924              } else {
1925                // right aligned
1926                $.extend(functions, {
1927                  down: nextSibling,
1928                  up: prevSibling,
1929                  next: closeSub,
1930                  previous: openSub
1931                });
1932              }
1933            } else {
1934              // horizontal menu
1935              $.extend(functions, {
1936                next: nextSibling,
1937                previous: prevSibling,
1938                down: openSub,
1939                up: closeSub
1940              });
1941            }
1942          } else {
1943            // not tabs -> one sub
1944            if (_this.options.alignment === 'left') {
1945              // left aligned
1946              $.extend(functions, {
1947                next: openSub,
1948                previous: closeSub,
1949                down: nextSibling,
1950                up: prevSibling
1951              });
1952            } else {
1953              // right aligned
1954              $.extend(functions, {
1955                next: closeSub,
1956                previous: openSub,
1957                down: nextSibling,
1958                up: prevSibling
1959              });
1960            }
1961          }
1962          Foundation.Keyboard.handleKey(e, 'DropdownMenu', functions);
1963        });
1964      }
1965
1966      /**
1967       * Adds an event handler to the body to close any dropdowns on a click.
1968       * @function
1969       * @private
1970       */
1971
1972    }, {
1973      key: '_addBodyHandler',
1974      value: function _addBodyHandler() {
1975        var $body = $(document.body),
1976            _this = this;
1977        $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu').on('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu', function (e) {
1978          var $link = _this.$element.find(e.target);
1979          if ($link.length) {
1980            return;
1981          }
1982
1983          _this._hide();
1984          $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu');
1985        });
1986      }
1987
1988      /**
1989       * Opens a dropdown pane, and checks for collisions first.
1990       * @param {jQuery} $sub - ul element that is a submenu to show
1991       * @function
1992       * @private
1993       * @fires DropdownMenu#show
1994       */
1995
1996    }, {
1997      key: '_show',
1998      value: function _show($sub) {
1999        var idx = this.$tabs.index(this.$tabs.filter(function (i, el) {
2000          return $(el).find($sub).length > 0;
2001        }));
2002        var $sibs = $sub.parent('li.is-dropdown-submenu-parent').siblings('li.is-dropdown-submenu-parent');
2003        this._hide($sibs, idx);
2004        $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 });
2005        var clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
2006        if (!clear) {
2007          var oldClass = this.options.alignment === 'left' ? '-right' : '-left',
2008              $parentLi = $sub.parent('.is-dropdown-submenu-parent');
2009          $parentLi.removeClass('opens' + oldClass).addClass('opens-' + this.options.alignment);
2010          clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
2011          if (!clear) {
2012            $parentLi.removeClass('opens-' + this.options.alignment).addClass('opens-inner');
2013          }
2014          this.changed = true;
2015        }
2016        $sub.css('visibility', '');
2017        if (this.options.closeOnClick) {
2018          this._addBodyHandler();
2019        }
2020        /**
2021         * Fires when the new dropdown pane is visible.
2022         * @event DropdownMenu#show
2023         */
2024        this.$element.trigger('show.zf.dropdownmenu', [$sub]);
2025      }
2026
2027      /**
2028       * Hides a single, currently open dropdown pane, if passed a parameter, otherwise, hides everything.
2029       * @function
2030       * @param {jQuery} $elem - element with a submenu to hide
2031       * @param {Number} idx - index of the $tabs collection to hide
2032       * @private
2033       */
2034
2035    }, {
2036      key: '_hide',
2037      value: function _hide($elem, idx) {
2038        var $toClose;
2039        if ($elem && $elem.length) {
2040          $toClose = $elem;
2041        } else if (idx !== undefined) {
2042          $toClose = this.$tabs.not(function (i, el) {
2043            return i === idx;
2044          });
2045        } else {
2046          $toClose = this.$element;
2047        }
2048        var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0;
2049
2050        if (somethingToClose) {
2051          $toClose.find('li.is-active').add($toClose).attr({
2052            'aria-expanded': false,
2053            'data-is-click': false
2054          }).removeClass('is-active');
2055
2056          $toClose.find('ul.js-dropdown-active').attr({
2057            'aria-hidden': true
2058          }).removeClass('js-dropdown-active');
2059
2060          if (this.changed || $toClose.find('opens-inner').length) {
2061            var oldClass = this.options.alignment === 'left' ? 'right' : 'left';
2062            $toClose.find('li.is-dropdown-submenu-parent').add($toClose).removeClass('opens-inner opens-' + this.options.alignment).addClass('opens-' + oldClass);
2063            this.changed = false;
2064          }
2065          /**
2066           * Fires when the open menus are closed.
2067           * @event DropdownMenu#hide
2068           */
2069
2070          // TODO: this is a hack.
2071          // There is a bigger issue in that the correct trigger doees not work
2072          // correctly, and it is unclear as to why.
2073          // this.$element.trigger('hide.zf.dropdownmenu', [$toClose]);
2074          this.$element.trigger('notifications.hide', [$toClose]);
2075        }
2076      }
2077
2078      /**
2079       * Destroys the plugin.
2080       * @function
2081       */
2082
2083    }, {
2084      key: 'destroy',
2085      value: function destroy() {
2086        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');
2087        $(document.body).off('.zf.dropdownmenu');
2088        Foundation.Nest.Burn(this.$element, 'dropdown');
2089        Foundation.unregisterPlugin(this);
2090      }
2091    }]);
2092
2093    return DropdownMenu;
2094  }();
2095
2096  /**
2097   * Default settings for plugin
2098   */
2099
2100
2101  DropdownMenu.defaults = {
2102    /**
2103     * Disallows hover events from opening submenus
2104     * @option
2105     * @example false
2106     */
2107    disableHover: false,
2108    /**
2109     * Allow a submenu to automatically close on a mouseleave event, if not clicked open.
2110     * @option
2111     * @example true
2112     */
2113    autoclose: true,
2114    /**
2115     * Amount of time to delay opening a submenu on hover event.
2116     * @option
2117     * @example 50
2118     */
2119    hoverDelay: 50,
2120    /**
2121     * Allow a submenu to open/remain open on parent click event. Allows cursor to move away from menu.
2122     * @option
2123     * @example true
2124     */
2125    clickOpen: false,
2126    /**
2127     * Amount of time to delay closing a submenu on a mouseleave event.
2128     * @option
2129     * @example 500
2130     */
2131
2132    closingTime: 500,
2133    /**
2134     * Position of the menu relative to what direction the submenus should open. Handled by JS.
2135     * @option
2136     * @example 'left'
2137     */
2138    alignment: 'left',
2139    /**
2140     * Allow clicks on the body to close any open submenus.
2141     * @option
2142     * @example true
2143     */
2144    closeOnClick: true,
2145    /**
2146     * Class applied to vertical oriented menus, Foundation default is `vertical`. Update this if using your own class.
2147     * @option
2148     * @example 'vertical'
2149     */
2150    verticalClass: 'vertical',
2151    /**
2152     * Class applied to right-side oriented menus, Foundation default is `align-right`. Update this if using your own class.
2153     * @option
2154     * @example 'align-right'
2155     */
2156    rightClass: 'align-right',
2157    /**
2158     * Boolean to force overide the clicking of links to perform default action, on second touch event for mobile.
2159     * @option
2160     * @example false
2161     */
2162    forceFollow: true
2163  };
2164
2165  // Window exports
2166  Foundation.plugin(DropdownMenu, 'DropdownMenu');
2167}(jQuery);
2168'use strict';
2169
2170var _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; }; }();
2171
2172function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2173
2174!function ($) {
2175
2176  /**
2177   * ResponsiveMenu module.
2178   * @module foundation.responsiveMenu
2179   * @requires foundation.util.triggers
2180   * @requires foundation.util.mediaQuery
2181   * @requires foundation.util.accordionMenu
2182   * @requires foundation.util.drilldown
2183   * @requires foundation.util.dropdown-menu
2184   */
2185
2186  var ResponsiveMenu = function () {
2187    /**
2188     * Creates a new instance of a responsive menu.
2189     * @class
2190     * @fires ResponsiveMenu#init
2191     * @param {jQuery} element - jQuery object to make into a dropdown menu.
2192     * @param {Object} options - Overrides to the default plugin settings.
2193     */
2194
2195    function ResponsiveMenu(element, options) {
2196      _classCallCheck(this, ResponsiveMenu);
2197
2198      this.$element = $(element);
2199      this.rules = this.$element.data('responsive-menu');
2200      this.currentMq = null;
2201      this.currentPlugin = null;
2202
2203      this._init();
2204      this._events();
2205
2206      Foundation.registerPlugin(this, 'ResponsiveMenu');
2207    }
2208
2209    /**
2210     * Initializes the Menu by parsing the classes from the 'data-ResponsiveMenu' attribute on the element.
2211     * @function
2212     * @private
2213     */
2214
2215
2216    _createClass(ResponsiveMenu, [{
2217      key: '_init',
2218      value: function _init() {
2219        // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules
2220        if (typeof this.rules === 'string') {
2221          var rulesTree = {};
2222
2223          // Parse rules from "classes" pulled from data attribute
2224          var rules = this.rules.split(' ');
2225
2226          // Iterate through every rule found
2227          for (var i = 0; i < rules.length; i++) {
2228            var rule = rules[i].split('-');
2229            var ruleSize = rule.length > 1 ? rule[0] : 'small';
2230            var rulePlugin = rule.length > 1 ? rule[1] : rule[0];
2231
2232            if (MenuPlugins[rulePlugin] !== null) {
2233              rulesTree[ruleSize] = MenuPlugins[rulePlugin];
2234            }
2235          }
2236
2237          this.rules = rulesTree;
2238        }
2239
2240        if (!$.isEmptyObject(this.rules)) {
2241          this._checkMediaQueries();
2242        }
2243      }
2244
2245      /**
2246       * Initializes events for the Menu.
2247       * @function
2248       * @private
2249       */
2250
2251    }, {
2252      key: '_events',
2253      value: function _events() {
2254        var _this = this;
2255
2256        $(window).on('changed.zf.mediaquery', function () {
2257          _this._checkMediaQueries();
2258        });
2259        // $(window).on('resize.zf.ResponsiveMenu', function() {
2260        //   _this._checkMediaQueries();
2261        // });
2262      }
2263
2264      /**
2265       * 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.
2266       * @function
2267       * @private
2268       */
2269
2270    }, {
2271      key: '_checkMediaQueries',
2272      value: function _checkMediaQueries() {
2273        var matchedMq,
2274            _this = this;
2275        // Iterate through each rule and find the last matching rule
2276        $.each(this.rules, function (key) {
2277          if (Foundation.MediaQuery.atLeast(key)) {
2278            matchedMq = key;
2279          }
2280        });
2281
2282        // No match? No dice
2283        if (!matchedMq) return;
2284
2285        // Plugin already initialized? We good
2286        if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return;
2287
2288        // Remove existing plugin-specific CSS classes
2289        $.each(MenuPlugins, function (key, value) {
2290          _this.$element.removeClass(value.cssClass);
2291        });
2292
2293        // Add the CSS class for the new plugin
2294        this.$element.addClass(this.rules[matchedMq].cssClass);
2295
2296        // Create an instance of the new plugin
2297        if (this.currentPlugin) this.currentPlugin.destroy();
2298        this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {});
2299      }
2300
2301      /**
2302       * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out.
2303       * @function
2304       */
2305
2306    }, {
2307      key: 'destroy',
2308      value: function destroy() {
2309        this.currentPlugin.destroy();
2310        $(window).off('.zf.ResponsiveMenu');
2311        Foundation.unregisterPlugin(this);
2312      }
2313    }]);
2314
2315    return ResponsiveMenu;
2316  }();
2317
2318  ResponsiveMenu.defaults = {};
2319
2320  // The plugin matches the plugin classes with these plugin instances.
2321  var MenuPlugins = {
2322    dropdown: {
2323      cssClass: 'dropdown',
2324      plugin: Foundation._plugins['dropdown-menu'] || null
2325    },
2326    drilldown: {
2327      cssClass: 'drilldown',
2328      plugin: Foundation._plugins['drilldown'] || null
2329    },
2330    accordion: {
2331      cssClass: 'accordion-menu',
2332      plugin: Foundation._plugins['accordion-menu'] || null
2333    }
2334  };
2335
2336  // Window exports
2337  Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu');
2338}(jQuery);
2339'use strict';
2340
2341var _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; }; }();
2342
2343function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2344
2345!function ($) {
2346
2347  /**
2348   * Dropdown module.
2349   * @module foundation.dropdown
2350   * @requires foundation.util.keyboard
2351   * @requires foundation.util.box
2352   * @requires foundation.util.triggers
2353   */
2354
2355  var Dropdown = function () {
2356    /**
2357     * Creates a new instance of a dropdown.
2358     * @class
2359     * @param {jQuery} element - jQuery object to make into a dropdown.
2360     *        Object should be of the dropdown panel, rather than its anchor.
2361     * @param {Object} options - Overrides to the default plugin settings.
2362     */
2363
2364    function Dropdown(element, options) {
2365      _classCallCheck(this, Dropdown);
2366
2367      this.$element = element;
2368      this.options = $.extend({}, Dropdown.defaults, this.$element.data(), options);
2369      this._init();
2370
2371      Foundation.registerPlugin(this, 'Dropdown');
2372      Foundation.Keyboard.register('Dropdown', {
2373        'ENTER': 'open',
2374        'SPACE': 'open',
2375        'ESCAPE': 'close',
2376        'TAB': 'tab_forward',
2377        'SHIFT_TAB': 'tab_backward'
2378      });
2379    }
2380
2381    /**
2382     * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anch
2382or.
2383     * @function
2384     * @private
2385     */
2386
2387
2388    _createClass(Dropdown, [{
2389      key: '_init',
2390      value: function _init() {
2391        var $id = this.$element.attr('id');
2392
2393        this.$anchor = $('[data-toggle="' + $id + '"]') || $('[data-open="' + $id + '"]');
2394        this.$anchor.attr({
2395          'aria-controls': $id,
2396          'data-is-focus': false,
2397          'data-yeti-box': $id,
2398          'aria-haspopup': true,
2399          'aria-expanded': false
2400
2401        });
2402
2403        this.options.positionClass = this.getPositionClass();
2404        this.counter = 4;
2405        this.usedPositions = [];
2406        this.$element.attr({
2407          'aria-hidden': 'true',
2408          'data-yeti-box': $id,
2409          'data-resize': $id,
2410          'aria-labelledby': this.$anchor[0].id || Foundation.GetYoDigits(6, 'dd-anchor')
2411        });
2412        this._events();
2413      }
2414
2415      /**
2416       * Helper function to determine current orientation of dropdown pane.
2417       * @function
2418       * @returns {String} position - string value of a position class.
2419       */
2420
2421    }, {
2422      key: 'getPositionClass',
2423      value: function getPositionClass() {
2424        var verticalPosition = this.$element[0].className.match(/(top|left|right|bottom)/g);
2425        verticalPosition = verticalPosition ? verticalPosition[0] : '';
2426        var horizontalPosition = /float-(.+)\s/.exec(this.$anchor[0].className);
2427        horizontalPosition = horizontalPosition ? horizontalPosition[1] : '';
2428        var position = horizontalPosition ? horizontalPosition + ' ' + verticalPosition : verticalPosition;
2429        return position;
2430      }
2431
2432      /**
2433       * Adjusts the dropdown panes orientation by adding/removing positioning classes.
2434       * @function
2435       * @private
2436       * @param {String} position - position class to remove.
2437       */
2438
2439    }, {
2440      key: '_reposition',
2441      value: function _reposition(position) {
2442        this.usedPositions.push(position ? position : 'bottom');
2443        //default, try switching to opposite side
2444        if (!position && this.usedPositions.indexOf('top') < 0) {
2445          this.$element.addClass('top');
2446        } else if (position === 'top' && this.usedPositions.indexOf('bottom') < 0) {
2447          this.$element.removeClass(position);
2448        } else if (position === 'left' && this.usedPositions.indexOf('right') < 0) {
2449          this.$element.removeClass(position).addClass('right');
2450        } else if (position === 'right' && this.usedPositions.indexOf('left') < 0) {
2451          this.$element.removeClass(position).addClass('left');
2452        }
2453
2454        //if default change didn't work, try bottom or left first
2455        else if (!position && this.usedPositions.indexOf('top') > -1 && this.usedPositions.indexOf('left') < 0) {
2456            this.$element.addClass('left');
2457          } else if (position === 'top' && this.usedPositions.indexOf('bottom') > -1 && this.usedPositions.indexOf('left') < 0) {
2458            this.$element.removeClass(position).addClass('left');
2459          } else if (position === 'left' && this.usedPositions.indexOf('right') > -1 && this.usedPositions.indexOf('bottom') < 0) {
2460            this.$element.removeClass(position);
2461          } else if (position === 'right' && this.usedPositions.indexOf('left') > -1 && this.usedPositions.indexOf('bottom') < 0) {
2462            this.$element.removeClass(position);
2463          }
2464          //if nothing cleared, set to bottom
2465          else {
2466              this.$element.removeClass(position);
2467            }
2468        this.classChanged = true;
2469        this.counter--;
2470      }
2471
2472      /**
2473       * Sets the position and orientation of the dropdown pane, checks for collisions.
2474       * Recursively calls itself if a collision is detected, with a new position class.
2475       * @function
2476       * @private
2477       */
2478
2479    }, {
2480      key: '_setPosition',
2481      value: function _setPosition() {
2482        if (this.$anchor.attr('aria-expanded') === 'false') {
2483          return false;
2484        }
2485        var position = this.getPositionClass(),
2486            $eleDims = Foundation.Box.GetDimensions(this.$element),
2487            $anchorDims = Foundation.Box.GetDimensions(this.$anchor),
2488            _this = this,
2489            direction = position === 'left' ? 'left' : position === 'right' ? 'left' : 'top',
2490            param = direction === 'top' ? 'height' : 'width',
2491            offset = param === 'height' ? this.options.vOffset : this.options.hOffset;
2492
2493        if ($eleDims.width >= $eleDims.windowDims.width || !this.counter && !Foundation.Box.ImNotTouchingYou(this.$element)) {
2494          this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
2495            'width': $eleDims.windowDims.width - this.options.hOffset * 2,
2496            'height': 'auto'
2497          });
2498          this.classChanged = true;
2499          return false;
2500        }
2501
2502        this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, position, this.options.vOffset, this.options.hOffset));
2503
2504        while (!Foundation.Box.ImNotTouchingYou(this.$element, false, true) && this.counter) {
2505          this._reposition(position);
2506          this._setPosition();
2507        }
2508      }
2509
2510      /**
2511       * Adds event listeners to the element utilizing the triggers utility library.
2512       * @function
2513       * @private
2514       */
2515
2516    }, {
2517      key: '_events',
2518      value: function _events() {
2519        var _this = this;
2520        this.$element.on({
2521          'open.zf.trigger': this.open.bind(this),
2522          'close.zf.trigger': this.close.bind(this),
2523          'toggle.zf.trigger': this.toggle.bind(this),
2524          'resizeme.zf.trigger': this._setPosition.bind(this)
2525        });
2526
2527        if (this.options.hover) {
2528          this.$anchor.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () {
2529            clearTimeout(_this.timeout);
2530            _this.timeout = setTimeout(function () {
2531              _this.open();
2532              _this.$anchor.data('hover', true);
2533            }, _this.options.hoverDelay);
2534          }).on('mouseleave.zf.dropdown', function () {
2535            clearTimeout(_this.timeout);
2536            _this.timeout = setTimeout(function () {
2537              _this.close();
2538              _this.$anchor.data('hover', false);
2539            }, _this.options.hoverDelay);
2540          });
2541          if (this.options.hoverPane) {
2542            this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () {
2543              clearTimeout(_this.timeout);
2544            }).on('mouseleave.zf.dropdown', function () {
2545              clearTimeout(_this.timeout);
2546              _this.timeout = setTimeout(function () {
2547                _this.close();
2548                _this.$anchor.data('hover', false);
2549              }, _this.options.hoverDelay);
2550            });
2551          }
2552        }
2553        this.$anchor.add(this.$element).on('keydown.zf.dropdown', function (e) {
2554
2555          var $target = $(this),
2556              visibleFocusableElements = Foundation.Keyboard.findFocusable(_this.$element);
2557
2558          Foundation.Keyboard.handleKey(e, 'Dropdown', {
2559            tab_forward: function () {
2560              if (_this.$element.find(':focus').is(visibleFocusableElements.eq(-1))) {
2561                // left modal downwards, setting focus to first element
2562                if (_this.options.trapFocus) {
2563                  // if focus shall be trapped
2564                  visibleFocusableElements.eq(0).focus();
2565                  e.preventDefault();
2566                } else {
2567                  // if focus is not trapped, close dropdown on focus out
2568                  _this.close();
2569                }
2570              }
2571            },
2572            tab_backward: function () {
2573              if (_this.$element.find(':focus').is(visibleFocusableElements.eq(0)) || _this.$element.is(':focus')) {
2574                // left modal upwards, setting focus to last element
2575                if (_this.options.trapFocus) {
2576                  // if focus shall be trapped
2577                  visibleFocusableElements.eq(-1).focus();
2578                  e.preventDefault();
2579                } else {
2580                  // if focus is not trapped, close dropdown on focus out
2581                  _this.close();
2582                }
2583              }
2584            },
2585            open: function () {
2586              if ($target.is(_this.$anchor)) {
2587                _this.open();
2588                _this.$element.attr('tabindex', -1).focus();
2589                e.preventDefault();
2590              }
2591            },
2592            close: function () {
2593              _this.close();
2594              _this.$anchor.focus();
2595            }
2596          });
2597        });
2598      }
2599
2600      /**
2601       * Adds an event handler to the body to close any dropdowns on a click.
2602       * @function
2603       * @private
2604       */
2605
2606    }, {
2607      key: '_addBodyHandler',
2608      value: function _addBodyHandler() {
2609        var $body = $(document.body).not(this.$element),
2610            _this = this;
2611        $body.off('click.zf.dropdown').on('click.zf.dropdown', function (e) {
2612          if (_this.$anchor.is(e.target) || _this.$anchor.find(e.target).length) {
2613            return;
2614          }
2615          if (_this.$element.find(e.target).length) {
2616            return;
2617          }
2618          _this.close();
2619          $body.off('click.zf.dropdown');
2620        });
2621      }
2622
2623      /**
2624       * Opens the dropdown pane, and fires a bubbling event to close other dropdowns.
2625       * @function
2626       * @fires Dropdown#closeme
2627       * @fires Dropdown#show
2628       */
2629
2630    }, {
2631      key: 'open',
2632      value: function open() {
2633        // var _this = this;
2634        /**
2635         * Fires to close other open dropdowns
2636         * @event Dropdown#closeme
2637         */
2638        this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id'));
2639        this.$anchor.addClass('hover').attr({ 'aria-expanded': true });
2640        // this.$element/*.show()*/;
2641        this._setPosition();
2642        this.$element.addClass('is-open').attr({ 'aria-hidden': false });
2643
2644        if (this.options.autoFocus) {
2645          var $focusable = Foundation.Keyboard.findFocusable(this.$element);
2646          if ($focusable.length) {
2647            $focusable.eq(0).focus();
2648          }
2649        }
2650
2651        if (this.options.closeOnClick) {
2652          this._addBodyHandler();
2653        }
2654
2655        /**
2656         * Fires once the dropdown is visible.
2657         * @event Dropdown#show
2658         */
2659        this.$element.trigger('show.zf.dropdown', [this.$element]);
2660      }
2661
2662      /**
2663       * Closes the open dropdown pane.
2664       * @function
2665       * @fires Dropdown#hide
2666       */
2667
2668    }, {
2669      key: 'close',
2670      value: function close() {
2671        if (!this.$element.hasClass('is-open')) {
2672          return false;
2673        }
2674        this.$element.removeClass('is-open').attr({ 'aria-hidden': true });
2675
2676        this.$anchor.removeClass('hover').attr('aria-expanded', false);
2677
2678        if (this.classChanged) {
2679          var curPositionClass = this.getPositionClass();
2680          if (curPositionClass) {
2681            this.$element.removeClass(curPositionClass);
2682          }
2683          this.$element.addClass(this.options.positionClass)
2684          /*.hide()*/.css({ height: '', width: '' });
2685          this.classChanged = false;
2686          this.counter = 4;
2687          this.usedPositions.length = 0;
2688        }
2689        this.$element.trigger('hide.zf.dropdown', [this.$element]);
2690      }
2691
2692      /**
2693       * Toggles the dropdown pane's visibility.
2694       * @function
2695       */
2696
2697    }, {
2698      key: 'toggle',
2699      value: function toggle() {
2700        if (this.$element.hasClass('is-open')) {
2701          if (this.$anchor.data('hover')) return;
2702          this.close();
2703        } else {
2704          this.open();
2705        }
2706      }
2707
2708      /**
2709       * Destroys the dropdown.
2710       * @function
2711       */
2712
2713    }, {
2714      key: 'destroy',
2715      value: function destroy() {
2716        this.$element.off('.zf.trigger').hide();
2717        this.$anchor.off('.zf.dropdown');
2718
2719        Foundation.unregisterPlugin(this);
2720      }
2721    }]);
2722
2723    return Dropdown;
2724  }();
2725
2726  Dropdown.defaults = {
2727    /**
2728     * Amount of time to delay opening a submenu on hover event.
2729     * @option
2730     * @example 250
2731     */
2732    hoverDelay: 250,
2733    /**
2734     * Allow submenus to open on hover events
2735     * @option
2736     * @example false
2737     */
2738    hover: false,
2739    /**
2740     * Don't close dropdown when hovering over dropdown pane
2741     * @option
2742     * @example true
2743     */
2744    hoverPane: false,
2745    /**
2746     * Number of pixels between the dropdown pane and the triggering element on open.
2747     * @option
2748     * @example 1
2749     */
2750    vOffset: 1,
2751    /**
2752     * Number of pixels between the dropdown pane and the triggering element on open.
2753     * @option
2754     * @example 1
2755     */
2756    hOffset: 1,
2757    /**
2758     * Class applied to adjust open position. JS will test and fill this in.
2759     * @option
2760     * @example 'top'
2761     */
2762    positionClass: '',
2763    /**
2764     * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands.
2765     * @option
2766     * @example false
2767     */
2768    trapFocus: false,
2769    /**
2770     * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening.
2771     * @option
2772     * @example true
2773     */
2774    autoFocus: false,
2775    /**
2776     * Allows a click on the body to close the dropdown.
2777     * @option
2778     * @example false
2779     */
2780    closeOnClick: false
2781  };
2782
2783  // Window exports
2784  Foundation.plugin(Dropdown, 'Dropdown');
2785}(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.