function SpellUsage(){this.NourishTime=50;this.EffHits=3;this.WGonCD=true;this.RollLB=true;this.TLonCD=true;this.SMonCD=true;this.OnClearcasts=1;this.RemainderSpell=0;this.NGProcsTime=75;this.HarmUptime=100;this.TranqTargets=10;this.TranqFreq=180;}
SpellUsage.prototype.setupControls=function(){addSelectOptions(document.getElementById("OnClearcasts"),[0,1,2],["None","Healing Touch","Regrowth"]);addSelectOptions(document.getElementById("RemainderSpell"),[0,1,2],["Rejuvenation","Healing Touch","Regrowth"]);this.updateControls();};SpellUsage.prototype.updateControls=function(){setValueFromProperty(this,"NourishTime");setValueFromProperty(this,"EffHits");setValueFromProperty(this,"WGonCD");setValueFromProperty(this,"RollLB");setValueFromProperty(this,"TLonCD");setValueFromProperty(this,"SMonCD");setValueFromProperty(this,"OnClearcasts");setValueFromProperty(this,"RemainderSpell");setValueFromProperty(this,"NGProcsTime");setValueFromProperty(this,"HarmUptime");setValueFromProperty(this,"TranqTargets");setValueFromProperty(this,"TranqFreq");};SpellUsage.prototype.readControls=function(){setPropertyFromValue(this,"NourishTime",true);setPropertyFromValue(this,"EffHits",true);setPropertyFromValue(this,"WGonCD");setPropertyFromValue(this,"RollLB");setPropertyFromValue(this,"TLonCD");setPropertyFromValue(this,"SMonCD");setPropertyFromValue(this,"OnClearcasts");setPropertyFromValue(this,"RemainderSpell");setPropertyFromValue(this,"NGProcsTime",true);setPropertyFromValue(this,"HarmUptime",true);setPropertyFromValue(this,"TranqTargets",true);setPropertyFromValue(this,"TranqFreq",true);};function Character(name,region,realm){this.name=name;this.region=region;this.realm=realm;}
Character.prototype.defaults=function(){this.stats=new Stats();this.gear=new Gear();this.buffs=getBuffs();this.spellUsage=new SpellUsage();this.talentSpecs=new Array(new TalentSpec(true));this.currentSpecIndex=0;this.profileLoaded=true;};Character.prototype.loadProfile=function(data){if(!data||data.error)
this.profileLoaded=false;else{this.stats=loadStats(data);this.gear=loadGear(data);this.talentSpecs=loadTalentSpecs(data);if(this.talentSpecs.length>0)
this.currentSpecIndex=this.findActiveSpecIndex();this.profileLoaded=true;}
this.onLoaded((this.profileLoaded)?this:null);};Character.prototype.findActiveSpecIndex=function(){if(this.talentSpecs.length==1)
return 0;for(var i=0;i<this.talentSpecs.length;i++){if(this.talentSpecs[i].active)
return i;}
return-1;};Character.prototype.load=function(){this.stats=null;this.gear=null;this.buffs=getBuffs();this.spellUsage=new SpellUsage();this.talentSpecs=null;this.currentSpecIndex=-1;this.profileLoaded=false;var url=window.TreeCalcs.urls.import_character.replace("%r",this.region);url=url.replace("%s",this.realm).replace("%n",this.name);var currentCharacter=this;$.ajax({url:url,dataType:"json",success:function(data){currentCharacter.loadProfile(data);},error:function(){currentCharacter.loadProfile(null);}});};Character.prototype.getCurrentSpec=function(){return(this.currentSpecIndex>=0)?this.talentSpecs[this.currentSpecIndex]:null;};Character.prototype.setCurrentSpec=function(i){if(i>=this.talentSpecs.length)
this.currentSpecIndex=this.findActiveSpecIndex();else
this.currentSpecIndex=i;};Character.prototype.setupControls=function(){this.stats.setupControls();this.gear.setupControls();this.getCurrentSpec().setupControls();setupBuffControls(this.buffs);this.spellUsage.setupControls();};Character.prototype.updateControls=function(){this.stats.updateControls();this.gear.updateControls();this.getCurrentSpec().updateControls();this.spellUsage.updateControls();updateBuffControls(this.buffs);};Character.prototype.readControls=function(){this.stats.readControls();this.gear.readControls();this.getCurrentSpec().readControls();readBuffControls(this.buffs);this.spellUsage.readControls();};Character.prototype.updateBonuses=function(isClear){this.stats.updateBonuses(isClear);this.gear.updateBonuses(isClear);this.getCurrentSpec().updateBonuses(isClear);updateBuffBonuses(this.buffs,isClear);};Character.prototype.setNoBuffs=function(){updateBuffControls(this.buffs,2);};Character.prototype.setDefaultBuffs=function(){updateBuffControls(this.buffs,1);};function Stats(){this.classId=Stats.DruidClassId;this.level=Stats.GoodLevel;this.raceId=0;this.spellPower=0;this.spellCrit=0;this.spellHaste=0;this.intellect=0;this.spirit=0;this.mastery=0;this.profession1Id=0;this.profession2Id=0;this.instantDelay=0;this.whatIf=null;}
Stats.DruidClassId=11;Stats.GoodLevel=85;Stats.prototype.toString=function(){var s="classId:"+this.classId;s+=";spellPower:"+this.spellPower;s+=";spellHaste:"+this.spellHaste;s+=";spellCrit:"+this.spellCrit;s+=";intellect:"+this.intellect;s+=";spirit:"+this.spirit;s+=";mastery:"+this.mastery;return s;}
Stats.prototype.load=function(data){this.classId=data["class"];this.level=data.level;this.raceId=data.race;var statsElement=data.stats;this.intellect=statsElement["int"];this.spirit=statsElement.spr;this.mastery=statsElement.masteryRating;this.spellPower=statsElement.spellPower;this.spellHaste=statsElement.hasteRating;this.spellCrit=statsElement.spellCritRating;var profElement=data.professions.primary;this.profession1Id=(profElement.length>0)?profElement[0].id:0;this.profession2Id=(profElement.length>1)?profElement[1].id:0;}
Stats.prototype.setupControls=function(){addSelectOptions(document.getElementById("raceId"),[0,4,22,8,6],["Not selected","Night elf","Worgen","Troll","Tauren"]);var professionIds=[0,165,393,171,164,333,186,202,182,197,755,773];var professionNames=["None","Leatheworking","Skinning","Alchemy","Blacksmithing","Enchanting","Mining","Engineering","Herbalism","Tailoring","Jewelcrafting","Inscription"];addSelectOptions(document.getElementById("profession1Id"),professionIds,professionNames);addSelectOptions(document.getElementById("profession2Id"),professionIds,professionNames);this.updateControls();}
Stats.prototype.hasProfession=function(profId){return this.profession1Id==profId||this.profession2Id==profId;}
Stats.prototype.isAlchemist=function(){return this.hasProfession(171);}
Stats.prototype.updateControls=function(){setValueFromProperty(this,"spellPower");setValueFromProperty(this,"spellCrit");setValueFromProperty(this,"spellHaste");setValueFromProperty(this,"intellect");setValueFromProperty(this,"spirit");setValueFromProperty(this,"mastery");setValueFromProperty(this,"instantDelay");setValueFromProperty(this,"raceId");setValueFromProperty(this,"profession1Id");setValueFromProperty(this,"profession2Id");this.updateBonuses(true);}
Stats.prototype.readControls=function(){setPropertyFromValue(this,"spellPower",true);setPropertyFromValue(this,"spellCrit",true);setPropertyFromValue(this,"spellHaste",true);setPropertyFromValue(this,"intellect",true);setPropertyFromValue(this,"spirit",true);setPropertyFromValue(this,"mastery",true);setPropertyFromValue(this,"instantDelay",true);setPropertyFromValue(this,"raceId",true);setPropertyFromValue(this,"profession1Id",true);setPropertyFromValue(this,"profession2Id",true);}
Stats.prototype.updateBonuses=function(isClear){setObjectBonuses(this,"spellPower",false,(isClear)?0:this.whatIf.spellPowerHPS,(isClear)?0:this.whatIf.spellPowerMP5);setObjectBonuses(this,"spellCrit",false,(isClear)?0:this.whatIf.spellCritHPS,(isClear)?0:this.whatIf.spellCritMP5);setObjectBonuses(this,"spellHaste",false,(isClear)?0:this.whatIf.spellHasteHPS,(isClear)?0:this.whatIf.spellHasteMP5);setObjectBonuses(this,"intellect",false,(isClear)?0:this.whatIf.intellectHPS,(isClear)?0:this.whatIf.intellectMP5);setObjectBonuses(this,"spirit",false,(isClear)?0:this.whatIf.spiritHPS,(isClear)?0:this.whatIf.spiritMP5);setObjectBonuses(this,"mastery",false,(isClear)?0:this.whatIf.masteryHPS,(isClear)?0:this.whatIf.masteryMP5);setObjectBonuses(this,"instantDelay",false,(isClear)?0:this.whatIf.instantDelayHPS,(isClear)?0:this.whatIf.instantDelayMP5);}
function loadStats(data){var stats=new Stats();stats.load(data);return stats;}
function Talent(name,maxPoints,whatIfIncluded,whatIfFactor){this.name=name;this.maxPoints=maxPoints;this.order=-1;this.whatIfIncluded=whatIfIncluded;this.points=0;this.whatIfFactor=(whatIfFactor!=null)?whatIfFactor:0;this.HPS=0;this.MP5=0;this.cumulativeMP5=false;}
Talent.prototype.toString=function(){return this.name+":"+this.points+((this.whatIfIncluded)?";"+this.HPS+";"+this.MP5:"");}
Talent.prototype.loadFromString=function(s){if(this.order>=0)
this.points=(this.order<s.length)?Number(s.charAt(this.order)):0;}
Talent.prototype.getWhatIfPoints=function(){return(this.points)?this.points*this.whatIfFactor:1;}
Talent.prototype.isExtraMode=function(){return(this.whatIfFactor&&this.whatIfFactor!=0)}
function Glyph(name,id){this.name=name;this.id=id;this.HPS=0;this.MP5=0;}
function TalentSpec(active){this.active=active;this.name="";this.treeOne=0;this.treeTwo=0;this.treeThree=0;this.value="";this.primeGlyphs=new Array(3);this.majorGlyphs=new Array(3);for(var i=0;i<this.primeGlyphs.length;i++)
this.primeGlyphs[i]=new Glyph("PrimeGlyph"+String(i+1),0);for(var i=0;i<this.majorGlyphs.length;i++)
this.majorGlyphs[i]=new Glyph("MajorGlyph"+String(i+1),0);this.talents=TalentSpec.getTalents();}
TalentSpec.getTalents=function(){var talents=[];var o=0;function addTalent(t){t.order=o++;talents[t.name]=t;}
addTalent(new Talent("NaturesGrace",3,true));addTalent(new Talent("StarlightWrath"));addTalent(new Talent("NaturesMajesty",2,true));addTalent(new Talent("Genesis",3,true));addTalent(new Talent("Moonglow",3,true));addTalent(new Talent("BalanceOfPower"));addTalent(new Talent("Euphoria"));addTalent(new Talent("MoonkinForm"));addTalent(new Talent("Typhoon"));addTalent(new Talent("ShootingStars"));addTalent(new Talent("OwlkinFrenzy"));addTalent(new Talent("GaleWinds"));addTalent(new Talent("SolarBeam"));addTalent(new Talent("Dreamstate"));addTalent(new Talent("ForceOfNature"));addTalent(new Talent("Sunfire"));addTalent(new Talent("EarthAndMoon"));addTalent(new Talent("FungalGrowth"));addTalent(new Talent("LunarShower"));addTalent(new Talent("Starfall"));addTalent(new Talent("FeralSwiftness"));addTalent(new Talent("Furor",3,true));talents["Furor"].cumulativeMP5=true;addTalent(new Talent("PredatoryStrikes"));addTalent(new Talent("InfectedWounds"));addTalent(new Talent("FurySwipes"));addTalent(new Talent("PrimalFury"));addTalent(new Talent("FeralAggression"));addTalent(new Talent("KingOfTheJungle"));addTalent(new Talent("FeralCharge"));addTalent(new Talent("Stampede"));addTalent(new Talent("ThickHide"));addTalent(new Talent("LeaderOfThePack"));addTalent(new Talent("BrutalImpact"));addTalent(new Talent("NurturingInstinct"));addTalent(new Talent("PrimalMadness"));addTalent(new Talent("SurvivalInstincts"));addTalent(new Talent("EndlessCharge"));addTalent(new Talent("NaturalReaction"));addTalent(new Talent("BloodInWater"));addTalent(new Talent("RendAndTear"));addTalent(new Talent("Pulverize"));addTalent(new Talent("Berserk"));addTalent(new Talent("BotG",2,true));addTalent(new Talent("NaturalShapeshifter",2,true));addTalent(new Talent("Naturalist",2,true));addTalent(new Talent("HotW",3,true,-1));talents["HotW"].cumulativeMP5=true;addTalent(new Talent("Perseverance",3));addTalent(new Talent("MasterShapeshifter",1,true));addTalent(new Talent("ImprovedRejuvenation",3,true));addTalent(new Talent("LivingSeed",3,true));addTalent(new Talent("Revitalize",2,true));addTalent(new Talent("NaturesSwiftness",1));addTalent(new Talent("FuryOfStormrage",2));addTalent(new Talent("NaturesBounty",3,true));addTalent(new Talent("EmpoweredTouch",2,true));addTalent(new Talent("MalfurionGift",2,true));addTalent(new Talent("Efflorescence",3,true));addTalent(new Talent("WildGrowth",1,true));addTalent(new Talent("NatureCure",1));addTalent(new Talent("NatureWard",2));addTalent(new Talent("GotE",3,true));addTalent(new Talent("SwiftRejuv",1,true));addTalent(new Talent("ToL",1,true));return talents;}
TalentSpec.loadTalentsFromString=function(talents,s){for(var n in talents){talents[n].loadFromString(s);}}
TalentSpec.prototype.load=function(talentItem){this.active=talentItem.selected;this.name=talentItem.name;this.loadGlyphs(talentItem.glyphs);this.loadTalents(talentItem);}
TalentSpec.prototype.toString=function(){return this.name+"("+this.treeOne+"/"+this.treeTwo+"/"+this.treeThree+")";}
TalentSpec.prototype.loadGlyphs=function(talentGlyphs){var i=0;for(var index=0;index<talentGlyphs.prime.length;index++)
this.primeGlyphs[i++].id=talentGlyphs.prime[index].glyph;i=0;for(var index=0;index<talentGlyphs.major.length;index++)
this.majorGlyphs[i++].id=talentGlyphs.major[index].glyph;}
TalentSpec.prototype.loadTalents=function(talentItem){this.treeOne=talentItem.trees[0];this.treeTwo=talentItem.trees[1];this.treeThree=talentItem.trees[2];this.value=talentItem.build;TalentSpec.loadTalentsFromString(this.talents,this.value);}
TalentSpec.prototype.hasGlyph=function(glyphId){for(var i=0;i<this.majorGlyphs.length;i++)
if(this.majorGlyphs[i].id==glyphId)return true;for(var i=0;i<this.primeGlyphs.length;i++)
if(this.primeGlyphs[i].id==glyphId)return true;return false;}
TalentSpec.prototype.hasGlyphOfSwiftmend=function(){return this.hasGlyph(168);}
TalentSpec.prototype.hasGlyphOfInnervate=function(){return this.hasGlyph(169);}
TalentSpec.prototype.hasGlyphOfRegrowth=function(){return this.hasGlyph(171);}
TalentSpec.prototype.hasGlyphOfRejuvenation=function(){return this.hasGlyph(172);}
TalentSpec.prototype.hasGlyphOfHealingTouch=function(){return this.hasGlyph(173);}
TalentSpec.prototype.hasGlyphOfLifebloom=function(){return this.hasGlyph(174);}
TalentSpec.prototype.hasGlyphOfWildGrowth=function(){return this.hasGlyph(672);}
TalentSpec.prototype.hasGlyphOfNourish=function(){return this.hasGlyph(673);}
TalentSpec.prototype.hasGlyphOfRebirth=function(){return this.hasGlyph(170);}
TalentSpec.prototype.setupControls=function(){for(var tn in this.talents){var t=this.talents[tn];if(t.maxPoints==null)
continue;addSelectOptions(document.getElementById(t.name),t.maxPoints+1);}
var primeGlyphNameList=["None","Swiftmend","Regrowth","Rejuvenation","Lifebloom"]
var primeGlyphValueList=[0,168,171,172,174];var majorGlyphNameList=["None","Innervate","Healing Touch","Wild Growth","Nourish","Rebirth"]
var majorGlyphValueList=[0,169,173,672,673,170];for(var g=0;g<this.majorGlyphs.length;g++){addSelectOptions(document.getElementById(this.majorGlyphs[g].name),majorGlyphValueList,majorGlyphNameList);}
for(var g=0;g<this.primeGlyphs.length;g++){addSelectOptions(document.getElementById(this.primeGlyphs[g].name),primeGlyphValueList,primeGlyphNameList);}}
TalentSpec.prototype.updateControls=function(){for(var tn in this.talents){var t=this.talents[tn];if(t.maxPoints==null)
continue;setValueFromProperty(t,"points",true);}
for(var i=0;i<this.majorGlyphs.length;i++){setValueFromProperty(this.majorGlyphs[i],"id",true)}
for(var i=0;i<this.primeGlyphs.length;i++){setValueFromProperty(this.primeGlyphs[i],"id",true)}
this.updateBonuses(true);}
TalentSpec.prototype.readControls=function(){for(var tn in this.talents){var t=this.talents[tn];if(t.maxPoints==null)
continue;setPropertyFromValue(t,"points",true,true);}
for(var i=0;i<this.majorGlyphs.length;i++){setPropertyFromValue(this.majorGlyphs[i],"id",true,true)}
for(var i=0;i<this.primeGlyphs.length;i++){setPropertyFromValue(this.primeGlyphs[i],"id",true,true)}}
TalentSpec.prototype.updateBonuses=function(isClear){for(var tn in this.talents){var t=this.talents[tn];if(t.maxPoints==null)
continue;setObjectBonuses(t,"points",true,(isClear)?0:t.HPS,(isClear)?0:t.MP5);}
for(var i=0;i<this.majorGlyphs.length;i++){setObjectBonuses(this.majorGlyphs[i],"id",true,(isClear)?0:this.majorGlyphs[i].HPS,(isClear)?0:this.majorGlyphs[i].MP5);}
for(var i=0;i<this.primeGlyphs.length;i++){setObjectBonuses(this.primeGlyphs[i],"id",true,(isClear)?0:this.primeGlyphs[i].HPS,(isClear)?0:this.primeGlyphs[i].MP5);}}
function loadTalentSpecs(data){var talentSpecs=new Array();var i=0;for(var index in data.talents){var spec=new TalentSpec();spec.load(data.talents[index]);talentSpecs[i++]=spec;}
return talentSpecs;}
function Buff(name,valueList,nameList,defaultValueIndex,whatIfIncluded,whatIfValueIndex){this.name=name;this.valueList=valueList;this.nameList=nameList;this.defaultValue=valueList[defaultValueIndex];this.value=this.defaultValue;this.whatIfIncluded=(whatIfIncluded==null)?true:whatIfIncluded;if(this.whatIfIncluded)
this.whatIfValueIndex=(whatIfValueIndex!=null)?whatIfValueIndex:defaultValueIndex;this.HPS=0;this.MP5=0;this.cumulativeMP5=false;}
Buff.prototype.toString=function(){return this.name+":"+this.value+((this.whatIfIncluded)?";"+this.HPS+";"+this.MP5:"");}
Buff.prototype.isOff=function(){if(this.valueList.length<2)
return false;return this.value==this.valueList[0];}
Buff.prototype.getWhatIfValue=function(){if(this.valueList.length==1)
return this.whatIfValueIndex;return(this.isOff())?this.valueList[this.whatIfValueIndex]:this.valueList[0];}
function getBuffs(){var buffs=[];function addBuff(buff){buffs[buff.name]=buff;}
addBuff(new Buff("RaidSpellHaste",[0,1],["Off","On"],0,true,1));addBuff(new Buff("RaidAllCrit",[0,1],["Off","On"],0,true,1));addBuff(new Buff("RaidSpellpower",[0,0.06,0.1],["None","6%","10%"],2));addBuff(new Buff("RaidAllStats",[0,1],["Off","On"],0,true,1));buffs["RaidAllStats"].cumulativeMP5=true;addBuff(new Buff("RaidMP5",[0,1],["Off","On"],0,true,1));addBuff(new Buff("RaidMana",[0,1],["Off","On"],0,true,1));buffs["RaidMana"].cumulativeMP5=true;addBuff(new Buff("FocusMagic",[0,1],["Off","On"],0,true,1));addBuff(new Buff("DarkIntent",[0,1],["Off","On"],0,true,1));addBuff(new Buff("ReplenishmentUptime",[100],null,0,true,0));addBuff(new Buff("MTTShamansSpirit",[5000],null,0,true,0));addBuff(new Buff("InnervateTo",[0,1,2],["None","Yourself","Someone else"],1,true,0));addBuff(new Buff("Potion",[0,1,2],["None","Mythical Mana","Concentration"],1,false));var foodNames=["None","Feast (90 int)","90 Spirit","90 Crit","90 Haste","90 Mastery"];var foodValues=[foodNames.length];for(var i=0;i<foodNames.length;i++)
foodValues[i]=i;addBuff(new Buff("Food",foodValues,foodNames,1,true,0));buffs["Food"].cumulativeMP5=true;var elixirNames=["None","Flowing Water (Flask)","Drakonic Mind (Flask)","of the Master","Mighty Speed","Ghost","of the Cobra"];var elixirValues=[elixirNames.length];for(var i=0;i<elixirNames.length;i++)
elixirValues[i]=i;addBuff(new Buff("BattleElixir",elixirValues,elixirNames,2,true,0));buffs["BattleElixir"].cumulativeMP5=true;addBuff(new Buff("BloodlustHeroism",[0,1,2],["Never","Once in 10m","Always"],0,true,0));addBuff(new Buff("RacialEffect",[0],["None"],0,true,0));return buffs;}
function setupBuffControls(buffs){for(var bn in buffs){var b=buffs[bn];if(b.valueList.length==1)
continue;addSelectOptions(document.getElementById(b.name),b.valueList,b.nameList);}
updateBuffControls(buffs,1);$("#raceId").change(checkBuffControls);$("#RacialEffect").append("<option value='0'>None</option>");}
function updateBuffControls(buffs,mode){var zeroBuff=new Buff("",[0],null,0);for(var bn in buffs){var b=buffs[bn];if(mode==2){zeroBuff.name=b.name;setValueFromProperty(zeroBuff,"value",true);}
else
setValueFromProperty(b,(mode==1)?"defaultValue":"value",true);}
updateBuffBonuses(buffs,true);checkBuffControls(buffs);}
function readBuffControls(buffs){for(var bn in buffs){var b=buffs[bn];setPropertyFromValue(b,"value",true,true);}}
function checkBuffControls(buffs){var race=$("#raceId option:selected").val();var effect=$("#RacialEffect");effect.children("option:eq(1)").remove();effect.val(0);if(race==22){effect.append("<option value='1'>Worgen Crit</option>");effect.val(1);}
else
if(race==8){effect.append("<option value='2'>Troll berserking</option>");effect.val(2);}}
function updateBuffBonuses(buffs,isClear){for(var bn in buffs){var b=buffs[bn];if(!b.whatIfIncluded)
continue;setObjectBonuses(b,"value",true,(isClear)?0:b.HPS,(isClear)?0:b.MP5);}}
function GearItem(){this.id=0;this.gem0Id=0;this.gem1Id=0;this.gem2Id=0;this.enchant=0;this.slot=null;}
GearItem.prototype.toString=function(){return"itemId:"+this.id;};GearItem.prototype.load=function(slot,item){this.slot=slot;this.id=item.id;if(item.tooltipParams.gem0)
this.gem0Id=item.tooltipParams.gem0;if(item.tooltipParams.gem1)
this.gem1Id=item.tooltipParams.gem1;if(item.tooltipParams.gem2)
this.gem2Id=item.tooltipParams.gem2;if(item.tooltipParams.enchant)
this.enchant=item.tooltipParams.enchant;};function GearEffect(name,value,nameList,whatIfIncluded){this.name=name;this.value=value;this.nameList=nameList;this.whatIfIncluded=(whatIfIncluded==null)?true:whatIfIncluded;this.HPS=0;this.MP5=0;this.extraMode=null;this.cumulativeMP5=false;}
GearEffect.prototype.toString=function(){return this.name+":"+this.value+"; "+this.HPS+"; "+this.MP5;};GearEffect.prototype.getWhatIfValue=function(){if(!this.whatIfIncluded)
return null;if(this.value)
return(typeof this.value=="number")?0:false;else
return(typeof this.value=="number")?null:true;};function Gear(items){this.items=items;this.effects=getEffects(items);}
Gear.prototype.setupControls=function(){for(var p in this.effects){var e=this.effects[p];if(!e.nameList)
continue;addSelectOptions(document.getElementById(e.name),e.nameList.length,e.nameList)}
this.updateControls();};Gear.prototype.updateControls=function(){for(var p in this.effects){setValueFromProperty(this.effects[p],"value",true);}
this.updateBonuses(true);this.checkControls();};Gear.prototype.readControls=function(){for(var p in this.effects){setPropertyFromValue(this.effects[p],"value",true,true);}};Gear.prototype.checkControls=function(){var t=!document.getElementById("T11Set2").checked;document.getElementById("T11Set4").disabled=t;if(t)document.getElementById("T11Set4").checked=false;t=!document.getElementById("T12Set2").checked;document.getElementById("T12Set4").disabled=t;if(t)document.getElementById("T12Set4").checked=false;t=!document.getElementById("T13Set2").checked;document.getElementById("T13Set4").disabled=t;if(t)document.getElementById("T13Set4").checked=false;};Gear.prototype.updateBonuses=function(isClear){for(var p in this.effects){var e=this.effects[p];if(!e.whatIfIncluded)
continue;setObjectBonuses(e,"value",true,(isClear)?0:e.HPS,(isClear)?0:e.MP5);}};function hasTyrandeDoll(items){return[new GearEffect("TyrandeDoll",isItemPresents(items,64645))];}
function hasAncientJar(items){return hasItemVersion(items,"AncientJar",59354,65029);}
function hasVibrantStone(items){return[new GearEffect("VibrantStone",isItemPresents(items,68777))];}
function hasShardOfWoe(items){return[new GearEffect("ShardOfWoe",isItemPresents(items,60233))];}
function hasMandala(items){return[new GearEffect("Mandala",isItemPresents(items,62472)||isItemPresents(items,62467)||isItemPresents(items,68711))];}
function hasRuneOfZeth(items){return hasItemVersion(items,"RuneZeth",68998,69185);}
function hasFieryQ(items){return hasItemVersion(items,"FieryQ",69000,69198);}
function hasPPEgg(items){return[new GearEffect("PPEgg",isItemPresents(items,71336))];}
function hasWitchHG(items){return hasItemVersion(items,"WitchHG",55787,56320);}
function hasRainsong(items){return hasItemVersion(items,"Rainsong",55854,56377);}
function hasEyeBP(items){return hasItemVersion(items,"EyeBP",68983,69149);}
function hasWindwardH(items){return hasItemVersion(items,"WindwardH",77209,78001,77981);}
function hasSeal7(items){return hasItemVersion(items,"Seal7",77204,77989,77969);}
function hasTitahk(items){return hasItemVersion(items,"Titahk",77190,78477,78486);}
function hasT11(items){var t11items=[60280,60277,60278,60276,60279,65194,65195,65196,65197,65198];var piecesCount=getSetItemsCount(items,t11items);return[new GearEffect("T11Set2",piecesCount>=2),new GearEffect("T11Set4",piecesCount>=4)];}
function hasT12(items){var t12items=[71102,71103,71104,71105,71106,71491,71492,71493,71494,71495];var piecesCount=getSetItemsCount(items,t12items);return[new GearEffect("T12Set2",piecesCount>=2),new GearEffect("T12Set4",piecesCount>=4)];}
function hasT13(items){var t13items=[78775,78785,78805,78835,78755,76749,76750,76751,76753,76752,78680,78690,78710,78740,78660];var piecesCount=getSetItemsCount(items,t13items);return[new GearEffect("T13Set2",piecesCount>=2),new GearEffect("T13Set4",piecesCount>=4)];}
function hasMetagem(items){var headItem=null;for(var p in items)
if(items[p].slot=="head")
headItem=items[p];var nameList=new Array("None","Ember Shadowspirit Diamond","Revitalizing/Burning Shadowspirit Diamond");if(!headItem)return new GearEffect("Metagem",0,nameList);var id=headItem.gem0Id;switch(headItem.gem0Id){case 52296:id=1;break;case 52297:id=2;break;case 68780:id=2;break;}
var gEffect=new GearEffect("Metagem",id,nameList);gEffect.cumulativeMP5=true;return[gEffect];}
function hasAstralLeather(items){var aEffect=new GearEffect("AstralLeather",true);aEffect.extraMode="Astral";aEffect.cumulativeMP5=true;return[aEffect];}
function hasPowerTorrent(items){return[new GearEffect("PowerTorrent",hasEnchant(items,4097))];}
function hasHurricane(items){return[new GearEffect("Hurricane",hasEnchant(items,4083))];}
function isItemPresents(items,itemId){if(items)
for(var i=0;i<items.length;i++){if((items[i])&&(items[i].id==itemId))
return true;}
return false;}
function getSetItemsCount(items,setItems){var count=0;for(var i=0;i<setItems.length;i++){if(isItemPresents(items,setItems[i]))count++;}
return count;}
function hasItemVersion(items,name,normalId,heroicId,rfId){var nameList=new Array("None","Normal","Heroic");var id=0;if(isItemPresents(items,normalId))
id=1;if(isItemPresents(items,heroicId))
id=2;if(rfId){if(isItemPresents(items,rfId))
id=3;nameList.push("Raid Finder");}
return[new GearEffect(name,id,nameList)];}
function hasEnchant(items,id){if(items)
for(var i=0;i<items.length;i++)
if(items[i].enchant==id)
return true;return false;}
function getEffects(items){var effects=[];effects=effects.concat(hasTyrandeDoll(items));effects=effects.concat(hasAncientJar(items));effects=effects.concat(hasVibrantStone(items));effects=effects.concat(hasShardOfWoe(items));effects=effects.concat(hasT11(items));effects=effects.concat(hasT12(items));effects=effects.concat(hasT13(items));effects=effects.concat(hasMetagem(items));effects=effects.concat(hasAstralLeather(items));effects=effects.concat(hasMandala(items));effects=effects.concat(hasRuneOfZeth(items));effects=effects.concat(hasFieryQ(items));effects=effects.concat(hasPPEgg(items));effects=effects.concat(hasWitchHG(items));effects=effects.concat(hasEyeBP(items));effects=effects.concat(hasRainsong(items));effects=effects.concat(hasWindwardH(items));effects=effects.concat(hasSeal7(items));effects=effects.concat(hasTitahk(items));effects=effects.concat(hasPowerTorrent(items));effects=effects.concat(hasHurricane(items));var effectsList=[];for(var i=0;i<effects.length;i++)
effectsList[effects[i].name]=effects[i];return effectsList;}
function loadGear(data){var gItems=new Array();var i=0;for(var index in data.items){var item=data.items[index];if(item.id){var gItem=new GearItem();gItem.load(index,item);gItems[i++]=gItem;}}
return new Gear(gItems);}
function HPET(name,healing,healingHarm,HPM,HPMHarm,usesMastery){this.name=name;this.healing=healing;this.healingHarm=healingHarm;this.HPM=HPM;this.HPMHarm=HPMHarm;this.usesMastery=usesMastery;this.intellect=0;this.haste=0;this.crit=0;this.mastery=0;this.index=-1;}
HPET.prototype.toString=function(){return this.name+":"+this.healing+"; "+this.MP5;};function SpellCalcs(character,extraMode){this.character=character;this.extraMode=extraMode;}
SpellCalcs._specials={};SpellCalcs.prototype.getBuffValue=function(buffName){return this.character.buffs[buffName].value;};SpellCalcs.prototype.getEffect=function(effectName){return this.character.gear.effects[effectName];};SpellCalcs.prototype.getEffectValue=function(effectName){var effect=this.getEffect(effectName);return(effect)?effect.value:0;};SpellCalcs.prototype.getTalent=function(talentName){return this.character.getCurrentSpec().talents[talentName];};SpellCalcs.prototype.getTalentPoints=function(talentName){return this.getTalent(talentName).points;};SpellCalcs.prototype.general=function(){this.RaidSpellHaste=(this.getBuffValue("RaidSpellHaste")==1)?0.05:0;this.RaidSpellCrit=(this.getBuffValue("RaidAllCrit")!=0)?0.05:0;this.RaidAllStats=(this.getBuffValue("RaidAllStats")==1)?0.05:0;this.RaidMana=(this.getBuffValue("RaidMana")==1)?2126:0;this.RaidMP5=(this.getBuffValue("RaidMP5")==1)?326:0;this.RaidSpellPower=this.getBuffValue("RaidSpellpower");this.AstralLeather=(this.getEffectValue("AstralLeather"))?0.05:0;this.Bloodlust=(this.getBuffValue("BloodlustHeroism")==1)?1.3:1;};SpellCalcs.prototype.basic=function(){var bc=new Object();var HotW=this.getTalentPoints("HotW");var metagem=this.getEffectValue("Metagem");var battleElixirBuff=this.getBuffValue("BattleElixir");var foodBuff=this.getBuffValue("Food");var food=0,battleElixir=0,guardianElixir=0,meta=0;bc.NGMult=1+this.getTalentPoints("NaturesGrace")*0.05;bc.MoonglowMult=(1-0.03*this.getTalentPoints("Moonglow"));bc.ShardSave=this.getEffectValue("ShardOfWoe")?205:0;var ExtraSpirit=(this.extraMode=="Spirit")?1:0;if(battleElixirBuff==1){battleElixir=this.character.stats.isAlchemist()?380:300;}
else
if(battleElixirBuff==5)
battleElixir=225;else
battleElixir=0;food=(foodBuff==2)?90:0;var spiritBonus=(this.getEffectValue("T11Set4")&&this.character.spellUsage.RollLB)?540*this.character.spellUsage.HarmUptime/100:0;bc.TotalSpi=this.character.stats.spirit+ExtraSpirit+food+battleElixir+spiritBonus+this.getBuffValue("MTTShamansSpirit")*2*12/180*1.4;var ExtraInt=(this.extraMode=="Intellect")?1:0;var ExtraAstral=(this.extraMode!="Astral")?0.05:0;var ExtraHotW=(this.extraMode=="HotW")?HotW*(-1):0;battleElixir=(battleElixirBuff==2)?(this.character.stats.isAlchemist()?380:300):0;food=(foodBuff==1)?90:0;bc.StartInt=(this.character.stats.intellect+ExtraInt+battleElixir+food)*(1+this.RaidAllStats)*(1+0.02*(HotW+ExtraHotW))*(1+ExtraAstral);var meanInt=(this.getEffectValue("Mandala"))?1926*10/50:0;if(this.getEffectValue("RuneZeth")==2)
meanInt+=1441*15/60;if(this.getEffectValue("RuneZeth")==1)
meanInt+=1277*15/60;if(this.getEffectValue("FieryQ")==1)
meanInt+=1149*25/90;if(this.getEffectValue("FieryQ")==2)
meanInt+=1297*25/90;if(this.getEffectValue("PowerTorrent"))
meanInt+=500*12/50;bc.TotalInt=(this.character.stats.intellect+meanInt+ExtraInt+battleElixir+food)*(1+this.RaidAllStats)*(1+0.02*(HotW+ExtraHotW))*(1+ExtraAstral);bc.BaseMana=18635;bc.RatingMult=12.8057006835937;bc.OoCChance=0;var furor=this.getTalentPoints("Furor");var ExtraFuror=(this.extraMode=="Furor")?furor*(-1):0;meta=(metagem==1)?0.02:0;bc.TotalMana=(bc.BaseMana-280+bc.StartInt*15+this.RaidMana)*(1+0.05*(furor+ExtraFuror))*(1+meta);bc.MeanMana=(bc.BaseMana-280+bc.TotalInt*15+this.RaidMana)*(1+0.05*(furor+ExtraFuror))*(1+meta);bc.RepMPS=bc.MeanMana*0.001;bc.RevitProc=bc.MeanMana*0.01*this.getTalentPoints("Revitalize");meanInt=(this.getEffectValue("Mandala"))?1926*10/50:0;if(this.getEffectValue("RuneZeth")==2)
meanInt+=1441;if(this.getEffectValue("RuneZeth")==1)
meanInt+=1277;if(this.getEffectValue("FieryQ")==1)
meanInt+=1149;if(this.getEffectValue("FieryQ")==2)
meanInt+=1297;if(this.getEffectValue("PowerTorrent"))
meanInt+=500*12/50;var innervateInt=(this.character.stats.intellect+meanInt+ExtraInt+battleElixir+food)*(1+this.RaidAllStats)*(1+0.02*(HotW+ExtraHotW))*(1+ExtraAstral);var innervateMana=(bc.BaseMana-280+innervateInt*15+this.RaidMana)*(1+0.05*(furor+ExtraFuror))*(1+meta);bc.InnervateMana=innervateMana*(((this.getBuffValue("InnervateTo")==1||this.getBuffValue("InnervateTo")==3)?0.2:0)+
((this.character.getCurrentSpec().hasGlyphOfInnervate()&&(this.getBuffValue("InnervateTo")==2||this.getBuffValue("InnervateTo")==3))?0.1:0));bc.PotMana=0;if(this.getBuffValue("Potion")==1)
bc.PotMana=10000;else
if(this.getBuffValue("Potion")==2)
bc.PotMana=22000*(this.getEffectValue("VibrantStone")?1.4:1);bc.UsableMana=bc.TotalMana+bc.PotMana;var ExtraSP=(this.extraMode=="SP")?1:0;bc.TrueSpellpower=this.character.stats.spellPower-this.character.stats.intellect+ExtraSP;bc.TotalSP=(bc.TrueSpellpower+bc.TotalInt)*(1+this.RaidSpellPower);bc.HealMult=1+0.04*this.getTalentPoints("MasterShapeshifter");food=(foodBuff==4)?90:0;battleElixir=(battleElixirBuff==4)?225:0;bc.HasteFromGear=this.character.stats.spellHaste+food+battleElixir;bc.BuffHaste=(1+this.RaidSpellHaste)*(1+this.getBuffValue("DarkIntent")*0.03)-1;var berserking=(this.getBuffValue("RacialEffect")==2?10:0);var bloodlust=0;if(this.getBuffValue("BloodlustHeroism")==1)
bloodlust=40;if(this.getBuffValue("BloodlustHeroism")==2)
bloodlust=600;var trinketParams=[[0,0,0],[0,0,0]];var tIndex=0;if(this.getEffectValue("ShardOfWoe")&&SpellCalcs._specials.effect!="ShardOfWoe"){trinketParams[tIndex][0]=1935;trinketParams[tIndex][1]=10;trinketParams[tIndex][2]=60;tIndex++;}
if(this.getEffectValue("PPEgg")&&SpellCalcs._specials.effect!="PPEgg"){trinketParams[tIndex][0]=2040;trinketParams[tIndex][1]=10;trinketParams[tIndex][2]=50;tIndex++;}
if(this.getEffectValue("WitchHG")==1&&SpellCalcs._specials.effect!="WitchHG"){trinketParams[tIndex][0]=918;trinketParams[tIndex][1]=15;trinketParams[tIndex][2]=50;tIndex++;}
if(this.getEffectValue("Rainsong")==1&&SpellCalcs._specials.effect!="Rainsong"){trinketParams[tIndex][0]=1290;trinketParams[tIndex][1]=15;trinketParams[tIndex][2]=75;tIndex++;}
if(this.getEffectValue("Seal7")==1&&SpellCalcs._specials.effect!="WindwardH"){trinketParams[tIndex][0]=2904;trinketParams[tIndex][1]=20;trinketParams[tIndex][2]=100;tIndex++;}
if(this.getEffectValue("Seal7")==2&&SpellCalcs._specials.effect!="WindwardH"){trinketParams[tIndex][0]=3278;trinketParams[tIndex][1]=20;trinketParams[tIndex][2]=100;tIndex++;}
if(this.getEffectValue("Seal7")==3&&SpellCalcs._specials.effect!="WindwardH"){trinketParams[tIndex][0]=2573;trinketParams[tIndex][1]=20;trinketParams[tIndex][2]=100;tIndex++;}
if((this.getEffectValue("WitchHG")==2&&SpellCalcs._specials.effect!="WitchHG")||(this.getEffectValue("Rainsong")==2&&SpellCalcs._specials.effect!="Rainsong")){trinketParams[tIndex][0]=1710;trinketParams[tIndex][1]=15;trinketParams[tIndex][2]=75;}
var hasteParams=[[0.2,0,berserking,180,0],[0.3,0,bloodlust,600,0],[0,450,(this.getEffectValue("Hurricane")?12:0),60,0],[0,trinketParams[0][0],trinketParams[0][1],trinketParams[0][2],0],[0,trinketParams[1][0],trinketParams[1][1],trinketParams[1][2],0],[this.getTalentPoints("NaturesGrace")*0.05,0,15,this.character.spellUsage.NGProcsTime,0]];switch(this.getEffectValue("Titahk")){case 1:hasteParams[2]=[0,1928,10,45];break;case 2:hasteParams[2]=[0,2175,10,45];break;case 3:hasteParams[2]=[0,1707,10,45];break;}
var hasteTotal1=0;var hasteTotal2=1;for(i=0;i<hasteParams.length;i++){hasteParams[i][4]=(hasteParams[i][3]!=0)?hasteParams[i][2]/hasteParams[i][3]:0;if(i==hasteParams.length-1)
continue;hasteTotal1+=hasteParams[i][1]*hasteParams[i][4];hasteTotal2*=1+hasteParams[i][0]*hasteParams[i][4];}
bc.hasteParams=hasteParams;bc.NGUptime=hasteParams[hasteParams.length-1][4];bc.TotalHaste=(1+(bc.HasteFromGear+hasteTotal1)/1000/bc.RatingMult)*(1+bc.BuffHaste)*hasteTotal2-1;bc.rjTicks=12;bc.wgTicks=7;bc.rgTicks=6;bc.lbTicks=10;function SpellHaste(counter,calc){this.counter=counter;this.percents=1;var haste=0;var rating=1;for(var i=0;i<counter.length;i++){this.percents*=(counter[i])?calc.hasteParams[i][4]:1-calc.hasteParams[i][4];haste+=calc.hasteParams[i][1]*counter[i];rating*=(1+counter[i]*calc.hasteParams[i][0]);}
this.haste=(1+(calc.HasteFromGear+haste)/1000/calc.RatingMult)*(1+calc.BuffHaste)*rating-1;this.rtRate=Math.roundNumber(3/(1+this.haste),3);this.rtTicks=Math.ceil(calc.rjTicks/this.rtRate-0.5);this.weRate=Math.roundNumber(1/(1+this.haste),3);this.weTicks=Math.ceil(calc.wgTicks/this.weRate-0.5);this.rRate=Math.roundNumber(2/(1+this.haste),3);this.rTicks=Math.ceil(calc.rgTicks/this.rRate-0.5);this.lTicks=Math.ceil(calc.lbTicks/this.weRate-0.5);this.lDur=this.weRate*this.lTicks;}
bc.spellsHaste=0;bc.rtRate=0;bc.rtTicks=0;bc.weRate=0;bc.weTicks=0;bc.rRate=0;bc.rTicks=0;bc.lTicks=0;bc.lDur=0;for(i=0;i<64;i++){var test=1;var counter=new Array(hasteParams.length);for(var j=1;j<=counter.length;j++){counter[j-1]=(i&test)?1:0;test=test<<1;}
spellsHaste=new SpellHaste(counter,bc);bc.spellsHaste+=spellsHaste.percents*spellsHaste.haste;bc.rtRate+=spellsHaste.percents*spellsHaste.rtRate;bc.rtTicks+=spellsHaste.percents*spellsHaste.rtTicks;bc.weRate+=spellsHaste.percents*spellsHaste.weRate;bc.weTicks+=spellsHaste.percents*spellsHaste.weTicks;bc.rRate+=spellsHaste.percents*spellsHaste.rRate;bc.rTicks+=spellsHaste.percents*spellsHaste.rTicks;bc.lTicks+=spellsHaste.percents*spellsHaste.lTicks;bc.lDur+=spellsHaste.percents*spellsHaste.lDur;}
bc.GCD=1.5/(1+bc.TotalHaste);bc.InstantCast=Math.max(bc.GCD,1)+this.character.stats.instantDelay;bc.NGGCD=Math.max(bc.GCD/(1+this.getTalentPoints("NaturesGrace")*0.05),1);bc.InstantCastNG=bc.NGGCD+this.character.stats.instantDelay;bc.InstantSpam=bc.InstantCastNG*bc.NGUptime+bc.InstantCast*(1-bc.NGUptime);var baseRegen=bc.BaseMana*0.05;var regenSpirit=0.5*(0.001+bc.TotalSpi*0.00334500009194*Math.sqrt(bc.TotalInt))*5;var regenFromGear=(this.getEffectValue("TyrandeDoll")?4200/60*5:0)+(this.getEffectValue("AncientJar")==1?6420/120*5:0)+
(this.getEffectValue("AncientJar")==2?7260/120*5:0);var regenBuffs=this.RaidMP5+regenFromGear;var regenReplenish=bc.RepMPS*this.getBuffValue("ReplenishmentUptime")/100*5;var regenInnervate=bc.InnervateMana/180*5;bc.TotalRegen=baseRegen+regenSpirit+regenBuffs+regenReplenish+regenInnervate;food=(foodBuff==3)?90:0;battleElixir=(battleElixirBuff==6)?225:0;bc.BaseCrit=this.character.stats.spellCrit+food+battleElixir;var critFromRating=bc.BaseCrit/(1400*bc.RatingMult);var critFromInt=0.018515000119805+bc.TotalInt*0.000015410500055;var critFromBuffs=this.RaidSpellCrit+((this.getBuffValue("FocusMagic")==1)?0.03:0)+this.getTalentPoints("NaturesMajesty")*0.02+
(this.getBuffValue("RacialEffect")==1?0.01:0);bc.TotalCrit=critFromRating+critFromInt+critFromBuffs;meta=(metagem==2)?1.03:1;bc.CritBonus=2*meta;food=(foodBuff==5)?90:0;battleElixir=(battleElixirBuff==3)?225:0;bc.MasteryRating=this.character.stats.mastery+food+battleElixir;bc.HarmMastery=(8+bc.MasteryRating/(bc.RatingMult*14))*0.0125;bc.EffloBonus=(this.getEffectValue("T12Set4"))?1+bc.HealMult*(1+bc.TotalCrit*(bc.CritBonus-1)):1;bc.TreeBonus=1.15;bc.TreeUptime=(this.getTalentPoints("ToL")&&this.character.spellUsage.TLonCD)?(25+3*this.getTalentPoints("NaturalShapeshifter"))/180:0;bc.T132Bonus=1-((this.getEffectValue("T13Set2"))?15/180*0.25:0);bc.T134Bonus=this.getEffectValue("T13Set4")?1.1:1;bc.EyeBP=0;if(this.getEffectValue("EyeBP")==2)
bc.EyeBP=(15810+18373)/2/45;if(this.getEffectValue("EyeBP")==1)
bc.EyeBP=(13984+16251)/2/45;bc.EyeBP*=(1+bc.TotalCrit*(bc.CritBonus-1))*bc.HealMult*(1+(bc.TreeBonus-1)*bc.TreeUptime);return bc;};SpellCalcs.prototype.genericHot=function(target){if(!target.AddBonus)
target.AddBonus=1.25+0.02*this.getTalentPoints("Genesis");if(!target.TickHeal)
target.TickHeal=(target.BaseHealPerTick+target.CoefficientPerTick*this.basicCalc.TotalSP)*this.basicCalc.HealMult*target.AddBonus;if(target.CritChance==null)
target.CritChance=this.basicCalc.TotalCrit;target.AvgHeal=target.CritChance*target.TickHeal*this.basicCalc.CritBonus+target.TickHeal*(1-target.CritChance);target.BaseMana=Math.floor(target.ManaCostPercent*this.basicCalc.BaseMana);target.ManaCost=Math.floor((target.BaseMana-this.basicCalc.ShardSave)*this.basicCalc.MoonglowMult*this.basicCalc.T132Bonus);if(!target.CastTime){target.CastTime=this.basicCalc.InstantCast;target.CastTimeNG=this.basicCalc.InstantCastNG;target.CastTimeMean=this.basicCalc.InstantSpam;}
else
target.CastTimeMean=target.CastTimeNG*this.basicCalc.NGUptime+target.CastTime*(1-this.basicCalc.NGUptime);target.MeanHealing=target.AvgHeal*target.MeanTicks+((target.ProcPerCast)?target.ProcPerCast:0);target.MeanHealingHarm=target.MeanHealing*(target.AddBonus+this.basicCalc.HarmMastery)/target.AddBonus;};SpellCalcs.prototype.rejuv=function(){var rj=new Object();rj.CastTime=Math.max((1.5-this.getTalentPoints("SwiftRejuv")*0.5)/(1+this.basicCalc.TotalHaste),1)+this.character.stats.instantDelay;rj.CastTimeNG=Math.max((1.5-this.getTalentPoints("SwiftRejuv")*0.5)/(1+this.basicCalc.TotalHaste)/this.basicCalc.NGMult,1)+this.character.stats.instantDelay;rj.BaseHealPerTick=1307;rj.CoefficientPerTick=0.134;rj.ManaCostPercent=0.2;rj.PreHasteDuration=this.basicCalc.rjTicks;rj.AddBonus=1.25+0.05*this.getTalentPoints("ImprovedRejuvenation")+(this.character.getCurrentSpec().hasGlyphOfRejuvenation()?0.1:0)+
0.02*this.getTalentPoints("BotG")+0.02*this.getTalentPoints("Genesis");rj.TickHeal=(rj.BaseHealPerTick+rj.CoefficientPerTick*this.basicCalc.TotalSP)*this.basicCalc.HealMult*rj.AddBonus;rj.MeanTicks=this.basicCalc.rtTicks*this.basicCalc.T134Bonus;var iRJMult=0;switch(this.getTalentPoints("ImprovedRejuvenation")){case 1:iRJMult=0.051;break;case 2:iRJMult=0.14;break;case 3:iRJMult=0.171;break;}
rj.ProcPerCast=this.getTalentPoints("GotE")*0.05*Math.floor(this.character.stats.spellHaste/(1000*this.basicCalc.RatingMult)/0.25+4.5)*(rj.BaseHealPerTick+rj.CoefficientPerTick*this.basicCalc.TotalSP)*this.basicCalc.HealMult*(1.25+(this.character.getCurrentSpec().hasGlyphOfRejuvenation()?0.1:0)+0.02*this.getTalentPoints("BotG")+iRJMult);this.genericHot(rj);rj.MeanHealingHarm=rj.AvgHeal*rj.MeanTicks*(rj.AddBonus+this.basicCalc.HarmMastery)/rj.AddBonus+rj.ProcPerCast;return rj;};SpellCalcs.prototype.wildgrowth=function(){var wg=new Object();wg.BaseHealPerTick=2975/7;wg.CoefficientPerTick=0.042*1.3*0.8;wg.ManaCostPercent=0.27;wg.PreHasteDuration=this.basicCalc.wgTicks;wg.MeanTicks=this.basicCalc.weTicks;this.genericHot(wg);wg.MeanHealing=wg.AvgHeal*wg.MeanTicks*(this.character.getCurrentSpec().hasGlyphOfWildGrowth()?6:5);wg.MeanHealingHarm=wg.MeanHealing*(wg.AddBonus+this.basicCalc.HarmMastery)/wg.AddBonus;return wg;};SpellCalcs.prototype.lifebloom=function(){var lb=new Object();lb.BaseHeal=1848;lb.Coefficient=0.355*0.8;lb.Heal=(lb.BaseHeal+lb.Coefficient*this.basicCalc.TotalSP)*this.basicCalc.HealMult*1.25*(1+0.02*this.getTalentPoints("Genesis")+0.05*this.getTalentPoints("GotE"));lb.CritChance=this.basicCalc.TotalCrit+((this.character.getCurrentSpec().hasGlyphOfLifebloom()?0.1:0));lb.AvgHealHarm=lb.Heal*lb.CritChance*this.basicCalc.CritBonus+lb.Heal*(1-lb.CritChance);lb.BaseHealPerTick=228;lb.CoefficientPerTick=0.0234;lb.ManaCostPercent=0.07;lb.PreHasteDuration=this.basicCalc.lbTicks;lb.MeanTicks=this.basicCalc.lTicks;lb.TickRate=this.basicCalc.weRate;if(this.getEffectValue("T11Set2"))
lb.CritChance+=0.05;this.genericHot(lb);lb.MeanHealing+=lb.AvgHealHarm;lb.MeanHealingHarm=lb.AvgHealHarm+lb.AvgHeal*lb.MeanTicks*(lb.AddBonus+this.basicCalc.HarmMastery)/lb.AddBonus;lb.MeanDuration=this.basicCalc.lDur;lb.tripleCast=3*(lb.AvgHealHarm+lb.AvgHeal*(lb.MeanTicks+1));lb.tripleCastHarm=3*(lb.AvgHealHarm+lb.AvgHeal*(lb.MeanTicks+1))*(lb.AddBonus+this.basicCalc.HarmMastery)/lb.AddBonus;lb.tripleSlow=3*(lb.AvgHealHarm+lb.AvgHeal*(2*lb.MeanTicks+2/3));lb.tripleSlowHarm=3*(lb.AvgHealHarm+lb.AvgHeal*(2*lb.MeanTicks+2/3))*(lb.AddBonus+this.basicCalc.HarmMastery)/lb.AddBonus;lb.rollingHP=3*(lb.AvgHeal*lb.MeanTicks);lb.rollingHPHarm=3*(lb.AvgHeal*lb.MeanTicks*(lb.AddBonus+this.basicCalc.HarmMastery)/lb.AddBonus);return lb;};SpellCalcs.prototype.regrowth=function(){var rg=new Object();rg.CastTime=Math.max(1.5/(1+this.basicCalc.TotalHaste)+this.character.stats.instantDelay,this.basicCalc.InstantCast);rg.CastTimeNG=Math.max(1.5/(1+this.basicCalc.TotalHaste)/this.basicCalc.NGMult+this.character.stats.instantDelay,this.basicCalc.InstantCastNG);rg.BaseHeal=(3383+3775)/2;rg.Coefficient=0.2936;rg.Heal=(rg.BaseHeal+rg.Coefficient*this.basicCalc.TotalSP)*this.basicCalc.HealMult*(1.25+0.05*this.getTalentPoints("EmpoweredTouch")+this.basicCalc.HarmMastery);rg.CritChance=this.basicCalc.TotalCrit+0.2*this.getTalentPoints("NaturesBounty");rg.AvgHealHarm=rg.Heal*rg.CritChance*this.basicCalc.CritBonus*(1+0.1*this.getTalentPoints("LivingSeed"))+rg.Heal*(1-rg.CritChance);rg.BaseHealPerTick=361;rg.CoefficientPerTick=0.0296;rg.ManaCostPercent=0.35;rg.PreHasteDuration=this.basicCalc.rgTicks;rg.MeanTicks=this.basicCalc.rTicks*this.basicCalc.T134Bonus;rg.AddBonus=1.25+0.02*this.getTalentPoints("Genesis")+this.basicCalc.HarmMastery;this.genericHot(rg);rg.MeanHealing+=rg.AvgHealHarm;rg.MeanHealingHarm=rg.MeanHealing;return rg;};SpellCalcs.prototype.tranquility=function(){var tq=new Object();var tranqTable={1:[9,0,0,1],2:[18,0,0,2],3:[27,0,0,3],4:[36,0,0,4],5:[45,0,0,5],6:[45,0,0,6],7:[43,0,1,6],8:[40,0,4,4],9:[40,0,7,2],10:[40,0,10,0],11:[36,2,9,0],12:[32,4,8,0],13:[29,6,7,0],14:[27,8,6,0],15:[25,10,5,0],16:[24,12,4,0],17:[23,14,3,0],18:[22,16,2,0],19:[21,18,1,0],20:[20,20,0,0]};tq.CastTime=Math.max(8/(1+this.basicCalc.TotalHaste)+this.character.stats.instantDelay,this.basicCalc.InstantCast);tq.CastTimeNG=Math.max(8/(1+this.basicCalc.TotalHaste)/this.basicCalc.NGMult+this.character.stats.instantDelay,this.basicCalc.InstantCastNG);tq.BaseHeal=3882;tq.Coefficient=0.398;tq.Heal=(tq.BaseHeal+tq.Coefficient*this.basicCalc.TotalSP)*this.basicCalc.HealMult*1.25;tq.CritChance=this.basicCalc.TotalCrit;tq.AvgHealHarm=tq.Heal*tq.CritChance*this.basicCalc.CritBonus+tq.Heal*(1-tq.CritChance);tq.BaseHealPerTick=343;tq.CoefficientPerTick=0.068;tq.ManaCostPercent=0.32;tq.PreHasteDuration=8;tq.MeanTicks=this.basicCalc.rtTicks;tq.CritChance=0;this.genericHot(tq);var tranqRow=tranqTable[this.character.spellUsage.TranqTargets];var tranqTicks=(tranqRow)?(tranqRow[0]+tranqRow[1]*(tq.MeanTicks-1)+tq.MeanTicks*(tranqRow[2]*2+tranqRow[3]*3)):0;tq.MeanHealing=tq.AvgHealHarm*Math.min(this.character.spellUsage.TranqTargets,4)+tq.AvgHeal*tranqTicks;tq.MeanHealingHarm=tq.MeanHealing*(tq.AddBonus+this.basicCalc.HarmMastery)/tq.AddBonus;return tq;};SpellCalcs.prototype.nourish=function(){var nr=new Object();nr.BaseHeal=(2403+2791)/2;nr.Coefficient=0.266;nr.ProcPerCast=0;nr.Heal=(nr.BaseHeal+nr.Coefficient*this.basicCalc.TotalSP)*this.basicCalc.HealMult*(1.25+0.05*this.getTalentPoints("EmpoweredTouch")+this.basicCalc.HarmMastery)*1.2;nr.CritChance=this.basicCalc.TotalCrit;nr.AvgHeal=nr.Heal*nr.CritChance*this.basicCalc.CritBonus*(1+0.1*this.getTalentPoints("LivingSeed"))+nr.Heal*(1-nr.CritChance)+nr.ProcPerCast;nr.BaseCastTime=3-0.25*this.getTalentPoints("Naturalist");nr.CastTime=Math.max(nr.BaseCastTime/(1+this.basicCalc.TotalHaste)+this.character.stats.instantDelay,this.basicCalc.InstantCast);nr.CastTimeNG=Math.max(nr.BaseCastTime/(1+this.basicCalc.TotalHaste)/this.basicCalc.NGMult+this.character.stats.instantDelay,this.basicCalc.InstantCast);nr.CastTimeMean=this.basicCalc.NGUptime*nr.CastTimeNG+(1-this.basicCalc.NGUptime)*nr.CastTime;nr.BaseManaCost=Math.floor(this.basicCalc.BaseMana*0.1);nr.ManaCost=Math.floor((nr.BaseManaCost-this.basicCalc.ShardSave)*this.basicCalc.MoonglowMult*this.basicCalc.T132Bonus);return nr;};SpellCalcs.prototype.healingtouch=function(){var ht=new Object();ht.BaseHeal=(7211+8515)/2;ht.Coefficient=0.806;ht.ProcPerCast=0;ht.Heal=(ht.BaseHeal+ht.Coefficient*this.basicCalc.TotalSP)*this.basicCalc.HealMult*(1.25+0.05*this.getTalentPoints("EmpoweredTouch")+this.basicCalc.HarmMastery);ht.CritChance=this.basicCalc.TotalCrit;ht.AvgHeal=ht.Heal*ht.CritChance*this.basicCalc.CritBonus*(1+0.1*this.getTalentPoints("LivingSeed"))+ht.Heal*(1-ht.CritChance)+ht.ProcPerCast;ht.BaseCastTime=3-0.25*this.getTalentPoints("Naturalist");ht.CastTime=Math.max(ht.BaseCastTime/(1+this.basicCalc.TotalHaste)+this.character.stats.instantDelay,this.basicCalc.InstantCast);ht.CastTimeNG=Math.max(ht.BaseCastTime/(1+this.basicCalc.TotalHaste)/this.basicCalc.NGMult+this.character.stats.instantDelay,this.basicCalc.InstantCast);ht.CastTimeMean=this.basicCalc.NGUptime*ht.CastTimeNG+(1-this.basicCalc.NGUptime)*ht.CastTime;ht.BaseManaCost=Math.floor(this.basicCalc.BaseMana*0.3);ht.ManaCost=Math.floor((ht.BaseManaCost-this.basicCalc.ShardSave)*this.basicCalc.MoonglowMult*this.basicCalc.T132Bonus);return ht;};SpellCalcs.prototype.swiftmend=function(){var sm=new Object();sm.BaseHeal=5228;sm.Coefficient=0.536;sm.ProcPerCast=0;sm.Heal=(sm.BaseHeal+sm.Coefficient*this.basicCalc.TotalSP)*this.basicCalc.HealMult*(1.25+0.05*this.getTalentPoints("ImprovedRejuvenation")+0.02*this.getTalentPoints("Genesis")+this.basicCalc.HarmMastery);sm.CritChance=this.basicCalc.TotalCrit;sm.AvgHeal=(sm.Heal*sm.CritChance*this.basicCalc.CritBonus*(1+0.1*this.getTalentPoints("LivingSeed"))+sm.Heal*(1-sm.CritChance))+sm.ProcPerCast;sm.AvgHealHarm=sm.AvgHeal;sm.CastTime=this.basicCalc.InstantCast;sm.CastTimeNG=this.basicCalc.InstantCastNG;sm.CastTimeMean=this.basicCalc.InstantSpam;sm.BaseManaCost=Math.floor(this.basicCalc.BaseMana*0.1);sm.ManaCost=Math.floor((sm.BaseManaCost-this.basicCalc.ShardSave)*this.basicCalc.MoonglowMult*this.basicCalc.T132Bonus);sm.Efflo=(sm.Heal*sm.CritChance*this.basicCalc.CritBonus+sm.Heal*(1-sm.CritChance))*0.04*this.getTalentPoints("Efflorescence")*this.basicCalc.weTicks*Math.min(this.character.spellUsage.EffHits,3)*this.basicCalc.HealMult*(1+this.basicCalc.HarmMastery);return sm;};SpellCalcs.prototype.getHPET=function(){function getHPETHot(name,calc,usesMastery){if(usesMastery===undefined)
usesMastery=true;return new HPET(name,calc.MeanHealing/calc.CastTimeMean,calc.MeanHealingHarm/calc.CastTimeMean,(calc.ManaCost)?calc.MeanHealing/calc.ManaCost:0,(calc.ManaCost)?calc.MeanHealingHarm/calc.ManaCost:0,usesMastery);}
function getHPETHeal(name,calc){return new HPET(name,calc.AvgHeal/calc.CastTimeMean,0,calc.AvgHeal/calc.ManaCost,0);}
var hpet=new Object();if(this.rejuvCalc)
hpet.rejuv=getHPETHot("Rejuvenation",this.rejuvCalc);if(this.regrowthCalc){hpet.rg=getHPETHot("Regrowth",this.regrowthCalc,false);hpet.rg.healingHarm=0;hpet.rg.HPMHarm=0;}
if(this.wgCalc)
hpet.wg=getHPETHot("Wild Growth",this.wgCalc);if(this.tranquilityCalc)
hpet.tranq=getHPETHot("Tranquility",this.tranquilityCalc);if(this.lifebloomCalc){hpet.lbs=getHPETHot("Lifebloom, Single",this.lifebloomCalc);hpet.lbs3=new HPET("Lifebloom, Slowroll to 3",this.lifebloomCalc.tripleSlow/this.lifebloomCalc.CastTimeMean/3,this.lifebloomCalc.tripleSlowHarm/this.lifebloomCalc.CastTimeMean/3,this.lifebloomCalc.tripleSlow/this.lifebloomCalc.ManaCost/3,this.lifebloomCalc.tripleSlowHarm/this.lifebloomCalc.ManaCost/3,true);hpet.lbsr=new HPET("Lifebloom, Rolling",this.lifebloomCalc.rollingHP/this.lifebloomCalc.CastTimeMean,this.lifebloomCalc.rollingHPHarm/this.lifebloomCalc.CastTimeMean,this.lifebloomCalc.rollingHP/this.lifebloomCalc.ManaCost,this.lifebloomCalc.rollingHPHarm/this.lifebloomCalc.ManaCost,true);}
if(this.nourishCalc)
hpet.nc=getHPETHeal("Nourish",this.nourishCalc);if(this.htCalc)
hpet.ht=getHPETHeal("Healing Touch",this.htCalc);if(this.smCalc){hpet.smDirect=getHPETHeal("Swiftmend Direct",this.smCalc);hpet.smDirect.healing*=this.basicCalc.EffloBonus;hpet.smDirect.HPM*=this.basicCalc.EffloBonus;hpet.smEfflo=new HPET("Swiftmend Efflorescence",this.smCalc.Efflo/this.smCalc.CastTimeMean,0,this.smCalc.Efflo/this.smCalc.ManaCost,0);hpet.sm=new HPET("Swiftmend",hpet.smDirect.healing+hpet.smEfflo.healing,0,hpet.smDirect.HPM+hpet.smEfflo.HPM,0);}
var index=0;for(var h in hpet)
hpet[h].index=index++;return hpet;};SpellCalcs.prototype.whatIfHPET=function(){var ifcalc=new SpellCalcs(this.character);var s={"allSpells":true,"HPET":true,"whatIf":false};ifcalc.extraMode="Intellect";ifcalc.run(s);var ifInt=ifcalc.HPETCalc;ifcalc.extraMode=null;var origHaste=this.character.stats.spellHaste;this.character.stats.spellHaste=this.character.stats.spellHaste+10*this.basicCalc.RatingMult;ifcalc.run(s);var ifHaste=ifcalc.HPETCalc;this.character.stats.spellHaste=origHaste;this.character.stats.spellCrit++;ifcalc.run(s);var ifCrit=ifcalc.HPETCalc;this.character.stats.spellCrit--;this.character.stats.mastery++;ifcalc.run(s);var ifMast=ifcalc.HPETCalc;this.character.stats.mastery--;var mastery=1-this.character.spellUsage.HarmUptime/100;for(var i in this.HPETCalc){var baseHeal=(this.HPETCalc[i].usesMastery)?this.HPETCalc[i].healing*mastery+this.HPETCalc[i].healingHarm*(1-mastery):this.HPETCalc[i].healing;this.HPETCalc[i].intellect=((this.HPETCalc[i].usesMastery)?(ifInt[i].healing*mastery+ifInt[i].healingHarm*(1-mastery)):ifInt[i].healing)-baseHeal;this.HPETCalc[i].haste=((this.HPETCalc[i].usesMastery)?(ifHaste[i].healing*mastery+ifHaste[i].healingHarm*(1-mastery)):ifHaste[i].healing)-baseHeal;this.HPETCalc[i].haste/=(10*this.basicCalc.RatingMult);this.HPETCalc[i].crit=((this.HPETCalc[i].usesMastery)?(ifCrit[i].healing*mastery+ifCrit[i].healingHarm*(1-mastery)):ifCrit[i].healing)-baseHeal;this.HPETCalc[i].mastery=((this.HPETCalc[i].usesMastery)?(ifMast[i].healing*mastery+ifMast[i].healingHarm*(1-mastery)):ifMast[i].healing)-baseHeal;}};SpellCalcs.prototype.getHasteInfo=function(){var currentHaste=this.basicCalc.TotalHaste*1000*this.basicCalc.RatingMult;var cap=(1.5/(this.basicCalc.BuffHaste+1)-1)*1000*this.basicCalc.RatingMult;var calc=this.basicCalc;var nextHaste=null;var nextName=null;var nextTicks=null;function hasteBP(div,value){return Math.ceil((div/((Math.ceilNumber(value,3)-0.0005)*(1+calc.BuffHaste))-1)*1000*calc.RatingMult);}
function getHasteTicks(name,opts){var ticks=null;for(var o in opts){if(opts[o].value<currentHaste)
ticks=opts[o].ticks;else{if(!nextHaste||nextHaste>opts[o].value){nextHaste=opts[o].value;nextName=name;nextTicks=opts[o].ticks;}}}
return ticks;}
var lb=[{ticks:12,value:hasteBP(1,10/11.5)},{ticks:13,value:hasteBP(1,10/12.5)},{ticks:14,value:hasteBP(1,10/13.5)},{ticks:15,value:hasteBP(1,10/14.5)},{ticks:16,value:hasteBP(1,10/15.5)},{ticks:17,value:hasteBP(1,10/16.5)}];var rg=[{ticks:4,value:hasteBP(2,6/3.5)},{ticks:5,value:hasteBP(2,6/4.5)},{ticks:6,value:hasteBP(2,6/5.5)}];var wg=[{ticks:8,value:hasteBP(1,7/7.5)},{ticks:9,value:hasteBP(1,7/8.5)},{ticks:10,value:hasteBP(1,7/9.5)},{ticks:11,value:hasteBP(1,7/10.5)},{ticks:12,value:hasteBP(1,7/11.5)}];var rj=[{ticks:5,value:hasteBP(3,12/4.5)},{ticks:6,value:hasteBP(3,12/5.5)},{ticks:7,value:hasteBP(3,12/6.5)}];return{current:currentHaste,lb:getHasteTicks("LB",lb),rg:getHasteTicks("RG",rg),wg:getHasteTicks("WG",wg),rj:getHasteTicks("RJ",rj),cap:cap,next:(nextHaste>currentHaste)?nextHaste:null,nextName:nextName,nextTicks:nextTicks};};SpellCalcs.prototype.run=function(selector){this.general();this.basicCalc=this.basic();var allSpells=(!selector||selector.allSpells);if(allSpells||selector.Rejuvenation||selector.Nourish)
this.rejuvCalc=this.rejuv();if(allSpells||selector.WG)
this.wgCalc=this.wildgrowth();if(allSpells||selector.LB)
this.lifebloomCalc=this.lifebloom();if(allSpells||selector.RG)
this.regrowthCalc=this.regrowth();if(allSpells||selector.Tranquility)
this.tranquilityCalc=this.tranquility();if(allSpells||selector.Nourish)
this.nourishCalc=this.nourish();if(allSpells||selector.HT)
this.htCalc=this.healingtouch();if(allSpells||selector.SM)
this.smCalc=this.swiftmend();if(!selector||selector.HPET||selector.whatIf)
this.HPETCalc=this.getHPET();if(!selector||selector.whatIf)
this.whatIfHPET();};function Rotation(index){this.index=index;this.HPS=0;this.MP5=0;this.TimeToOOM=0;}
Rotation.prototype.toString=function(){return String(this.index)+":"+this.HPS+" ; "+this.MP5+" ; "+this.TimeToOOM;}
function RotationSpell(name,healing,MP5,castTimeRatio){this.name=name;this.healing=healing;this.MP5=MP5;this.castTimeRatio=(castTimeRatio!=null)?castTimeRatio:0;}
RotationSpell.prototype.toString=function(){return this.name+":"+this.healing+"; "+this.MP5;}
Rotation.prototype.calc=function(spellCalcs){var healing=0;var mp5=0;var castTimeRatio=0;var mastery=spellCalcs.character.spellUsage.HarmUptime/100;castTimeRatio=((spellCalcs.character.spellUsage.NourishTime>0||spellCalcs.character.spellUsage.RemainderSpell!=0)&&spellCalcs.getTalentPoints("EmpoweredTouch")>0)?0:(spellCalcs.character.spellUsage.RollLB?spellCalcs.lifebloomCalc.CastTimeMean/spellCalcs.lifebloomCalc.MeanDuration:0);if(spellCalcs.character.spellUsage.RollLB)
healing=(spellCalcs.lifebloomCalc.rollingHP*(1-mastery)+spellCalcs.lifebloomCalc.rollingHPHarm*mastery)/spellCalcs.lifebloomCalc.MeanDuration;else
healing=0;mp5=((spellCalcs.character.spellUsage.NourishTime>0||spellCalcs.character.spellUsage.RemainderSpell!=0)&&spellCalcs.getTalentPoints("EmpoweredTouch")>0)?0:(spellCalcs.character.spellUsage.RollLB?spellCalcs.lifebloomCalc.ManaCost/spellCalcs.lifebloomCalc.MeanDuration:0);mp5*=5;this.lifebloom=new RotationSpell("Lifebloom",healing,mp5,castTimeRatio);castTimeRatio=(spellCalcs.character.spellUsage.TranqTargets>0&&spellCalcs.character.spellUsage.TranqFreq>0)?spellCalcs.tranquilityCalc.CastTimeMean/spellCalcs.character.spellUsage.TranqFreq:0;if(castTimeRatio){healing=spellCalcs.tranquilityCalc.MeanHealingHarm/spellCalcs.character.spellUsage.TranqFreq;mp5=spellCalcs.tranquilityCalc.ManaCost/spellCalcs.character.spellUsage.TranqFreq/5;}
else{healing=0;mp5=0;}
this.tranquility=new RotationSpell("Tranquility",healing,mp5,castTimeRatio);var wgGlyph=(spellCalcs.character.getCurrentSpec().hasGlyphOfWildGrowth())?10:8;if(spellCalcs.character.spellUsage.WGonCD&&spellCalcs.getTalentPoints("WildGrowth")>0){castTimeRatio=spellCalcs.wgCalc.CastTimeMean/(wgGlyph+spellCalcs.basicCalc.InstantSpam/2);healing=(spellCalcs.wgCalc.MeanHealing*(1-mastery)+spellCalcs.wgCalc.MeanHealingHarm*mastery)/(wgGlyph+spellCalcs.basicCalc.InstantSpam/2);mp5=spellCalcs.wgCalc.ManaCost/(wgGlyph+spellCalcs.basicCalc.InstantSpam/2)*5;}
else{healing=0;castTimeRatio=0;mp5=0;}
this.wg=new RotationSpell("WG",healing,mp5,castTimeRatio);var effloHPS=0;if(spellCalcs.character.spellUsage.SMonCD){castTimeRatio=spellCalcs.smCalc.CastTimeMean/(15+spellCalcs.basicCalc.InstantSpam/2);healing=spellCalcs.smCalc.AvgHeal/(15+spellCalcs.basicCalc.InstantSpam/2);if(spellCalcs.getEffectValue("T12Set4"))
healing*=(1+spellCalcs.basicCalc.HealMult*(1+spellCalcs.basicCalc.TotalCrit*(spellCalcs.basicCalc.CritBonus-1)));effloHPS=spellCalcs.smCalc.Efflo/(15+spellCalcs.basicCalc.InstantSpam/2);mp5=spellCalcs.smCalc.ManaCost/(15+spellCalcs.basicCalc.InstantSpam/2)*5;}
else{healing=0;mp5=0;castTimeRatio=0;}
this.sm=new RotationSpell("SM",healing,mp5,castTimeRatio);this.sm.effloHPS=effloHPS;this.filler=new RotationSpell("Filler",0,0);healing=(spellCalcs.rejuvCalc.MeanHealing*(1-mastery)+spellCalcs.rejuvCalc.MeanHealingHarm*mastery)/spellCalcs.rejuvCalc.CastTimeMean;mp5=spellCalcs.rejuvCalc.ManaCost/spellCalcs.rejuvCalc.CastTimeMean*5;this.rejuv=new RotationSpell("Rejuv Spam",healing,mp5);if(spellCalcs.character.spellUsage.RemainderSpell==0){this.filler.healing=healing;this.filler.mp5=mp5;this.filler.castTime=spellCalcs.rejuvCalc.CastTimeMean;}
healing=(spellCalcs.htCalc.AvgHeal*(1-mastery)+spellCalcs.htCalc.AvgHeal*mastery)/spellCalcs.htCalc.CastTimeMean;mp5=spellCalcs.htCalc.ManaCost/spellCalcs.htCalc.CastTimeMean*5;this.ht=new RotationSpell("HT Spam",healing,mp5);if(spellCalcs.character.spellUsage.RemainderSpell==1){this.filler.healing=healing;this.filler.mp5=mp5;this.filler.castTime=spellCalcs.htCalc.CastTimeMean;}
healing=(spellCalcs.regrowthCalc.MeanHealing*(1-mastery)+spellCalcs.regrowthCalc.MeanHealingHarm*mastery)/spellCalcs.regrowthCalc.CastTimeMean;mp5=spellCalcs.regrowthCalc.ManaCost/spellCalcs.regrowthCalc.CastTimeMean*5;this.rg=new RotationSpell("RG Spam",healing,mp5);if(spellCalcs.character.spellUsage.RemainderSpell==2){this.filler.healing=healing;this.filler.mp5=mp5;this.filler.castTime=spellCalcs.regrowthCalc.CastTimeMean;}
var castRate=this.lifebloom.castTimeRatio/spellCalcs.lifebloomCalc.CastTimeMean+this.wg.castTimeRatio/spellCalcs.wgCalc.CastTimeMean+this.sm.castTimeRatio/spellCalcs.smCalc.CastTimeMean+
(1-this.lifebloom.castTimeRatio-this.wg.castTimeRatio-this.sm.castTimeRatio)*((1-spellCalcs.character.spellUsage.NourishTime/100)/this.filler.castTime+spellCalcs.character.spellUsage.NourishTime/100/spellCalcs.nourishCalc.CastTimeMean);var ccRate=castRate*spellCalcs.basicCalc.OoCChance+((spellCalcs.character.spellUsage.RollLB)?0.02*spellCalcs.getTalentPoints("MalfurionGift")/spellCalcs.lifebloomCalc.TickRate:0);var ccRGHTCastTimeRatio=ccRate*(spellCalcs.character.spellUsage.OnClearcasts==2?spellCalcs.regrowthCalc.CastTimeMean:spellCalcs.character.spellUsage.OnClearcasts==1?spellCalcs.htCalc.CastTimeMean:0);var ccRGHTHealing=ccRGHTCastTimeRatio*(spellCalcs.character.spellUsage.OnClearcasts==2?this.rg.healing:spellCalcs.character.spellUsage.OnClearcasts==1?this.ht.healing:0);var ccRGHTMP5=0;this.ccFiller=new RotationSpell("CC Filler",ccRGHTHealing,ccRGHTMP5,ccRGHTCastTimeRatio);var nourishCastTimeRatio=(1-this.lifebloom.castTimeRatio-this.tranquility.castTimeRatio-this.wg.castTimeRatio-this.sm.castTimeRatio-ccRGHTCastTimeRatio)*spellCalcs.character.spellUsage.NourishTime/100;this.filler.castTimeRatio=1-this.lifebloom.castTimeRatio-this.tranquility.castTimeRatio-this.wg.castTimeRatio-this.sm.castTimeRatio-ccRGHTCastTimeRatio-nourishCastTimeRatio;this.filler.HPS=this.filler.healing*this.filler.castTimeRatio;var fillerMP5=this.filler.mp5*this.filler.castTimeRatio;var concurrentRejuvs=(spellCalcs.character.spellUsage.RemainderSpell==0)?this.filler.castTimeRatio/spellCalcs.rejuvCalc.CastTimeMean*12:0;var nbUptime=Math.min(concurrentRejuvs/6,1);var effectiveNBHaste=(1/(1-0.1*spellCalcs.getTalentPoints("NaturesBounty"))-1)*nbUptime;healing=(spellCalcs.nourishCalc.AvgHeal*(1-mastery)+spellCalcs.nourishCalc.AvgHeal*mastery)/spellCalcs.nourishCalc.CastTimeMean*(1+effectiveNBHaste);mp5=spellCalcs.nourishCalc.ManaCost/spellCalcs.nourishCalc.CastTimeMean*5*(1+effectiveNBHaste);this.nourish=new RotationSpell("Nourish Spam",healing,mp5,nourishCastTimeRatio);this.nourish.HPS=healing*nourishCastTimeRatio;var nourishMP5=mp5*nourishCastTimeRatio;var lbTicksPerSec=1/spellCalcs.lifebloomCalc.TickRate;var rejuvTicksPerSec=(spellCalcs.character.spellUsage.RemainderSpell==0)?this.filler.castTimeRatio/spellCalcs.rejuvCalc.CastTimeMean*spellCalcs.rejuvCalc.MeanTicks:0;var revitProcTime=(spellCalcs.getTalentPoints("Revitalize")>0&&(lbTicksPerSec>0||rejuvTicksPerSec>0))?1/((lbTicksPerSec+rejuvTicksPerSec)*0.2)+12:0;var revitMP5=revitProcTime?1/revitProcTime*spellCalcs.basicCalc.RevitProc*5:0;var T12_2=(spellCalcs.getEffectValue("T12Set2"))?lbTicksPerSec*0.4*spellCalcs.basicCalc.BaseMana*0.01*5:0;var outTreeHPS=this.lifebloom.healing+this.tranquility.healing+this.wg.healing+this.sm.healing+effloHPS+ccRGHTHealing+this.nourish.HPS+this.filler.HPS;var outTreeMP5=this.lifebloom.MP5+this.tranquility.MP5+this.wg.MP5+this.sm.MP5+ccRGHTMP5+nourishMP5+fillerMP5-revitMP5-T12_2;var outTreeCastRate=this.lifebloom.castTimeRatio/spellCalcs.lifebloomCalc.CastTimeMean+this.wg.castTimeRatio/spellCalcs.wgCalc.CastTimeMean+
this.sm.castTimeRatio/spellCalcs.smCalc.CastTimeMean+
((spellCalcs.character.spellUsage.OnClearcasts==2)?ccRGHTCastTimeRatio/spellCalcs.regrowthCalc.CastTimeMean:0)+
((spellCalcs.character.spellUsage.OnClearcasts==1)?ccRGHTCastTimeRatio/spellCalcs.htCalc.CastTimeMean:0)+
(1-this.lifebloom.castTimeRatio-this.wg.castTimeRatio-this.sm.castTimeRatio-ccRGHTCastTimeRatio)*((1-spellCalcs.character.spellUsage.NourishTime/100)/this.filler.castTime+spellCalcs.character.spellUsage.NourishTime/100/spellCalcs.nourishCalc.CastTimeMean);var healingBonus=spellCalcs.basicCalc.TreeBonus;var treeUptime=spellCalcs.basicCalc.TreeUptime;healing=(spellCalcs.lifebloomCalc.MeanHealing*(1-mastery)+spellCalcs.lifebloomCalc.MeanHealingHarm*mastery)/spellCalcs.lifebloomCalc.CastTimeMean*healingBonus;mp5=spellCalcs.lifebloomCalc.ManaCost/spellCalcs.lifebloomCalc.CastTimeMean*5;this.lifebloomSpam=new RotationSpell("Lifebloom Spam",healing,mp5);castTimeRatio=spellCalcs.character.spellUsage.RollLB?spellCalcs.lifebloomCalc.CastTimeMean/spellCalcs.lifebloomCalc.MeanDuration:0;healing=this.lifebloom.healing*healingBonus;mp5=(spellCalcs.character.spellUsage.RollLB?spellCalcs.lifebloomCalc.ManaCost/spellCalcs.lifebloomCalc.MeanDuration:0)*5;this.lifebloomTank=new RotationSpell("Lifebloom Tank",healing,mp5,castTimeRatio);this.tranquilityTree=new RotationSpell("Tranquility Tree",this.tranquility.healing*healingBonus,this.tranquility.MP5,this.tranquility.castTimeRatio);if(spellCalcs.character.spellUsage.WGonCD&&spellCalcs.getTalentPoints("WildGrowth")>0){healing=(spellCalcs.wgCalc.MeanHealing*(1-mastery)+spellCalcs.wgCalc.MeanHealingHarm*mastery)/(wgGlyph+spellCalcs.basicCalc.InstantSpam/2)*(healingBonus*(spellCalcs.character.getCurrentSpec().hasGlyphOfWildGrowth()?8/6:7/5));}
else{healing=0;castTimeRatio=0;mp5=0;}
this.wgTree=new RotationSpell("WG Tree",healing,this.wg.MP5,this.wg.castTimeRatio);healing=this.sm.healing*healingBonus;effloHPS=this.sm.effloHPS*Math.pow(healingBonus,2);this.smTree=new RotationSpell("SM Tree",healing,this.sm.MP5,this.sm.castTimeRatio);this.smTree.effloHPS=effloHPS;var meanConcurrentLBs=4;ccRate=meanConcurrentLBs*0.02*spellCalcs.getTalentPoints("MalfurionGift")/spellCalcs.lifebloomCalc.TickRate;ccRGHTCastTimeRatio=ccRate*spellCalcs.basicCalc.InstantSpam;ccRGHTHealing=ccRGHTCastTimeRatio*(spellCalcs.regrowthCalc.MeanHealing*(1-mastery)+spellCalcs.regrowthCalc.MeanHealingHarm*mastery)/spellCalcs.basicCalc.InstantSpam*healingBonus;ccRGHTMP5=0;this.ccFillerTree=new RotationSpell("CC Filler Tree",ccRGHTHealing,ccRGHTMP5,ccRGHTCastTimeRatio);castTimeRatio=1-this.lifebloomTank.castTimeRatio-this.tranquilityTree.castTimeRatio-this.wgTree.castTimeRatio-this.smTree.castTimeRatio-ccRGHTCastTimeRatio;healing=this.lifebloomSpam.healing*castTimeRatio;mp5=this.lifebloomSpam.MP5*castTimeRatio;this.treeFiller=new RotationSpell("Tree Filler",healing,mp5,castTimeRatio);lbTicksPerSec=castTimeRatio/spellCalcs.lifebloomCalc.CastTimeMean*spellCalcs.lifebloomCalc.MeanTicks+(spellCalcs.character.spellUsage.RollLB?1/spellCalcs.lifebloomCalc.TickRate:0);revitProcTime=(spellCalcs.getTalentPoints("Revitalize")?1/(lbTicksPerSec*0.2)+12:0);revitMP5=revitProcTime?1/revitProcTime*spellCalcs.basicCalc.RevitProc*5:0;var inTreeHPS=this.lifebloomTank.healing+this.tranquilityTree.healing+this.wgTree.healing+this.smTree.healing+effloHPS+ccRGHTHealing+healing;var inTreeMP5=this.lifebloomTank.MP5+this.tranquilityTree.MP5+this.wgTree.MP5+this.smTree.MP5+ccRGHTMP5+mp5-revitMP5-T12_2;var inTreeCastRate=1/spellCalcs.basicCalc.InstantSpam;var windward=0;switch(spellCalcs.getEffectValue("WindwardH")){case 1:windward=spellCalcs.basicCalc.TotalSP*1.25+10388+12073;break;case 2:windward=spellCalcs.basicCalc.TotalSP*1.411+11726+13627;break;case 3:windward=spellCalcs.basicCalc.TotalSP*1.107+9203+10696;break;}
if(windward)
windward=(windward/2/20)*(1+spellCalcs.basicCalc.TotalCrit*(spellCalcs.basicCalc.CritBonus-1))*spellCalcs.basicCalc.HealMult*(1+(healingBonus-1)*treeUptime);this.HPS=outTreeHPS*(1-treeUptime)+inTreeHPS*treeUptime+spellCalcs.basicCalc.EyeBP+windward;this.MP5=outTreeMP5*(1-treeUptime)+inTreeMP5*treeUptime;this.MP5=-this.MP5+spellCalcs.basicCalc.TotalRegen;this.CastRate=outTreeCastRate*(1-treeUptime)+inTreeCastRate*treeUptime;this.TimeToOOM=(this.MP5<0)?-spellCalcs.basicCalc.UsableMana/this.MP5*5:"Never";this.filler.percentage=this.filler.HPS/this.HPS*(1-treeUptime);this.filler.time=this.filler.castTimeRatio*(1-treeUptime);this.nourish.percentage=this.nourish.HPS/this.HPS*(1-treeUptime);this.nourish.time=this.nourish.castTimeRatio*(1-treeUptime);this.lifebloom.percentage=this.lifebloom.healing/this.HPS*(1-treeUptime)+this.lifebloomTank.healing/this.HPS*treeUptime;this.lifebloom.time=this.lifebloom.castTimeRatio*(1-treeUptime)+this.lifebloomTank.castTimeRatio*treeUptime;this.wg.percentage=this.wg.healing/this.HPS*(1-treeUptime)+this.wgTree.healing/this.HPS*treeUptime;this.wg.time=this.wg.castTimeRatio*(1-treeUptime)+this.wgTree.castTimeRatio*treeUptime;this.sm.percentage=this.sm.healing/this.HPS*(1-treeUptime)+this.smTree.healing/this.HPS*treeUptime;this.sm.time=this.sm.castTimeRatio*(1-treeUptime)+this.smTree.castTimeRatio*treeUptime;this.efflo={percentage:this.sm.effloHPS/this.HPS*(1-treeUptime)+this.smTree.effloHPS/this.HPS*treeUptime,time:null};this.ccFiller.percentage=this.ccFiller.healing/this.HPS*(1-treeUptime);this.ccFiller.time=this.ccFiller.castTimeRatio*(1-treeUptime);this.treeFiller.percentage=this.treeFiller.healing/this.HPS*treeUptime;this.treeFiller.time=this.treeFiller.castTimeRatio*treeUptime;this.ccFillerTree.percentage=this.ccFillerTree.healing/this.HPS*treeUptime;this.ccFillerTree.time=this.ccFillerTree.castTimeRatio*treeUptime;return true;}
function RotationCalcs(spellCalcs){this.spell=spellCalcs;this.currentRotation=null;}
RotationCalcs.prototype.rotations=function(rotationIndex,whatIfCalcs,extraMode){var rc,r,sc=(rotationIndex==null||!whatIfCalcs)?this.spell:new SpellCalcs(this.spell.character,extraMode);function calcAndUpdate(i){if(rotationIndex!=null){r.calc(sc,true);if(whatIfCalcs)
r.whatIfCalcs=sc;}
else{r.calc(sc);rc[i]=r;}}
sc.run();if(rotationIndex==null){rc=new Array();}
if(rotationIndex==null||rotationIndex==0){r=new Rotation(rotationIndex,"Base");calcAndUpdate(0);}
return(rotationIndex!=null)?r:rc;}
RotationCalcs.prototype.whatIfCurrentRotation=function(){var originalRotation=this.rotationCalc[this.currentRotation];var originalValue=null;var newRotation;function whatIfGlyph(rc,glyph){originalValue=glyph.id;glyph.id=0;newRotation=rc.rotations(rc.currentRotation,true);glyph.id=originalValue;var mult=(glyph.id>0)?1:-1;glyph.HPS=mult*(originalRotation.HPS-newRotation.HPS);glyph.MP5=mult*(originalRotation.MP5-newRotation.MP5);}
function whatIfStat(rc,statName,granulation,extraMode){if(!extraMode){originalValue=rc.spell.character.stats[statName];rc.spell.character.stats[statName]+=(granulation)?granulation:1;}
newRotation=rc.rotations(rc.currentRotation,true,extraMode);rc.spell.character.stats.whatIf[statName+"HPS"]=(newRotation.HPS-originalRotation.HPS);rc.spell.character.stats.whatIf[statName+"MP5"]=(newRotation.MP5-originalRotation.MP5);if(!extraMode)
rc.spell.character.stats[statName]=originalValue;}
var mp5IntRatio=(originalRotation.TimeToOOM!="Never")?5/originalRotation.TimeToOOM:0;var totalMana=0;for(var i in this.spell.character.getCurrentSpec().talents){var t=this.spell.character.getCurrentSpec().talents[i];if(!t.whatIfIncluded)continue;if(!t.isExtraMode()){originalValue=t.points;t.points=t.getWhatIfPoints();}
newRotation=this.rotations(this.currentRotation,true,(t.isExtraMode())?t.name:null);if(!t.isExtraMode())
t.points=originalValue;var mult=(t.points>0)?1:-1;t.HPS=mult*(originalRotation.HPS-newRotation.HPS);if(t.cumulativeMP5){totalMana=this.spell.basicCalc.TotalMana-newRotation.whatIfCalcs.basicCalc.TotalMana;t.MP5=mult*(originalRotation.MP5-newRotation.MP5+totalMana*mp5IntRatio);}
else
t.MP5=mult*(originalRotation.MP5-newRotation.MP5);}
for(var i in this.spell.character.getCurrentSpec().primeGlyphs){whatIfGlyph(this,this.spell.character.getCurrentSpec().primeGlyphs[i]);}
for(var i in this.spell.character.getCurrentSpec().majorGlyphs){whatIfGlyph(this,this.spell.character.getCurrentSpec().majorGlyphs[i]);}
for(var i in this.spell.character.buffs){var b=this.spell.character.buffs[i];if(!b.whatIfIncluded)
continue;originalValue=b.value;b.value=b.getWhatIfValue();newRotation=this.rotations(this.currentRotation,true);b.value=originalValue;var mult=(!b.isOff())?1:-1;b.HPS=mult*(originalRotation.HPS-newRotation.HPS);if(b.cumulativeMP5){totalMana=this.spell.basicCalc.TotalMana-newRotation.whatIfCalcs.basicCalc.TotalMana;b.MP5=mult*(originalRotation.MP5-newRotation.MP5+totalMana*mp5IntRatio);}
else
b.MP5=mult*(originalRotation.MP5-newRotation.MP5);}
for(var i in this.spell.character.gear.effects){var e=this.spell.character.gear.effects[i];var newValue=e.getWhatIfValue();var extraMode=null;if(newValue==null)
continue;originalValue=e.value;if(e.extraMode)
extraMode=e.extraMode;else
e.value=newValue;SpellCalcs._specials.effect=e.name;newRotation=this.rotations(this.currentRotation,true,extraMode);e.value=originalValue;SpellCalcs._specials.effect=null;var mult=(e.value)?1:-1;e.HPS=mult*(originalRotation.HPS-newRotation.HPS);if(e.cumulativeMP5){totalMana=this.spell.basicCalc.TotalMana-newRotation.whatIfCalcs.basicCalc.TotalMana;e.MP5=mult*(originalRotation.MP5-newRotation.MP5+totalMana*mp5IntRatio);}
else
e.MP5=mult*(originalRotation.MP5-newRotation.MP5);}
this.spell.character.stats.whatIf=new Object();whatIfStat(this,"spellPower",1,"SP");whatIfStat(this,"spellCrit");whatIfStat(this,"spellHaste",10*this.spell.basicCalc.RatingMult);this.spell.character.stats.whatIf["spellHaste"+"HPS"]/=10*this.spell.basicCalc.RatingMult;this.spell.character.stats.whatIf["spellHaste"+"MP5"]/=10*this.spell.basicCalc.RatingMult
whatIfStat(this,"intellect",1,"Intellect");totalMana=newRotation.whatIfCalcs.basicCalc.TotalMana-this.spell.basicCalc.TotalMana;this.spell.character.stats.whatIf["intellect"+"MP5"]+=totalMana*mp5IntRatio;whatIfStat(this,"spirit",1,"Spirit");whatIfStat(this,"mastery");whatIfStat(this,"instantDelay",0.01);}
RotationCalcs.prototype.run=function(){this.rotationCalc=this.rotations();}
RotationCalcs.prototype.setCurrentRotation=function(index){this.currentRotation=index;this.whatIfCurrentRotation();}
function calculate(character,rotationIndex){var spellCalcs=new SpellCalcs(character);var rotation=new RotationCalcs(spellCalcs);rotation.run();rotation.setCurrentRotation(rotationIndex);return rotation;}
function HintHelper(element,hintValue){element.hintValue=hintValue;if(element.value=="")
element.value=hintValue;element.onfocus=function(e){if(element.hintValue&&element.value==element.hintValue)
element.value="";}
element.onblur=function(e){if(element.hintValue&&element.value=="")
element.value=element.hintValue;}}
function setElementVisibility(elem,isVisible){elem.style.display=(isVisible)?"block":"none";}
function addSelectOptions(select,valueList,nameList){var isGenerated=(typeof valueList=="number");var len=(isGenerated)?valueList:valueList.length;for(var i=0;i<len;i++){var o=document.createElement("option");if(isGenerated){o.text=(nameList)?nameList[i]:String(i);o.value=i;}
else{o.text=nameList[i];o.value=valueList[i];}
select.add(o,null);}}
var messageElement;var nameInput;var realmInput;var regionSelect;var currentChar;var oldCalc,currentCalc;function LogItem(character,calc){this.character=character;this.calc=calc;}
LogItem.prototype.toString=function(){return"HPS:"+Math.roundNumber(this.calc.rotationCalc[0].HPS,1)+" MP5: "+Math.roundNumber(this.calc.rotationCalc[0].MP5,1);};var hpsLog=new Array();$(document).ready(function(){$('#tabs').tabs();nameInput=document.getElementById("nameInput");realmInput=document.getElementById("realmInput");regionSelect=document.getElementById("regionSelect");$("#realmInput").autocomplete({source:[],minLength:2});$("#regionSelect").change(updateRealms);updateRealms();new HintHelper(nameInput,"Character Name");new HintHelper(realmInput,"Character Realm");messageElement=document.getElementById("messageElement");currentChar=new Character();currentChar.defaults();currentChar.setupControls();showRotations();$("#hpsLog").dblclick(setLogItem);restoreInputFromCookies();Math.roundNumber=function(x,d){if(d==0)
return Math.round(x);var pad=Math.pow(10,d);return Math.round(x*pad)/pad;};Math.ceilNumber=function(x,d){if(d==0)
return Math.ceil(x);var pad=Math.pow(10,d);return Math.ceil(x*pad)/pad;};});function updateRealms(){var region=$("#regionSelect").val();var url=window.TreeCalcs.urls.get_realms.replace("%r",region);$.ajax({url:url,dataType:"json",success:function(data){$("#realmInput").autocomplete("option","source",data);},error:function(){$("#realmInput").autocomplete("option","source",[]);}});}
function setLogItem(){var logItem=hpsLog[$("#hpsLog").val()];currentChar=logItem.character;currentCalc=logItem.calc;currentChar.updateControls();showHPS();}
function setMessage(text,isError){messageElement.className=(isError)?"error":"info";messageElement.innerHTML=text;}
function clearMessage(){setMessage("");}
function showHint(number){setElementVisibility(document.getElementById("hint1P"),(number==1));setElementVisibility(document.getElementById("hint2P"),(number==2));}
function setElementBonuses(elem,hps,mp5){while(elem&&elem.nodeName!="SPAN")
elem=elem.nextSibling;if(!elem)
return;for(var i=0;i<elem.children.length;i++){var node=elem.children[i];var s="",n,u;switch(node.nodeName){case"STRONG":s=(hps!=0)?Math.roundNumber(hps,2).toString():"<br />";u="HPS";n=hps;break;case"EM":if(mp5!=0)s=Math.roundNumber(mp5,2).toString();u="MP5";n=mp5;break;}
if(n!=0)
s=s+" "+u;node.innerHTML=s;node.className=(n>0)?"":"negative";}}
function findElementForObject(object,propertyName,useNameProperty){return document.getElementById((useNameProperty)?object.name:propertyName);}
function setObjectBonuses(object,propertyName,useNameProperty,hps,mp5){var element=findElementForObject(object,propertyName,useNameProperty);setElementBonuses(element,hps,mp5);}
function setValueFromProperty(object,propertyName,useNameProperty){var element=findElementForObject(object,propertyName,useNameProperty);if(!element)
return;if(element.type=="checkbox"||element.type=="radio")
element.checked=object[propertyName]!=0;else
if(element.type=="select-one"){for(var i=0;i<element.options.length;i++){if(element.options[i].value==object[propertyName])
element.selectedIndex=i;}}
else
element.value=object[propertyName];}
function setPropertyFromValue(object,propertyName,isNumeric,useNameProperty){var element=findElementForObject(object,propertyName,useNameProperty);if(!element)
return;if(element.type=="checkbox"||element.type=="radio")
object[propertyName]=element.checked;else
if(element.type=="select-one"){object[propertyName]=Number(element.options[element.selectedIndex].value);}
else
if(isNumeric){var v=Number(element.value);if(!isFinite(v))
throw(element.id+" is not a number");object[propertyName]=v;}
else
object[propertyName]=element.value;}
function importCharacter(){if(nameInput.value.length==0||nameInput.value.indexOf(' ')>=0){setMessage("Enter the character name",true);return;}
if(realmInput.value.length==0||realmInput.value==realmInput.hintValue){setMessage("Enter the realm",true);return;}
var loadingChar=new Character(nameInput.value,regionSelect.value,realmInput.value);loadingChar.onLoaded=importCharacterCallback;loadingChar.load();setMessage("Loading character...");}
var CookieInputState={"LastCharacterName":"#nameInput","LastCharacterRegion":"#regionSelect","LastCharacterRealm":"#realmInput","LastCharacterSpec":"#specSelect"};function restoreInputFromCookies(){for(var c in CookieInputState){var n=$.cookie(c);if(n)
$(CookieInputState[c]).val(n);}}
function storeInputToCookies(){for(var c in CookieInputState)
$.cookie(c,$(CookieInputState[c]).val())}
function importCharacterCallback(c){clearMessage();if(!c){setMessage("Import error. Check the input or re-try.",true);return;}
if(c.stats.classId!=Stats.DruidClassId){setMessage("Import error. Not a druid!",true);return;}
if(c.stats.level<Stats.GoodLevel){setMessage("Import error. Too low level character.",true);return;}
oldCalc=null;currentCalc=null;currentChar=c;currentChar.setCurrentSpec(document.getElementById("specSelect").value);currentChar.updateControls();showHint(1);showRotations();clearHasteCap();clearLog();setElementVisibility(document.getElementById("spells"),false);storeInputToCookies();}
function resetStats(){currentChar.stats.updateControls();}
function checkGearControls(){currentChar.gear.checkControls();}
function resetGearAndSpells(){currentChar.gear.updateControls();currentChar.spellUsage.updateControls();}
function resetTalents(){currentChar.getCurrentSpec().updateControls();}
function buffsToDefaults(){currentChar.setDefaultBuffs();}
function buffsToNone(){currentChar.setNoBuffs();}
function getSelectedRotation(){return 0;}
function showRotations(){var table=$("#rotationTable > tbody");var rotation=(currentCalc)?currentCalc.rotationCalc[0]:null;$("#ccFiller label").html(($("#OnClearcasts").val()!=0)?$("#OnClearcasts :selected").text():"Nothing on CC");$("#filler label").html($("#RemainderSpell :selected").text());var seriesData=[];var seriesLegend="";table.children("tr").each(function(){var id=$(this).prop("id");var percentageStr="";var timeStr="";if(id.length>0){if(rotation){var p=Math.roundNumber(rotation[id].percentage*100,2);if(p>0)percentageStr=String(p)+"%";var t=Math.roundNumber(rotation[id].time*100,2);if(t>0)timeStr=String(t)+"%";seriesData.push(rotation[id].percentage);}
seriesLegend+=$(this).children(":nth-child(1)").children("label").html()+" |";$(this).children(":nth-child(2)").children("strong").html(percentageStr);$(this).children(":nth-child(3)").children("small").html(timeStr);}});if(rotation){$("#currentHPS > strong").html(Math.roundNumber(rotation.HPS,2));$("#currentMP5 > strong").html(Math.roundNumber(rotation.MP5,2)+" MP5");$("#currentOOM > strong").html(Math.roundNumber(rotation.TimeToOOM,2)+" s");if(oldCalc){var diff=rotation.HPS-oldCalc.rotationCalc[0].HPS;var oldStr="";var oldIsBetter=diff<0;if(!oldIsBetter)
oldStr="+";oldStr+=Math.roundNumber(diff,2)+" HPS";var el=$("#currentHPS > em");el.html(oldStr);if(oldIsBetter)el.addClass("negative");else el.removeClass("negative");diff=rotation.MP5-oldCalc.rotationCalc[0].MP5;oldStr="";oldIsBetter=diff<0;if(!oldIsBetter)
oldStr="+";oldStr+=Math.roundNumber(diff,2)+" MP5";el=$("#currentMP5 > em");el.html(oldStr);if(oldIsBetter)el.addClass("negative");else el.removeClass("negative");}}
if(seriesLegend[seriesLegend.length-1]=="|")
seriesLegend=seriesLegend.substring(0,seriesLegend.length-1);showChart(seriesData,seriesLegend);}
function showChart(data,legend){$('#rotationChart').gchart('destroy');if(currentCalc){data=[$.gchart.series("Spell contribution",data)];$('#rotationChart').gchart({width:400,height:300,backgroundColor:'transparent',margins:[10,10],type:'pie3d',series:data,extension:{chdl:legend,chco:'4BA7CE|141A48|2363BC|0037FF|7826FF|7777CC|C2B1DD|000079|FFFFFF',chdlp:'b'}});}}
function setSpellInfo(td,value){var s=(value!=0)?Math.roundNumber(value,2).toString():"";var c=null;if(value>0)s="+"+s;else c="negative";td.children[0].innerHTML=s;if(c)
td.children[0].className=c;}
function initSpells(table){for(var hn in currentCalc.spell.HPETCalc){var h=currentCalc.spell.HPETCalc[hn];var html="<tr name='spell"+h.index+"'>";html+="<td><label>"+h.name+"</label></td>";for(var i=0;i<4;i++){if(i==1||i==3)
html+="<td><strong class='harm'></strong></td>";else
html+="<td><strong></strong></td>";}
for(i=0;i<4;i++)
html+="<td><dfn></dfn></td>";html+="</tr>";table.append(html);}}
function showSpells(){var table=$("#spellTable:first-child");if(table.find("tr").size()<=1)
initSpells(table);for(var hn in currentCalc.spell.HPETCalc){var h=currentCalc.spell.HPETCalc[hn];var row=table.find("tr[name='spell"+h.index+"'] > td");setSpellInfo(row[1],h.healing);setSpellInfo(row[2],h.healingHarm);setSpellInfo(row[3],h.HPM);setSpellInfo(row[4],h.HPMHarm);setSpellInfo(row[5],h.intellect);setSpellInfo(row[6],h.haste);setSpellInfo(row[7],h.crit);setSpellInfo(row[8],h.mastery);}}
function showHasteCap(){if(!currentCalc)
return;var hasteInfo=currentCalc.spell.getHasteInfo();var current=$("#currentHaste");current.find("strong").html(Math.round(hasteInfo.current));var extraString="";if(hasteInfo.lb)
extraString+=hasteInfo.lb+"th LB ";if(hasteInfo.wg)
extraString+=", "+hasteInfo.wg+"th WG ";if(hasteInfo.rg)
extraString+=", "+hasteInfo.rg+"th RG ";if(hasteInfo.rj)
extraString+=", "+hasteInfo.rj+"th RJ ";current.find("em").html(extraString);var next=$("#nextHaste");var nextString="";if(hasteInfo.next){next.find("strong").html(Math.round(hasteInfo.next));nextString="+"+Math.round(hasteInfo.next-hasteInfo.current)+" for "+hasteInfo.nextTicks+"th tick of "+hasteInfo.nextName;}
else
next.find("strong").html("");next.find("em").html(nextString);}
function clearHasteCap(){$("#currentHaste > *").html("");$("#nextHaste > *").html("");}
function updateLog(){var logItem=new LogItem(currentChar,currentCalc);hpsLog.push(logItem);$("#hpsLog").append(new Option(logItem.toString(),hpsLog.length-1));}
function showLog(){$("#hpsLog").parent().show();}
function clearLog(){hpsLog=new Array();$("#hpsLog").html("");$("#hpsLog").parent().hide();}
function calculateHPS(){currentChar.readControls();oldCalc=currentCalc;currentCalc=calculate(currentChar,getSelectedRotation());updateLog();}
function showHPS(){currentChar.updateBonuses();showRotations();showHasteCap();showLog();setElementVisibility(document.getElementById("spells"),true);showSpells();clearMessage();showHint(2);}
function updateHPS(){setMessage("Calculating...");try{calculateHPS();showHPS();currentChar=jQuery.extend(true,{},currentChar);}
catch(e){setMessage("Calc error: "+e,true);}}
