diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js
index f10a9a7d..8b6a16c6 100644
--- a/Resources/Scripts/code.js
+++ b/Resources/Scripts/code.js
@@ -1,4 +1,4 @@
-(function($, $TD, $TDX, TD){
+(function($TD, $TDX, $, TD){
   //
   // Variable: Current highlighted column jQuery & data objects.
   //
@@ -22,7 +22,7 @@
   //
   // Variable: DOM object containing the main app element.
   //
-  const app = $(document.body).children(".js-app");
+  const app = typeof $ === "function" && $(document.body).children(".js-app");
   
   //
   // Constant: Column icon classes mapped to their titles.
@@ -65,11 +65,12 @@
   };
   
   //
-  // Function: Returns true if an object has a specified property, otherwise returns false without throwing an error.
+  // Function: Returns true if an object has a specified property, otherwise returns false with a debug-only error message.
   //
   const ensurePropertyExists = function(obj, ...chain){
     for(let index = 0; index < chain.length; index++){
       if (!obj.hasOwnProperty(chain[index])){
+        debugger;
         $TD.crashDebug("Missing property "+chain[index]+" in chain [obj]."+chain.join("."));
         return false;
       }
@@ -80,6 +81,20 @@
     return true;
   };
   
+  //
+  // Function: Returns a jQuery object but also shows a debug-only error message if no elements are found.
+  //
+  const $$ = function(selector, context){
+    let result = $(selector, context);
+    
+    if (!result.length){
+      debugger;
+      $TD.crashDebug("No elements were found for selector "+selector);
+    }
+    
+    return result;
+  };
+  
   //
   // Function: Retrieves a property of an element with a specified class.
   //
@@ -101,10 +116,10 @@
   $(document).on("uiColumnRendered", function(e, data){
     let icon = data.$column.find(".column-type-icon").first();
     return if icon.length !== 1;
-    
+
     let name = Array.prototype.find.call(icon[0].classList, cls => cls.startsWith("icon-"));
     return if !name;
-    
+
     data.$column.attr("data-td-icon", name);
     data.column._tduck_icon = name;
   });
@@ -277,6 +292,11 @@
   // Function: Shows tweet detail, used in notification context menu.
   //
   (function(){
+    return if !ensurePropertyExists(TD, "ui", "updates", "showDetailView");
+    return if !ensurePropertyExists(TD, "controller", "columnManager", "showColumn");
+    return if !ensurePropertyExists(TD, "controller", "columnManager", "getByApiid");
+    return if !ensurePropertyExists(TD, "controller", "clients", "getPreferredClient");
+    
     const showTweetDetailInternal = function(column, chirp){
       TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp) || chirp);
       TD.controller.columnManager.showColumn(column.model.privateState.key);
@@ -393,7 +413,7 @@
   // Block: Add TweetDuck buttons to the settings menu.
   //
   onAppReady.push(function(){
-    $("[data-action='settings-menu']").click(function(){
+    $$("[data-action='settings-menu']").click(function(){
       setTimeout(function(){
         let menu = $(".js-dropdown-content").children("ul").first();
         return if menu.length === 0;
@@ -627,6 +647,9 @@
   // Block: Update highlighted column and tweet for context menu and other functionality.
   //
   (function(){
+    return if !ensurePropertyExists(TD, "controller", "columnManager", "get");
+    return if !ensurePropertyExists(TD, "services", "ChirpBase", "TWEET");
+    
     const updateHighlightedColumn = function(ele){
       highlightedColumnEle = ele;
       highlightedColumnObj = ele ? TD.controller.columnManager.get(ele.attr("data-column")) : null;
@@ -877,22 +900,28 @@
   //
   // Block: Fix scheduled tweets not showing up sometimes.
   //
-  $(document).on("dataTweetSent", function(e, data){
-    if (data.response.state && data.response.state === "scheduled"){
-      let column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");
+  (function(){
+    return if !ensurePropertyExists(TD, "controller", "columnManager", "getAll");
+    
+    $(document).on("dataTweetSent", function(e, data){
+      if (data.response.state && data.response.state === "scheduled"){
+        let column = Object.values(TD.controller.columnManager.getAll()).find(column => column.model.state.type === "scheduled");
 
-      if (column){
-        setTimeout(function(){
-          column.reloadTweets();
-        }, 1000);
+        if (column){
+          setTimeout(function(){
+            column.reloadTweets();
+          }, 1000);
+        }
       }
-    }
-  });
+    });
+  })();
   
   //
   // Block: Hold Shift to restore cleared column.
   //
   (function(){
+    return if !ensurePropertyExists(TD, "vo", "Column", "prototype", "clear");
+    
     var holdingShift = false;
     
     const updateShiftState = (pressed) => {
@@ -916,8 +945,6 @@
       }
     });
     
-    return if !ensurePropertyExists(TD, "vo", "Column", "prototype", "clear");
-    
     TD.vo.Column.prototype.clear = prependToFunction(TD.vo.Column.prototype.clear, function(){
       window.setTimeout(resetActiveFocus, 0); // unfocuses the Clear button, otherwise it steals keyboard input
       
@@ -933,11 +960,13 @@
   // Block: Refocus the textbox after switching accounts.
   //
   onAppReady.push(function(){
+    const composeInput = $$(".js-compose-text", ".js-docked-compose");
+    
     const refocusInput = function(){
-      $(".js-compose-text", ".js-docked-compose").focus();
+      composeInput.focus();
     };
     
-    $(".js-account-list", ".js-docked-compose").delegate(".js-account-item", "click", function(e){
+    $$(".js-account-list", ".js-docked-compose").delegate(".js-account-item", "click", function(e){
       setTimeout(refocusInput, 0);
     });
   });
@@ -1048,7 +1077,7 @@
       default: throw "Invalid mustache injection operation. Only 'replace', 'append', 'prepend' are supported.";
     }
     
-    let prev = TD.mustaches[name];
+    let prev = TD.mustaches && TD.mustaches[name];
     
     if (!prev){
       $TD.crashDebug("Mustache injection is referencing an invalid mustache: "+name);
@@ -1141,9 +1170,9 @@
     
     TD.mustaches["media/native_video.mustache"] = '<div class="js-media-gif-container media-item nbfc is-video" style="background-image:url({{imageSrc}})"><video class="js-media-gif media-item-gif full-width block {{#isPossiblySensitive}}is-invisible{{/isPossiblySensitive}}" loop src="{{videoUrl}}"></video><a class="js-gif-play pin-all is-actionable">{{> media/video_overlay}}</a></div>';
     
-    if (!ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet") ||
-        !ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer") ||
-        !ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused"))return;
+    return if !ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet");
+    return if !ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer");
+    return if !ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused");
     
     var cancelModal = false;
     
@@ -1172,10 +1201,10 @@
   if (ensurePropertyExists(TD, "services", "TwitterMedia")){
     let media = TD.services.TwitterMedia;
     
-    if (!ensurePropertyExists(media, "YOUTUBE_TINY_RE") ||
-        !ensurePropertyExists(media, "YOUTUBE_LONG_RE") ||
-        !ensurePropertyExists(media, "YOUTUBE_RE") ||
-        !ensurePropertyExists(media, "SERVICES", "youtube"))return;
+    return if !ensurePropertyExists(media, "YOUTUBE_TINY_RE");
+    return if !ensurePropertyExists(media, "YOUTUBE_LONG_RE");
+    return if !ensurePropertyExists(media, "YOUTUBE_RE");
+    return if !ensurePropertyExists(media, "SERVICES", "youtube");
     
     media.YOUTUBE_TINY_RE = new RegExp(media.YOUTUBE_TINY_RE.source.replace("http:", "https?:"));
     media.YOUTUBE_RE = new RegExp(media.YOUTUBE_LONG_RE.source+"|"+media.YOUTUBE_TINY_RE.source);
@@ -1187,12 +1216,11 @@
   //
   onAppReady.push(function(){
     let ele = $(`<svg id="td-compose-drawer-pin" viewBox="0 0 24 24" class="icon js-show-tip" data-original-title="Stay open" data-tooltip-position="left">
-       <path d="M9.884,16.959l3.272,0.001l-0.82,4.568l-1.635,0l-0.817,-4.569Z"/>
-       <rect x="8.694" y="7.208" width="5.652" height="7.445"/>
-       <path d="M16.877,17.448c0,-1.908 -1.549,-3.456 -3.456,-3.456l-3.802,0c-1.907,0 -3.456,1.548 -3.456,3.456l10.714,0Z"/>
-       <path d="M6.572,5.676l2.182,2.183l5.532,0l2.182,-2.183l0,-1.455l-9.896,0l0,1.455Z"/>
-       </svg>`
-    ).appendTo(".js-docked-compose .js-compose-header");
+ <path d="M9.884,16.959l3.272,0.001l-0.82,4.568l-1.635,0l-0.817,-4.569Z"/>
+ <rect x="8.694" y="7.208" width="5.652" height="7.445"/>
+ <path d="M16.877,17.448c0,-1.908 -1.549,-3.456 -3.456,-3.456l-3.802,0c-1.907,0 -3.456,1.548 -3.456,3.456l10.714,0Z"/>
+ <path d="M6.572,5.676l2.182,2.183l5.532,0l2.182,-2.183l0,-1.455l-9.896,0l0,1.455Z"/>
+ </svg>`).appendTo(".js-docked-compose .js-compose-header");
     
     ele.click(function(){
       if (TD.settings.getComposeStayOpen()){
@@ -1213,26 +1241,31 @@
   //
   // Block: Make temporary search column appear as the first one and clear the input box.
   //
-  $(document).on("uiSearchNoTemporaryColumn", function(e, data){
-    if (data.query && data.searchScope !== "users" && !data.columnKey){
-      if ($TDX.openSearchInFirstColumn){
-        let order = TD.controller.columnManager._columnOrder;
-        
-        if (order.length > 1){
-          let columnKey = order[order.length-1];
-          
-          order.splice(order.length-1, 1);
-          order.splice(1, 0, columnKey);
-          TD.controller.columnManager.move(columnKey, "left");
+  (function(){
+    return if !ensurePropertyExists(TD, "controller", "columnManager", "_columnOrder");
+    return if !ensurePropertyExists(TD, "controller", "columnManager", "move");
+    
+    $(document).on("uiSearchNoTemporaryColumn", function(e, data){
+      if (data.query && data.searchScope !== "users" && !data.columnKey){
+        if ($TDX.openSearchInFirstColumn){
+          let order = TD.controller.columnManager._columnOrder;
+
+          if (order.length > 1){
+            let columnKey = order[order.length-1];
+
+            order.splice(order.length-1, 1);
+            order.splice(1, 0, columnKey);
+            TD.controller.columnManager.move(columnKey, "left");
+          }
+        }
+
+        if (!("tweetduck" in data)){
+          $(".js-app-search-input").val("");
+          $(".js-perform-search").blur();
         }
       }
-      
-      if (!("tweetduck" in data)){
-        $(".js-app-search-input").val("");
-        $(".js-perform-search").blur();
-      }
-    }
-  });
+    });
+  })();
   
   //
   // Block: Setup global function to add a search column with the specified query.
@@ -1250,9 +1283,9 @@
   //
   onAppReady.push(function(){
     let container = $(".js-search-in-popover");
-    let hashtags = $(".js-typeahead-topic-list", container);
+    let hashtags = $$(".js-typeahead-topic-list", container);
     
-    $(".js-typeahead-user-list", container).insertBefore(hashtags);
+    $$(".js-typeahead-user-list", container).insertBefore(hashtags);
     hashtags.addClass("list-divider");
   });
   
@@ -1269,17 +1302,17 @@
       app.click(); // unfocus everything
     };
     
-    $(".js-app-search-input").keydown(function(e){
+    $$(".js-app-search-input").keydown(function(e){
       (e.ctrlKey && e.keyCode === 13) && openSearchExternally(e, $(this)); // enter
     });
     
-    $(".js-perform-search").on("click auxclick", function(e){
+    $$(".js-perform-search").on("click auxclick", function(e){
       (e.ctrlKey || e.button === 1) && openSearchExternally(e, $(".js-app-search-input:visible"));
     }).each(function(){
       window.TDGF_prioritizeNewestEvent($(this)[0], "click");
     });
     
-    $("[data-action='show-search']").on("click auxclick", function(e){
+    $$("[data-action='show-search']").on("click auxclick", function(e){
       (e.ctrlKey || e.button === 1) && openSearchExternally(e, $());
     });
   });
@@ -1460,14 +1493,19 @@
   // Block: Custom reload function with memory cleanup.
   //
   window.TDGF_reload = function(){
-    let session = TD.storage.feedController.getAll()
-                    .filter(feed => !!feed.getTopSortIndex())
-                    .reduce((obj, feed) => (obj[feed.privateState.key] = feed.getTopSortIndex(), obj), {});
-    
-    $TD.setSessionData("gc", JSON.stringify(session)).then(() => {
-      window.gc && window.gc();
+    try{
+      let session = TD.storage.feedController.getAll()
+                      .filter(feed => !!feed.getTopSortIndex())
+                      .reduce((obj, feed) => (obj[feed.privateState.key] = feed.getTopSortIndex(), obj), {});
+      
+      $TD.setSessionData("gc", JSON.stringify(session)).then(() => {
+        window.gc && window.gc();
+        window.location.reload();
+      });
+    }catch(err){
+      $TD.crashDebug("Error saving session during a reload");
       window.location.reload();
-    });
+    }
     
     window.TDGF_reload = function(){}; // redefine to prevent reloading multiple times
   };
@@ -1482,7 +1520,7 @@
       state = {};
     }
     
-    var showMissedNotifications = function(){
+    const showMissedNotifications = function(){
       let tweets = [];
       let columns = {};
       
@@ -1510,18 +1548,20 @@
       }
     };
     
-    $(document).one("dataColumnsLoaded", function(){
-      let columns = Object.values(TD.controller.columnManager.getAll());
-      let remaining = columns.length;
+    if (ensurePropertyExists(TD, "controller", "columnManager", "getAll")){
+      $(document).one("dataColumnsLoaded", function(){
+        let columns = Object.values(TD.controller.columnManager.getAll());
+        let remaining = columns.length;
 
-      for(let column of columns){
-        column.ui.getChirpContainer().one("dataColumnFeedUpdated", () => {
-          if (--remaining === 0){
-            setTimeout(showMissedNotifications, 1);
-          }
-        });
-      }
-    });
+        for(let column of columns){
+          column.ui.getChirpContainer().one("dataColumnFeedUpdated", () => {
+            if (--remaining === 0){
+              setTimeout(showMissedNotifications, 1);
+            }
+          });
+        }
+      });
+    }
   }
   
   //
@@ -1571,4 +1611,4 @@
       location.href = "https://twitter.com/login?hide_message=true&redirect_after_login=https%3A%2F%2Ftweetdeck.twitter.com%2F%3Fvia_twitter_login%3Dtrue";
     };
   }
-})($, $TD, $TDX, TD);
+})($TD, $TDX, window.$, window.TD || {});