/*
 *  Bootstrap Dropdown Hover - v4.2.0
 *  Open dropdown menus on mouse hover, the proper way.
 *  http://www.virtuosoft.eu/code/bootstrap-dropdown-hover/
 *
 *  Made by István Ujj-Mészáros
 *  Under Apache License v2.0 License
 */

!function(o){"function"==typeof define&&define.amd?define(["jquery"],o):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),o(t),t}:o(jQuery)}(function(i){var n,r,d="bootstrapDropdownHover",o={clickBehavior:"sticky",hideTimeout:200},s=!1;function a(e,t){this.element=i(e),this.settings=i.extend({},o,t,this.element.data()),this._defaults=o,this._name=d,this.init()}function u(e){var t,o=e.attr("data-target");return o||(o=(o=e.attr("href"))&&/#[A-Za-z]/.test(o)&&o.replace(/.*(?=#[^\s]*$)/,"")),(t=o&&i(o))&&t.length||(t=e.parent()),t}r=function(){var e=" -webkit- -moz- -o- -ms- ".split(" ");if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)return!0;var t,o=["(",e.join("touch-enabled),("),"heartz",")"].join("");return t=o,window.matchMedia(t).matches}(),a.prototype={init:function(){var t,o;return this.setClickBehavior(this.settings.clickBehavior),this.setHideTimeout(this.settings.hideTimeout),o=u((t=this).element),i(".dropdown-toggle, .dropdown-menu",o).on("mouseenter.dropdownhover",function(){r||(clearTimeout(n),o.is(".open, .show")||(s=!1,t.element.dropdown("toggle")))}),i(".dropdown-toggle, .dropdown-menu",o).on("mouseleave.dropdownhover",function(){r||s||(n=setTimeout(function(){o.is(".open, .show")&&t.element.dropdown("toggle")},t.settings.hideTimeout))}),t.element.on("click.dropdownhover",function(e){if("link"===t.settings.clickBehavior||!r)switch(t.settings.clickBehavior){case"default":return;case"disable":return e.preventDefault(),void e.stopImmediatePropagation();case"link":return void e.stopImmediatePropagation();case"sticky":return void(s?s=!1:(s=!0,o.is(".open, .show")&&(e.stopImmediatePropagation(),e.preventDefault())))}}),this.element},setClickBehavior:function(e){return this.settings.clickBehavior=e,this.element},setHideTimeout:function(e){return this.settings.hideTimeout=e,this.element},destroy:function(){var e,t;return clearTimeout(n),t=u((e=this).element),i(".dropdown-toggle, .dropdown-menu",t).off(".dropdownhover"),i(".dropdown-toggle, .dropdown-menu",t).off(".dropdown"),e.element.off(".dropdownhover"),i("body").off(".dropdownhover"),this.element.data("plugin_"+d,null),this.element}},i.fn[d]=function(o){var t,n=arguments;return void 0===o||"object"==typeof o?(i.contains(document,i(this)[0])||i('[data-toggle="dropdown"]').each(function(e,t){i(t).bootstrapDropdownHover(o)}),this.each(function(){i(this).hasClass("dropdown-toggle")&&"dropdown"===i(this).data("toggle")?i.data(this,"plugin_"+d)||i.data(this,"plugin_"+d,new a(this,o)):i('[data-toggle="dropdown"]',this).each(function(e,t){i(t).bootstrapDropdownHover(o)})})):"string"==typeof o&&"_"!==o[0]&&"init"!==o?(this.each(function(){var e=i.data(this,"plugin_"+d);e instanceof a&&"function"==typeof e[o]&&(t=e[o].apply(e,Array.prototype.slice.call(n,1)))}),void 0!==t?t:this):void 0}});