var hashchange = (function () {

var exports = {};

var expected_hash;
var changing_hash = false;

// Some browsers zealously URI-decode the contents of
// window.location.hash.  So we hide our URI-encoding
// by replacing % with . (like MediaWiki).

exports.encodeHashComponent = function(str) {
    return encodeURIComponent(str)
        .replace(/\./g, '%2E')
        .replace(/%/g,  '.');
};

function decodeHashComponent(str) {
    return decodeURIComponent(str.replace(/\./g, '%'));
}

exports.changehash = function (newhash) {
    if (changing_hash) {
        return;
    }
    $(document).trigger($.Event('hashchange.zephyr'));
    expected_hash = newhash;
    // Some browsers reset scrollTop when changing the hash to "",
    // so we save and restore it.
    // http://stackoverflow.com/questions/4715073/window-location-hash-prevent-scrolling-to-the-top
    var scrolltop = viewport.scrollTop();
    window.location.hash = newhash;
    util.reset_favicon();
    if (newhash === "" || newhash === "#") {
        viewport.scrollTop(scrolltop);
    }
};

exports.save_narrow = function (operators) {
    if (changing_hash) {
        return;
    }
    if (operators === undefined) {
        exports.changehash('#');
    } else {
        var new_hash = '#narrow';
        $.each(operators, function (idx, elem) {
            new_hash += '/' + hashchange.encodeHashComponent(elem[0])
                      + '/' + hashchange.encodeHashComponent(elem[1]);
        });
        exports.changehash(new_hash);
    }
};

function parse_narrow(hash) {
    var i, operators = [];
    for (i=1; i<hash.length; i+=2) {
        // We don't construct URLs with an odd number of components,
        // but the user might write one.
        var operator = decodeHashComponent(hash[i]);
        var operand  = decodeHashComponent(hash[i+1] || '');
        operators.push([operator, operand]);
    }
    narrow.activate(operators, {
        select_first_unread: true,
        change_hash:    false  // already set
    });
}

// Returns true if this function performed a narrow
function do_hashchange() {
    // If window.location.hash changed because our app explicitly
    // changed it, then we don't need to do anything.
    // (This function only neds to jump into action if it changed
    // because e.g. the back button was pressed by the user)
    //
    // The second case is for handling the fact that some browsers
    // automatically convert '#' to '' when you change the hash to '#'.
    if (window.location.hash === expected_hash ||
        (expected_hash !== undefined &&
         window.location.hash.replace(/^#/, '') === '' &&
         expected_hash.replace(/^#/, '') === '')) {
        return false;
    }

    $(document).trigger($.Event('hashchange.zephyr'));

    // NB: In Firefox, window.location.hash is URI-decoded.
    // Even if the URL bar says #%41%42%43%44, the value here will
    // be #ABCD.
    var hash = window.location.hash.split("/");
    switch (hash[0]) {
        case "#narrow":
            ui.change_tab_to("#home");
            parse_narrow(hash);
            ui.update_floating_recipient_bar();
            return true;
        case "":
        case "#":
            ui.change_tab_to("#home");
            narrow.deactivate();
            ui.update_floating_recipient_bar();
            break;
        case "#subscriptions":
            ui.change_tab_to("#subscriptions");
            break;
        case "#settings":
            ui.change_tab_to("#settings");
            break;
    }
    return false;
}

function hashchanged() {
    changing_hash = true;
    var ret = do_hashchange();
    changing_hash = false;
    return ret;
}

exports.initialize = function () {
    // jQuery doesn't have a hashchange event, so we manually wrap
    // our event handler
    window.onhashchange = blueslip.wrap_function(hashchanged);
    hashchanged();
};

return exports;

}());

@@ -1718,16 +1718,34 @@
 te one.%0A
+        try %7B%0A    
         
@@ -1785,24 +1785,28 @@
 t(hash%5Bi%5D);%0A
+    
         var 
@@ -1862,16 +1862,20 @@
         
+    
 operator
@@ -1911,129 +1911,223 @@
     
-%7D%0A
     
-narrow.activate(operators, %7B%0A        select_first_unread: true,%0A    
+%7D catch (err) %7B%0A            return undefined;%0A        %7D%0A    %7D%0A    return operators;%0A%7D%0A%0Afunction activate_home_tab() %7B%0A
     
+ui.
 change_
-hash:    false  // already set%0A    %7D
+tab_to(%22#home%22);%0A    narrow.deactivate();%0A    ui.update_floating_recipient_bar(
 );%0A%7D
@@ -3174,16 +3174,32 @@
         
+ var operators =
  parse_n
@@ -3227,142 +3227,289 @@
     
-ui.update_floating_recipient_bar();%0A            return true;%0A        case %22%22:%0A        case %22#%22:%0A            ui.change_tab_to(%22#home%22);
+if (operators === undefined) %7B%0A                // If the narrow URL didn't parse, clear%0A                // window.location.hash and send them to the home tab%0A                window.location.hash = '';%0A                activate_home_tab();%0A                return false;%0A            %7D
 %0A   
@@ -3516,34 +3516,32 @@
          narrow.
-de
 activate();%0A    
@@ -3537,55 +3537,271 @@
 ate(
-);%0A            ui.update_floating_recipient_bar
+operators, %7B%0A                select_first_unread: true,%0A                change_hash:    false  // already set%0A            %7D);%0A            ui.update_floating_recipient_bar();%0A            return true;%0A        case %22%22:%0A        case %22#%22:%0A            activate_home_tab
 ();%0A

Handle malformed narrow URLs gracefully.