/*
 *  /MathJax/extensions/MathEvents.js
 *
 *  Copyright (c) 2009-2015 The MathJax Consortium
 *
 *  Licensed 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.
 */

(function(d,h,l,g,m,b,j){var p="2.6.0";var i=MathJax.Extension;var c=i.MathEvents={version:p};var k=d.config.menuSettings;var o={hover:500,frame:{x:3.5,y:5,bwidth:1,bcolor:"#A6D",hwidth:"15px",hcolor:"#83A"},button:{x:-6,y:-3,wx:-2},fadeinInc:0.2,fadeoutInc:0.05,fadeDelay:50,fadeoutStart:400,fadeoutDelay:15*1000,styles:{".MathJax_Hover_Frame":{"border-radius":".25em","-webkit-border-radius":".25em","-moz-border-radius":".25em","-khtml-border-radius":".25em","box-shadow":"0px 0px 15px #83A","-webkit-box-shadow":"0px 0px 15px #83A","-moz-box-shadow":"0px 0px 15px #83A","-khtml-box-shadow":"0px 0px 15px #83A",border:"1px solid #A6D ! important",display:"inline-block",position:"absolute"},".MathJax_Menu_Button .MathJax_Hover_Arrow":{position:"absolute",cursor:"pointer",display:"inline-block",border:"2px solid #AAA","border-radius":"4px","-webkit-border-radius":"4px","-moz-border-radius":"4px","-khtml-border-radius":"4px","font-family":"'Courier New',Courier","font-size":"9px",color:"#F0F0F0"},".MathJax_Menu_Button .MathJax_Hover_Arrow span":{display:"block","background-color":"#AAA",border:"1px solid","border-radius":"3px","line-height":0,padding:"4px"},".MathJax_Hover_Arrow:hover":{color:"white!important",border:"2px solid #CCC!important"},".MathJax_Hover_Arrow:hover span":{"background-color":"#CCC!important"}}};var n=c.Event={LEFTBUTTON:0,RIGHTBUTTON:2,MENUKEY:"altKey",KEY:{RETURN:13,ESCAPE:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40},Mousedown:function(q){return n.Handler(q,"Mousedown",this)},Mouseup:function(q){return n.Handler(q,"Mouseup",this)},Mousemove:function(q){return n.Handler(q,"Mousemove",this)},Mouseover:function(q){return n.Handler(q,"Mouseover",this)},Mouseout:function(q){return n.Handler(q,"Mouseout",this)},Click:function(q){return n.Handler(q,"Click",this)},DblClick:function(q){return n.Handler(q,"DblClick",this)},Menu:function(q){return n.Handler(q,"ContextMenu",this)},Handler:function(t,r,s){if(l.loadingMathMenu){return n.False(t)}var q=b[s.jaxID];if(!t){t=window.event}t.isContextMenu=(r==="ContextMenu");if(q[r]){return q[r](t,s)}if(i.MathZoom){return i.MathZoom.HandleEvent(t,r,s)}},False:function(q){if(!q){q=window.event}if(q){if(q.preventDefault){q.preventDefault()}else{q.returnValue=false}if(q.stopPropagation){q.stopPropagation()}q.cancelBubble=true}return false},Keydown:function(r,q){if(!r){r=window.event}if(r.keyCode===n.KEY.SPACE){n.ContextMenu(r,this)}},ContextMenu:function(t,E,w){var B=b[E.jaxID],v=B.getJaxFromMath(E);var F=(B.config.showMathMenu!=null?B:d).config.showMathMenu;if(!F||(k.context!=="MathJax"&&!w)){return}if(c.msieEventBug){t=window.event||t}n.ClearSelection();f.ClearHoverTimer();if(v.hover){if(v.hover.remove){clearTimeout(v.hover.remove);delete v.hover.remove}v.hover.nofade=true}var u=MathJax.Menu;var G,D;if(u){if(u.loadingDomain){return n.False(t)}G=m.loadDomain("MathMenu");if(!G){u.jax=v;var r=u.menu.Find("Show Math As").submenu;r.items[0].name=v.sourceMenuTitle;r.items[0].format=(v.sourceMenuFormat||"MathML");r.items[1].name=j[v.inputJax].sourceMenuTitle;r.items[5].disabled=!j[v.inputJax].annotationEncoding;var A=r.items[2];A.disabled=true;var q=A.submenu.items;annotationList=MathJax.Hub.Config.semanticsAnnotations;for(var z=0,y=q.length;z<y;z++){var s=q[z].name[1];if(v.root&&v.root.getAnnotation(s)!==null){A.disabled=false;q[z].hidden=false}else{q[z].hidden=true}}var x=u.menu.Find("Math Settings","MathPlayer");x.hidden=!(v.outputJax==="NativeMML"&&d.Browser.hasMathPlayer);return u.menu.Post(t)}u.loadingDomain=true;D=function(){delete u.loadingDomain}}else{if(l.loadingMathMenu){return n.False(t)}l.loadingMathMenu=true;G=l.Require("[MathJax]/extensions/MathMenu.js");D=function(){delete l.loadingMathMenu;if(!MathJax.Menu){MathJax.Menu={}}}}var C={pageX:t.pageX,pageY:t.pageY,clientX:t.clientX,clientY:t.clientY};g.Queue(G,D,["ContextMenu",n,C,E,w]);return n.False(t)},AltContextMenu:function(s,r){var t=b[r.jaxID];var q=(t.config.showMathMenu!=null?t:d).config.showMathMenu;if(q){q=(t.config.showMathMenuMSIE!=null?t:d).config.showMathMenuMSIE;if(k.context==="MathJax"&&!k.mpContext&&q){if(!c.noContextMenuBug||s.button!==n.RIGHTBUTTON){return}}else{if(!s[n.MENUKEY]||s.button!==n.LEFTBUTTON){return}}return t.ContextMenu(s,r,true)}},ClearSelection:function(){if(c.safariContextMenuBug){setTimeout("window.getSelection().empty()",0)}if(document.selection){setTimeout("document.selection.empty()",0)}},getBBox:function(s){s.appendChild(c.topImg);var r=c.topImg.offsetTop,t=s.offsetHeight-r,q=s.offsetWidth;s.removeChild(c.topImg);return{w:q,h:r,d:t}}};var f=c.Hover={Mouseover:function(s,r){if(k.discoverable||k.zoom==="Hover"){var u=s.fromElement||s.relatedTarget,t=s.toElement||s.target;if(u&&t&&(d.isMathJaxNode(u)!==d.isMathJaxNode(t)||d.getJaxFor(u)!==d.getJaxFor(t))){var q=this.getJaxFromMath(r);if(q.hover){f.ReHover(q)}else{f.HoverTimer(q,r)}return n.False(s)}}},Mouseout:function(s,r){if(k.discoverable||k.zoom==="Hover"){var u=s.fromElement||s.relatedTarget,t=s.toElement||s.target;if(u&&t&&(d.isMathJaxNode(u)!==d.isMathJaxNode(t)||d.getJaxFor(u)!==d.getJaxFor(t))){var q=this.getJaxFromMath(r);if(q.hover){f.UnHover(q)}else{f.ClearHoverTimer()}return n.False(s)}}},Mousemove:function(s,r){if(k.discoverable||k.zoom==="Hover"){var q=this.getJaxFromMath(r);if(q.hover){return}if(f.lastX==s.clientX&&f.lastY==s.clientY){return}f.lastX=s.clientX;f.lastY=s.clientY;f.HoverTimer(q,r);return n.False(s)}},HoverTimer:function(q,r){this.ClearHoverTimer();this.hoverTimer=setTimeout(g(["Hover",this,q,r]),o.hover)},ClearHoverTimer:function(){if(this.hoverTimer){clearTimeout(this.hoverTimer);delete this.hoverTimer}},Hover:function(q,u){if(i.MathZoom&&i.MathZoom.Hover({},u)){return}var t=b[q.outputJax],v=t.getHoverSpan(q,u),y=t.getHoverBBox(q,v,u),w=(t.config.showMathMenu!=null?t:d).config.showMathMenu;var A=o.frame.x,z=o.frame.y,x=o.frame.bwidth;if(c.msieBorderWidthBug){x=0}q.hover={opacity:0,id:q.inputID+"-Hover"};var r=h.Element("span",{id:q.hover.id,isMathJax:true,style:{display:"inline-block",width:0,height:0,position:"relative"}},[["span",{className:"MathJax_Hover_Frame",isMathJax:true,style:{display:"inline-block",position:"absolute",top:this.Px(-y.h-z-x-(y.y||0)),left:this.Px(-A-x+(y.x||0)),width:this.Px(y.w+2*A),height:this.Px(y.h+y.d+2*z),opacity:0,filter:"alpha(opacity=0)"}}]]);var s=h.Element("span",{isMathJax:true,id:q.hover.id+"Menu",className:"MathJax_Menu_Button",style:{display:"inline-block","z-index":1,width:0,height:0,position:"relative"}},[["span",{className:"MathJax_Hover_Arrow",isMathJax:true,math:u,onclick:this.HoverMenu,jax:t.id,style:{left:this.Px(y.w+A+x+(y.x||0)+o.button.x),top:this.Px(-y.h-z-x-(y.y||0)-o.button.y),opacity:0,filter:"alpha(opacity=0)"}},[["span",{isMathJax:true},"\u25BC"]]]]);if(y.width){r.style.width=s.style.width=y.width;r.style.marginRight=s.style.marginRight="-"+y.width;r.firstChild.style.width=y.width;s.firstChild.style.left="";s.firstChild.style.right=this.Px(o.button.wx)}v.parentNode.insertBefore(r,v);if(w){v.parentNode.insertBefore(s,v)}if(v.style){v.style.position="relative"}this.ReHover(q)},ReHover:function(q){if(q.hover.remove){clearTimeout(q.hover.remove)}q.hover.remove=setTimeout(g(["UnHover",this,q]),o.fadeoutDelay);this.HoverFadeTimer(q,o.fadeinInc)},UnHover:function(q){if(!q.hover.nofade){this.HoverFadeTimer(q,-o.fadeoutInc,o.fadeoutStart)}},HoverFade:function(q){delete q.hover.timer;q.hover.opacity=Math.max(0,Math.min(1,q.hover.opacity+q.hover.inc));q.hover.opacity=Math.floor(1000*q.hover.opacity)/1000;var s=document.getElementById(q.hover.id),r=document.getElementById(q.hover.id+"Menu");s.firstChild.style.opacity=q.hover.opacity;s.firstChild.style.filter="alpha(opacity="+Math.floor(100*q.hover.opacity)+")";if(r){r.firstChild.style.opacity=q.hover.opacity;r.firstChild.style.filter=s.style.filter}if(q.hover.opacity===1){return}if(q.hover.opacity>0){this.HoverFadeTimer(q,q.hover.inc);return}s.parentNode.removeChild(s);if(r){r.parentNode.removeChild(r)}if(q.hover.remove){clearTimeout(q.hover.remove)}delete q.hover},HoverFadeTimer:function(q,s,r){q.hover.inc=s;if(!q.hover.timer){q.hover.timer=setTimeout(g(["HoverFade",this,q]),(r||o.fadeDelay))}},HoverMenu:function(q){if(!q){q=window.event}return b[this.jax].ContextMenu(q,this.math,true)},ClearHover:function(q){if(q.hover.remove){clearTimeout(q.hover.remove)}if(q.hover.timer){clearTimeout(q.hover.timer)}f.ClearHoverTimer();delete q.hover},Px:function(q){if(Math.abs(q)<0.006){return"0px"}return q.toFixed(2).replace(/\.?0+$/,"")+"px"},getImages:function(){if(k.discoverable){var q=new Image();q.src=o.button.src}}};var a=c.Touch={last:0,delay:500,start:function(r){var q=new Date().getTime();var s=(q-a.last<a.delay&&a.up);a.last=q;a.up=false;if(s){a.timeout=setTimeout(a.menu,a.delay,r,this);r.preventDefault()}},end:function(r){var q=new Date().getTime();a.up=(q-a.last<a.delay);if(a.timeout){clearTimeout(a.timeout);delete a.timeout;a.last=0;a.up=false;r.preventDefault();return n.Handler((r.touches[0]||r.touch),"DblClick",this)}},menu:function(r,q){delete a.timeout;a.last=0;a.up=false;return n.Handler((r.touches[0]||r.touch),"ContextMenu",q)}};d.Browser.Select({MSIE:function(q){var s=(document.documentMode||0);var r=q.versionAtLeast("8.0");c.msieBorderWidthBug=(document.compatMode==="BackCompat");c.msieEventBug=q.isIE9;c.msieAlignBug=(!r||s<8);if(s<9){n.LEFTBUTTON=1}},Safari:function(q){c.safariContextMenuBug=true},Opera:function(q){c.operaPositionBug=true},Konqueror:function(q){c.noContextMenuBug=true}});c.topImg=(c.msieAlignBug?h.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}):h.Element("span",{style:{width:0,height:0,display:"inline-block"}}));if(c.operaPositionBug){c.topImg.style.border="1px solid"}c.config=o=d.CombineConfig("MathEvents",o);var e=function(){var q=o.styles[".MathJax_Hover_Frame"];q.border=o.frame.bwidth+"px solid "+o.frame.bcolor+" ! important";q["box-shadow"]=q["-webkit-box-shadow"]=q["-moz-box-shadow"]=q["-khtml-box-shadow"]="0px 0px "+o.frame.hwidth+" "+o.frame.hcolor};g.Queue(d.Register.StartupHook("End Config",{}),[e],["getImages",f],["Styles",l,o.styles],["Post",d.Startup.signal,"MathEvents Ready"],["loadComplete",l,"[MathJax]/extensions/MathEvents.js"])})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback,MathJax.Localization,MathJax.OutputJax,MathJax.InputJax);
