diff --git a/panorama/dota.d.ts b/panorama/dota.d.ts
index 3738e26..6896f09 100644
--- a/panorama/dota.d.ts
+++ b/panorama/dota.d.ts
@@ -217,7 +217,7 @@ interface CScriptBindingPR_Abilities {
     GetLevel(entityID:number) : number;
     GetKeybind(entityID:number) : string;
     IsCooldownReady(entityID:number) : boolean;
-    GetAutoCastState(entityID:number) : number;
+    GetAutoCastState(entityID:number) : boolean;
     GetCooldownTimeRemaining(entityID:number) : number;
     GetToggleState(entityID:number) : number;
     IsInAbilityPhase(entityID:number) : boolean;
@@ -241,6 +241,7 @@ interface CScriptBindingPR_Game {
 }
 
 interface Panel {
+    BHasClass(className:string) : boolean;
     LoadLayoutAsync(path:String, unknown:boolean, unknown2:boolean) : void;
     RemoveAndDeleteChildren() : void;
     AddClass(name:String) : void;
@@ -251,6 +252,11 @@ interface Panel {
 interface Label extends Panel {
     text : string;
 }
+//TODO: extends Image
+interface DOTAAbilityImage extends Panel {
+    abilityname:string;
+    contextEntityIndex:number;
+}
 
 interface DollarStatic {
     (selector: string) : Panel;
diff --git a/panorama/scripts/custom_game/actionpanel/abilitypanel.js b/panorama/scripts/custom_game/actionpanel/abilitypanel.js
index 2c13019..745e09a 100644
--- a/panorama/scripts/custom_game/actionpanel/abilitypanel.js
+++ b/panorama/scripts/custom_game/actionpanel/abilitypanel.js
@@ -2,7 +2,7 @@
 (function () {
     var SILENCE_NONE = 0, SILENCE_ABILITIES = 1, SILENCE_PASSIVES = 2, SILENCE_ALL = 3;
     var ABILITY_STATE_DEFAULT = 0, ABILITY_STATE_ACTIVE = 1, ABILITY_STATE_ABILITY_PHASE = 2, ABILITY_STATE_COOLDOWN = 3;
-    ABILITY_STATE_MUTED = 4;
+    //    ABILITY_STATE_MUTED = 4;
     var panel = $.GetContextPanel();
     /* Initialise this ability panel with an ability (like a constructor). */
     panel.init = function (ability, unit) {
@@ -110,7 +110,7 @@
             $("#cooldownswipe").style.clip = "radial(50% 50%, 0deg, -360deg)";
         });
         // Make cooldown label visible
-        $("#CooldownLabel").text = Math.ceil(duration);
+        $("#CooldownLabel").text = Math.ceil(duration).toString();
         $("#CooldownLabel").style.visibility = "visible";
         // Start the schedule loop
         $.Schedule(duration % 1.0, panel.updateCooldown);
@@ -122,7 +122,7 @@
             return;
         }
         var cooldown = Abilities.GetCooldownTimeRemaining(panel.ability);
-        $("#CooldownLabel").text = Math.ceil(cooldown);
+        $("#CooldownLabel").text = Math.ceil(cooldown).toString();
         $.Schedule(1.0, panel.updateCooldown);
     };
     /* Add level pips. */
@@ -169,7 +169,7 @@
                 $("#AbilityImage").RemoveClass("NotLearned");
                 if (manaCost > 0) {
                     $("#ManaLabel").style.visibility = "visible";
-                    $("#ManaLabel").text = manaCost;
+                    $("#ManaLabel").text = manaCost.toString();
                 }
                 else {
                     $("#ManaLabel").style.visibility = "collapse";
diff --git a/panorama/scripts/custom_game/actionpanel/abilitypanel.ts b/panorama/scripts/custom_game/actionpanel/abilitypanel.ts
index cf876f4..4a5e248 100644
--- a/panorama/scripts/custom_game/actionpanel/abilitypanel.ts
+++ b/panorama/scripts/custom_game/actionpanel/abilitypanel.ts
@@ -1,4 +1,28 @@
 /// <reference path="../../../dota.d.ts" />
+interface AbilityPanel extends Panel {
+    init(ability, unit) : void;
+    ability:number;
+    abilityName:string;
+    ownerUnit:number;
+    level:number;
+    maxLevel:number;
+    learning:boolean;
+    autocast:boolean;
+    state:number;
+    pips:Label[];
+    setLevel(level:number) : void;
+    reinit():void;
+    setLearnMode(learn:boolean):void;
+    showTooltip():void;
+    hideTooltip():void;
+    onLeftClick():void;
+    onRightClick():void;
+    startCooldown(duration:number):void;
+    updateCooldown():void;
+    addLevelPips(level?:number):void;
+    setSilenceState(state:number):void;
+    update():void;
+}
 
 (function() {
     var SILENCE_NONE = 0,
@@ -10,9 +34,9 @@
         ABILITY_STATE_ACTIVE = 1,
         ABILITY_STATE_ABILITY_PHASE = 2,
         ABILITY_STATE_COOLDOWN = 3;
-        ABILITY_STATE_MUTED = 4;
+    //    ABILITY_STATE_MUTED = 4;
 
-    var panel = $.GetContextPanel();
+    var panel = <AbilityPanel>$.GetContextPanel();
 
     /* Initialise this ability panel with an ability (like a constructor). */
     panel.init = function(ability, unit) {
@@ -29,8 +53,8 @@
         panel.pips = [];
 
         // Set the ability image.
-        $( "#AbilityImage" ).abilityname = panel.abilityName;
-        $( "#AbilityImage" ).contextEntityIndex = panel.ownerUnit;
+        (<DOTAAbilityImage>$( "#AbilityImage" )).abilityname = panel.abilityName;
+        (<DOTAAbilityImage>$( "#AbilityImage" )).contextEntityIndex = panel.ownerUnit;
 
         // Set a special style for passive abilities
         if (Abilities.IsPassive(panel.ability)) {
@@ -59,7 +83,7 @@
         if (Abilities.IsPassive(panel.ability)) {
             $("#HotkeyLabel").style.visibility = "collapse";
         } else {
-            $("#HotkeyLabel").text = hotkey;
+            (<Label>$("#HotkeyLabel")).text = hotkey;
         }
     }
 
@@ -76,7 +100,7 @@
 
         // Update hotkey label, can change because of slot swapping
         var hotkey = Abilities.GetKeybind(panel.ability);
-        $("#HotkeyLabel").text = hotkey;
+        (<Label>$("#HotkeyLabel")).text = hotkey;
 
         // Do not play shine on panels that came off cooldown while looking away
         if (panel.state === ABILITY_STATE_COOLDOWN && Abilities.IsCooldownReady(panel.ability)) {
@@ -136,7 +160,7 @@
         });
 
         // Make cooldown label visible
-        $("#CooldownLabel").text = Math.ceil(duration);
+        (<Label>$("#CooldownLabel")).text = Math.ceil(duration).toString();
         $("#CooldownLabel").style.visibility = "visible";
 
         // Start the schedule loop
@@ -151,7 +175,7 @@
         }
         
         var cooldown = Abilities.GetCooldownTimeRemaining(panel.ability);
-        $("#CooldownLabel").text = Math.ceil(cooldown);
+        (<Label>$("#CooldownLabel")).text = Math.ceil(cooldown).toString();
 
         $.Schedule(1.0, panel.updateCooldown);
     }
@@ -163,7 +187,7 @@
         var maxLevel = panel.maxLevel;
         if (maxLevel < 8) {
             for (var i = 0; i < maxLevel; i++) {
-                var pip = $.CreatePanel("Panel", pipContainer, "");
+                var pip = <Label>$.CreatePanel("Panel", pipContainer, "");
                 if (i < level) {
                     pip.AddClass("LeveledPip");
                 } else {
@@ -176,7 +200,7 @@
             }
         } else {
             //Add pips for levels > 8
-            var pipLabel = $.CreatePanel("Label", pipContainer, "");
+            var pipLabel = <Label>$.CreatePanel("Label", pipContainer, "");
             pipLabel.text = "0/"+maxLevel;
             panel.pips[0] = pipLabel;
         }
@@ -201,7 +225,7 @@
 
                 if (manaCost > 0) {
                     $("#ManaLabel").style.visibility = "visible";
-                    $("#ManaLabel").text = manaCost;
+                    (<Label>$("#ManaLabel")).text = manaCost.toString();
                 } else {
                     $("#ManaLabel").style.visibility = "collapse";
                 }
diff --git a/panorama/scripts/custom_game/actionpanel/actionpanel.js b/panorama/scripts/custom_game/actionpanel/actionpanel.js
index 8bafabb..d67b164 100644
--- a/panorama/scripts/custom_game/actionpanel/actionpanel.js
+++ b/panorama/scripts/custom_game/actionpanel/actionpanel.js
@@ -1,17 +1,25 @@
 /// <reference path="../../../dota.d.ts" />
+/// <reference path="abilitypanel.ts" />
 (function () {
-    var SILENCE_NONE = 0, SILENCE_ABILITIES = 1, SILENCE_PASSIVES = 2, SILENCE_ALL = 3;
+    // Bitmask enum
+    var SilenceState;
+    (function (SilenceState) {
+        SilenceState[SilenceState["None"] = 0] = "None";
+        SilenceState[SilenceState["Abilities"] = 1] = "Abilities";
+        SilenceState[SilenceState["Passives"] = 2] = "Passives";
+        SilenceState[SilenceState["All"] = 3] = "All";
+    })(SilenceState || (SilenceState = {}));
     var ItemDB = {
         587: "default",
         10150: "dire",
         10324: "portal",
-        11349: "mana_pool" //ID is actually TI5, I don't have mana pool to test though
+        11349: "mana_pool" // ID is actually TI5, I don't have mana pool to test though
     };
     var units = {};
     var currentUnit = -1;
     var abilities = {};
     var learnMode = false;
-    var silenceState = SILENCE_NONE;
+    var silenceState = SilenceState.None;
     /* Set actionpanel for a specified unit. */
     function SetActionPanel(unit) {
         var abilityContainer = $("#AbilitiesContainer");
@@ -21,7 +29,7 @@
         }
         // Remove old ability layout
         abilityContainer.RemoveClass("AbilityLayout" + countAbilityLayout(currentUnit));
-        //Set the new current unit
+        // Set the new current unit
         currentUnit = unit;
         // Retrieve panels we made previously to avoid deletion or excessive panels.
         if (units[unit] !== undefined) {
@@ -58,16 +66,16 @@
         var unit = Players.GetQueryUnit(Players.GetLocalPlayer());
         // Filter out invalid units (happens when switching back to the hero from a query unit.)
         // This also fires an update_selected_unit event so should be handled fine.
-        if (unit != -1) {
+        if (unit !== -1) {
             SetActionPanel(unit);
         }
     }
     function onStatsChanged(event) {
-        //Ability points changed - reinit all abilities
+        // Ability points changed - reinit all abilities
         for (var ab in abilities) {
             abilities[ab].reinit();
         }
-        //Update stats?
+        // Update stats?
     }
     function onAbilityChanged(event) {
         updateVisibleAbilities();
@@ -77,14 +85,14 @@
         $.Msg(skinName);
         if (skinName !== undefined) {
             $("#MinimapBorder").style.backgroundImage = "url('s2r://panorama/images/hud/" + skinName + "/actionpanel/minimapborder.png');";
-            //WTF DO WE DO NOW WITH DIFFERENT RESOLUTIONS!!
+            // WTF DO WE DO NOW WITH DIFFERENT RESOLUTIONS!!
             $("#MinimapSpacer").style.backgroundImage = "url('s2r://panorama/images/hud/" + skinName + "/actionpanel/spacer_16_9.png');";
-            //TODO: spacer_16_10
-            //WTF DO WE DO NOW WITH DIFFERENT RESOLUTIONS!!
-            //TODO: portrait
+            // TODO: spacer_16_10
+            // WTF DO WE DO NOW WITH DIFFERENT RESOLUTIONS!!
+            // TODO: portrait
             $("#PortraitBorder").style.backgroundImage = "url('s2r://panorama/images/hud/" + skinName + "/actionpanel/portrait_wide.png');";
             $("#center_left_wide").style.backgroundImage = "url('s2r://panorama/images/hud/" + skinName + "/actionpanel/center_left_wide.png');";
-            //TODO: center_left
+            // TODO: center_left
             $("#center_right").style.backgroundImage = "url('s2r://panorama/images/hud/" + skinName + "/actionpanel/center_right.png');";
             $.Msg($("#MinimapBorder").style.backgroundImage);
         }
@@ -92,11 +100,11 @@
     }
     function updateVisibleAbilities() {
         var abilityContainer = $("#AbilitiesContainer");
-        //Hide all abilities
+        // Hide all abilities
         for (var ab in abilities) {
             abilities[ab].style.visibility = "collapse";
         }
-        //Show only the visible abilities
+        // Show only the visible abilities
         var slot = 0;
         var abilityCount = Entities.GetAbilityCount(currentUnit) - 1;
         while (slot < abilityCount) {
@@ -109,7 +117,7 @@
             if (!Abilities.IsAttributeBonus(ability) && !Abilities.IsHidden(ability)) {
                 if (abilities[ability] !== undefined) {
                     abilities[ability].style.visibility = "visible";
-                    //Reinit the ability to check for changes
+                    // Reinit the ability to check for changes
                     abilities[ability].reinit();
                 }
                 else {
@@ -136,7 +144,7 @@
         var count = 0;
         for (var slot = 0; slot < Entities.GetAbilityCount(currentUnit); slot++) {
             var ability = Entities.GetAbility(unit, slot);
-            if (ability == -1) {
+            if (ability === -1) {
                 break;
             }
             if (!Abilities.IsAttributeBonus(ability) && !Abilities.IsHidden(ability)) {
@@ -147,25 +155,25 @@
     }
     /* Get the silence state (abilities, passives or both) */
     function getSilenceState(unit) {
-        var state = SILENCE_NONE;
+        var state = SilenceState.None;
         if (Entities.IsSilenced(unit) || Entities.IsHexed(unit))
-            state += SILENCE_ABILITIES;
+            state += SilenceState.Abilities;
         if (Entities.PassivesDisabled(unit))
-            state += SILENCE_PASSIVES;
+            state += SilenceState.Passives;
         return state;
     }
     /* Update loop */
     function onUpdate() {
-        //Check if we are in ability learn mode
+        // Check if we are in ability learn mode
         if (Game.IsInAbilityLearnMode() !== learnMode) {
             learnMode = Game.IsInAbilityLearnMode();
             for (var ab in abilities) {
                 abilities[ab].setLearnMode(learnMode);
             }
         }
-        //Make ability state only visible to allies (this can be commented out to see enemy ability states!)
+        // Make ability state only visible to allies (this can be commented out to see enemy ability states!)
         if (!Entities.IsEnemy(currentUnit)) {
-            //Check silence state
+            // Check silence state
             var silenceS = getSilenceState(currentUnit);
             if (silenceS !== silenceState) {
                 silenceState = silenceS;
@@ -185,16 +193,16 @@
     GameEvents.Subscribe("dota_player_update_query_unit", onUpdateQueryUnit);
     GameEvents.Subscribe("dota_portrait_unit_stats_changed", onStatsChanged);
     GameEvents.Subscribe("dota_ability_changed", onAbilityChanged);
-    //Listen for hacky inventory updates
+    // Listen for hacky inventory updates
     GameEvents.Subscribe("inventory_updated", onSteamInventoryChanged);
-    //Set default unit
+    // Set default unit
     var unit = Players.GetQueryUnit(Players.GetLocalPlayer());
     if (unit === -1) {
         unit = Players.GetLocalPlayerPortraitUnit();
     }
     SetActionPanel(unit);
-    //Listen to dota_action_success to determine cast state
+    // Listen to dota_action_success to determine cast state
     onUpdate();
-    //Listen for level up event - dota_ability_changed
-    //Listen for casts (cooldown starts)
+    // Listen for level up event - dota_ability_changed
+    // Listen for casts (cooldown starts)
 })();
diff --git a/panorama/scripts/custom_game/actionpanel/actionpanel.ts b/panorama/scripts/custom_game/actionpanel/actionpanel.ts
index eb3fa39..1b2bdb2 100644
--- a/panorama/scripts/custom_game/actionpanel/actionpanel.ts
+++ b/panorama/scripts/custom_game/actionpanel/actionpanel.ts
@@ -1,4 +1,6 @@
 /// <reference path="../../../dota.d.ts" />
+/// <reference path="abilitypanel.ts" />
+
 (function() {
     // Bitmask enum
     enum SilenceState {
@@ -145,7 +147,7 @@
                 }
                 else {
                     // Create new panel and load the layout.
-                    let abilityPanel = $.CreatePanel( "Panel", abilityContainer, "" );
+                    let abilityPanel = <AbilityPanel>$.CreatePanel( "Panel", abilityContainer, "" );
                     abilityPanel.LoadLayoutAsync( "file://{resources}/layout/custom_game/actionpanel/abilitypanel.xml", false, false );
 
                     // Initialise the ability panel.
