/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
"use strict";$(document).ready(function(){$(this).find('[data-toggle="collapseAccordion"]').off("click").on("click",function(n){var l=$(this);return l.siblings(".panel-body").slideToggle(500),l.children().children(".panel-toggle").toggleClass("fa-angle-down fa-angle-up"),n.stopPropagation(),!1})});
"use strict";!function(e){e.fn.navigationBar=function(n){var t=e.extend({},e.fn.navigationBar.defaults,n);return this.each(function(){function n(){var n=window.location.pathname+window.location.hash;"/"!==n[n.length-1]&&(n+="/"),i.find("li a").each(function(t,a){var s=e(a),i=s.attr("data-href")||s.attr("href"),o=null==i||"/"===i[i.length-1]?i:i+"/";-1!==n.indexOf(o)&&-1===["","#"].indexOf(i)?s.parent().addClass("active"):s.parent().removeClass("active")})}function a(n){var a=e(n).parent(),s=t.activeClass,o=r+"."+s,l=f+"."+s;i.find(o).removeClass(s),i.find(l).removeClass(s),a.addClass(s)}var s=this,i=e(this).find(".navigation-bar-container"),o=e(this).find("[data-toggle="+t.navBarToggleDataAttr+"]"),l=e(this).find("[data-toggle="+t.subMenuNavToggleDataAttr+"]"),r=".side-nav-menu>li",f=".side-nav-menu>li>ul>li",u=e(this).find(".more-actions"),d=u.children(".dropdown-menu");l.each(function(n,t){return e(t).parent().addClass("has-sub-menu")}),t.fitHeight&&(e(this).addClass("navigation-bar-fit-height"),e(this).find(".side-nav-menu").on("DOMMouseScroll mousewheel",function(n){var t=e(this),a=this.scrollTop,s=this.scrollHeight,i=t.innerHeight(),o=n.originalEvent.wheelDelta,l=o>0,r=function(){return n.stopPropagation(),n.preventDefault(),n.returnValue=!1,!1};return!l&&-o>s-i-a?(t.scrollTop(s),r()):l&&o>a?(t.scrollTop(0),r()):void 0}));var c=i.width();t.moveLeftContent&&e(t.content).css("margin-left",c),t.moveLeftFooter&&e(t.footer).css("margin-left",c),t.handlePopState&&(n(),e(window).bind("popstate",n)),e(r+">a").on("click",function(){a(this)}),e(f+">a").on("click",function(){a(this),e(this).parent().parent().parent().addClass(t.activeClass)}),l.off("click").on("click",function(n){if(i.hasClass("collapsed"))return!1;var a=e(this);return a.siblings(".sub-menu").slideToggle(600,function(){var e=a.parent();return e.find("ul").is(":visible")?e.removeClass("collapsed"):e.addClass("collapsed")}),a.children(".toggle-icon").toggleClass(t.menuLeftClass+" "+t.menuDownClass),n.stopPropagation(),!1}),t.fitHeight&&u.on("click",function(){var n=e(this),t=e(".side-nav-header");d.css({top:n.offset().top-t.offset().top+20+"px",left:n.offset().left+"px"})}),i.children(".side-nav-menu").scroll(function(){u.removeClass("open")}),o.click(function(){return i.toggleClass("collapsed").promise().done(function(){var n=i.find("ul.sub-menu"),a=i.find(".side-nav-menu>li");i.hasClass("collapsed")?(n.hide(),u.hide(),a.hover(function(){e(this).find("ul.sub-menu").show();var n=e(this),a=e(".side-nav-header");t.fitHeight&&e(this).find("ul.sub-menu").css({position:"fixed",top:n.offset().top-a.offset().top+"px",left:"50px"})},function(){e(this).find("ul.sub-menu").hide()})):(n.show().each(function(n,t){return e(t).parent().removeClass("collapsed")}),a.unbind("mouseenter mouseleave"),i.find(".toggle-icon").removeClass(t.menuLeftClass).addClass(t.menuDownClass),u.show(),t.fitHeight&&e(s).find("ul.sub-menu").css({position:"relative",top:0,left:0})),i.on("transitionend",function(){var n=i.width();t.moveLeftContent&&e(t.content).css("margin-left",n),t.moveLeftFooter&&e(t.footer).css("margin-left",n)}),o.find("span").toggleClass(t.collapseNavBarClass+" "+t.expandNavBarClass)}),!1})})},e.fn.navigationBar.defaults={handlePopState:!0,fitHeight:!1,content:"#main",footer:"footer",moveLeftContent:!0,moveLeftFooter:!0,menuLeftClass:"glyphicon-menu-right",menuDownClass:"glyphicon-menu-down",collapseNavBarClass:"fa-angle-double-left",expandNavBarClass:"fa-angle-double-right",activeClass:"active",navBarToggleDataAttr:"collapse-side-nav",subMenuNavToggleDataAttr:"collapse-sub-menu"}}(jQuery);
