/*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/
// THIS IS AN AUTOMATICALLY COMBINED FILE. PLEASE EDIT source/*.js!!



/******************************************
 Fetched from source/base-http-extensions.js
******************************************/

// URL calls currently 'in escrow'. This controls the spinny wheel animation
var async_escrow = {}
var async_maxwait = 250; // ms to wait before displaying spinner
var async_status = 'clear';
var async_cache = {}

// Escrow spinner check
async function escrow_check() {
    let now = new Date();
    let show_spinner = false;
    for (var k in async_escrow) {
        if ( (now - async_escrow[k]) > async_maxwait ) {
            show_spinner = true;
            break;
        }
    }
    // Fetch or create the spinner
    let spinner = document.getElementById('spinner');
    if (!spinner) {
        spinner = new HTML('div', { id: 'spinner', class: 'spinner'});
        spinwheel = new HTML('div', {id: 'spinwheel', class: 'spinwheel'});
        spinner.inject(spinwheel);
        spinner.inject(new HTML('h2', {}, "Loading, please wait.."));
        document.body.appendChild(spinner);
    }
    // Show or don't show spinner?
    if (show_spinner) {
        spinner.style.display = 'block';
        if (async_status === 'clear') {
            console.log("Waiting for JSON resource, deploying spinner");
            async_status = 'waiting';
        }
    } else {
        spinner.style.display = 'none';
        if (async_status === 'waiting') {
            console.log("All URLs out of escrow, dropping spinner");
            async_status = 'clear';
        }
    }
}

async function async_snap(error) {
    msg = await error.text();
    msg = msg.replace(/<.*?>/g, ""); // strip HTML tags
    modal("An error occured", "An error code %u occured while trying to fetch %s:\n%s".format(error.status, error.url, msg), "error");
}


// Asynchronous GET call
async function GET(url, callback, state) {
    console.log("Fetching JSON resource at %s".format(url))
    let pkey = "GET-%s-%s".format(callback, url);
    let res = undefined;
    let res_json = undefined;
    state = state || {};
    state.url = url;
    if (state && state.cached === true && async_cache[url]) {
        console.log("Fetching %s from cache".format(url));
        res_json = async_cache[url];
    }
    else {
        try {
            console.log("putting %s in escrow...".format(url));
            async_escrow[pkey] = new Date(); // Log start of request in escrow dict
            const rv = await fetch(url, {credentials: 'same-origin'}); // Wait for resource...
            
            // Since this is an async request, the request may have been canceled
            // by the time we get a response. Only do callback if not.
            if (async_escrow[pkey] !== undefined) {
                delete async_escrow[pkey]; // move out of escrow when fetched
                res = rv;
            }
        }
        catch (e) {
            delete async_escrow[pkey]; // move out of escrow if failed
            console.log("The URL %s could not be fetched: %s".format(url, e));
            modal("An error occured", "An error occured while trying to fetch %s:\n%s".format(url, e), "error");
        }
    }
    if (res !== undefined || res_json !== undefined) {
        // We expect a 2xx return code (usually 200 or 201), snap otherwise
        if ((res_json) || (res.status >= 200 && res.status < 300)) {
            console.log("Successfully fetched %s".format(url))
            if (res_json) {
                js = res_json;
            } else {
                js = await res.json();
                async_cache[url] = js;
            }
            if (callback) {
                callback(state, js);
            } else {
                console.log("No callback function was registered for %s, ignoring result.".format(url));
            }
        } else {
            console.log("URL %s returned HTTP code %u, snapping!".format(url, res.status));
            async_snap(res);
        }
    }
}


/******************************************
 Fetched from source/base-js-extensions.js
******************************************/

/**
 * String formatting prototype
 * A'la printf
 */

String.prototype.format = function() {
  let args = arguments;
  let n = 0;
  let t = this;
  let rtn = this.replace(/(?!%)?%([-+]*)([0-9.]*)([a-zA-Z])/g, function(m, pm, len, fmt) {
      len = parseInt(len || '1');
      // We need the correct number of args, balk otherwise, using ourselves to format the error!
      if (args.length <= n) {
        let err = "Error interpolating string '%s': Expected at least %u argments, only got %u!".format(t, n+1, args.length);
        console.log(err);
        throw err;
      }
      let varg = args[n];
      n++;
      switch (fmt) {
        case 's':
          if (typeof(varg) == 'function') {
            varg = '(function)';
          }
          return varg;
        // For now, let u, d and i do the same thing
        case 'd':
        case 'i':
        case 'u':
          varg = parseInt(varg).pad(len); // truncate to Integer, pad if needed
          return varg;
      }
    });
  return rtn;
}


/**
 * Number prettification prototype:
 * Converts 1234567 into 1,234,567 etc
 */

Number.prototype.pretty = function(fix) {
  if (fix) {
    return String(this.toFixed(fix)).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
  }
  return String(this.toFixed(0)).replace(/(\d)(?=(\d{3})+$)/g, '$1,');
};


/**
 * Number padding
 * usage: 123.pad(6) -> 000123
 */

Number.prototype.pad = function(n) {
  var str;
  str = String(this);

  /* Do we need to pad? if so, do it using String.repeat */
  if (str.length < n) {
    str = "0".repeat(n - str.length) + str;
  }
  return str;
};


/* Func for converting a date to YYYY-MM-DD HH:MM */

Date.prototype.ISOBare = function() {
  var M, d, h, m, y;
  y = this.getFullYear();
  m = (this.getMonth() + 1).pad(2);
  d = this.getDate().pad(2);
  h = this.getHours().pad(2);
  M = this.getMinutes().pad(2);
  return y + "-" + m + "-" + d + " " + h + ":" + M;
};


/* isArray: function to detect if an object is an array */

isArray = function(value) {
  return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
};


/* isHash: function to detect if an object is a hash */

isHash = function(value) {
  return value && typeof value === 'object' && !isArray(value);
};


/* Remove an array element by value */

Array.prototype.remove = function(val) {
  var i, item, j, len;
  for (i = j = 0, len = this.length; j < len; i = ++j) {
    item = this[i];
    if (item === val) {
      this.splice(i, 1);
      return this;
    }
  }
  return this;
};


/* Check if array has value */
Array.prototype.has = function(val) {
  var i, item, j, len;
  for (i = j = 0, len = this.length; j < len; i = ++j) {
    item = this[i];
    if (item === val) {
      return true;
    }
  }
  return false;
};




/******************************************
 Fetched from source/body-fixups.js
******************************************/

ponymail_url_regex = new RegExp("(" + "(?:(?:[a-z]+)://)" + "(?:\\S+(?::\\S*)?@)?" + "(?:" + "([01][0-9][0-9]|2[0-4][0-9]|25[0-5])" + "|" + "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" + "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" + "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" + "\\.?" + ")" + "(?::\\d{2,5})?" + "(?:[/?#]([^,<>()\\[\\] \\t\\r\\n]|(<[^:\\s]*?>|\\([^:\\s]*?\\)|\\[[^:\\s]*?\\]))*)?" + ")\\.?", "mi");

// Regex for things to potentially put inside quote objects:
// - quotes
// - forwarded emails
// - inline quoting
// - top posting with original email following
ponymail_quote_regex = new RegExp("(" +
  // Typical encapsulation of context by ticketing systems and/or bug trackers
  "(---\\r?\\n([^\\r\\n]*?\\r?\\n)*?---$)|" +
  "(" +
    "(?:\\r?\\n|^)" +  // start of line or after a colon
    // Classic method; a signal line and the quote with '>' starting each line quoted
    "(" +
      "(" + // Initial line signalling a quote
        "((\\d+-\\d+-\\d+)\\s+.+<\\S+@\\S+>:[ \t\r\n]+)|" +  // "01-02-1982 Foo Bar <foo@bar.baz>:" OR
        "(on\\s+(.+|.+\\n.+)\\s+wrote:[\r?\n]+)|" +          // "On $somedate, $someone wrote:", OR...
        "(le\\s+(.+|.+\\n.+)\\s+écrit:[\r?\n]+)|" +          // French version of the above, OR...
        "(.?am .+? schrieb\\s+.+:[\r?\n]+)|" +               // German version of the above, OR...
        "(envoy[ée] de mon .+|sent from my .+|von meinem .+ gesendet)[ \t\r\n]+" + // "sent from my iphone/ipad/android phone/whatever", usually means the next part is a quote.
      ")" + // End initial signal line
      "(^$)*" + // Accept blank newlines following it...
      "(((^(?!>)[\\s\\S]+$)*)|(^\\s*>[\\s\\S]+$)*)" +  // Either text that follows immediately after with no '>' first, OR text with '>' first, but NOT both...
    ")|" +
      "(" +
        // Lines after the signal line; comes in one shape, generally speaking...
        "(^\\s*>+[ \\t]*[^\r\n]*\r*\n+)+" + // Lines beginning with one or more '>' after the initial signal line
      ")" +      
    ")+|" + //OR...
    "(" +
      "^(-{5,10}).+?\\1[\r\n]+" + // ----- Forwarded Message -----
      "(^\\w+:\\s+.+[\r\n]+){3,10}[\r\n]+" + // Between three and ten header fields (we ask for at least 3, so as to not quote PGP blocks)
      "[\\S\\s]+" + // Whatever comes next...
    ")+" +
    ")", "mi");

// Somewhat simplified method for catching email footers/trailers that we don't need
ponymail_trailer_regex = new RegExp("^--[\r\n]+.*", "mi");//(--\r?\n([^\r\n]*?\r?\n){1,6}$)|[\r\n.]+^((--+ \r?\n|--+\r?\n|__+\r?\n|--+\\s*[^\r\n]+\\s*--+\r?\n)(.*\r?\n)+)+$", "m");

// This is a regex for capturing code diff blocks in an email
ponymail_diff_regex = new RegExp(
  "(" +
  "^-{3} .+?[\r\n]+" + // Starts with a "--- /foo/bar/baz"
  "^\\+{3} .+?[\r\n]+" + // Then a "+++ /foo/bar/baz"
  "(" + // Then one or more of...
    "^@@ .+[\r\n]+" + // positioning
    "(^ .*[\r\n]*$){0,3}" + // diff header
    "(^[-+ ].*[\r\n]*)+" + // actual diff
    "(^ .*[\r\n]*$){0,3}" + // diff trailer
  ")+" +
  ")", "mi");

// Function for turning URLs into <a> tags
function fixup_urls(splicer) {
    
    if (typeof splicer == 'object') {
      return splicer;
        //splicer = splicer.innerText;
    }
    /* Array holding text and links */
    var i, m, t, textbits, url, urls;
    textbits = [];

    /* Find the first link, if any */
    i = splicer.search(ponymail_url_regex);
    urls = 0;

    /* While we have more links, ... */
    while (i !== -1) {
      urls++;

      /* Only parse the first 250 URLs... srsly */
      if (urls > 250) {
        break;
      }

      /* Text preceding the link? add it to textbits frst */
      if (i > 0) {
        t = splicer.substr(0, i);
        textbits.push(t);
        splicer = splicer.substr(i);
      }

      /* Find the URL and cut it out as a link */
      m = splicer.match(ponymail_url_regex);
      if (m) {
        url = m[1];
        i = url.length;
        t = splicer.substr(0, i);
        textbits.push(new HTML('a', {
          href: url
        }, url));
        splicer = splicer.substr(i);
      }

      /* Find the next link */
      i = splicer.search(ponymail_url_regex);
    }

    /* push the remaining text into textbits */
    textbits.push(splicer);
    return textbits;
}


// Simple check to (attempt to) assess whether a trailer should
// remain or get cut out.
function legit_trailer(a) {
  let lines = a.split(/\s*\r?\n/);
  let first_line = lines.shift();
  while (first_line.length == 0 && lines.length) first_line = lines.shift(); // get first meaningful line
  if (!lines.length || first_line == '--') return ''; // likely a simple trailer
  let last_line = lines.pop();
  while (last_line.length == 0 && lines.length) last_line = lines.pop(); // get last meaningful line
  
  // Check if first and last line are similar, which is usually indictive of a ticket system
  if (last_line == first_line) {
    return a;
  }
  // Otherwise, check if first line has two or more dashes, and it occurs again later (also tix)
  if (first_line.match(/^---+/) && lines.has(first_line)) {
    return "|||" + a + "|||";
  }
  
  // Lastly, if there is "sufficient" length to the dashes, allow (JIRA etc)
  if (first_line.match(/^-{6,72}$/)) return a;
  return '';
}

// Function for cutting away trailers
function cut_trailer(splicer) {
    if (!chatty_layout) return splicer; // only invoke in social rendering mode
    if (typeof splicer == 'object') {
        splicer.innerText = splicer.innerText.replace(ponymail_trailer_regex, legit_trailer, 3);
    } else {
        splicer = splicer.replace(ponymail_trailer_regex, legit_trailer);

    }
    return splicer;
}

function color_diff_lines(diff) {
  let lines = diff.split(/[\r\n]+/);
  let ret = [];
  for (var z = 0; z < lines.length;z++) {
    let line = lines[z];
    let color = 'grey';
    if (line[0] == '@') color = 'blue';
    if (line[0] == '-') color = 'red';
    if (line[0] == '+') color = 'green';
    if (line[0] == ' ') color = 'black';
    let el = new HTML('span', {style: {color: color}}, line);
    ret.push(el);
    ret.push(new HTML('br'));
  }
  return ret;
}

// Function for coloring diffs
function fixup_diffs(splicer) {
    if (!chatty_layout) return splicer; // only invoke in social rendering mode
    if (typeof splicer == 'object') {
        splicer = splicer.innerText;
    }
    /* Array holding text and links */
    var i, m, t, diff, diffs;
    let textbits = [];

    /* Find the first link, if any */
    i = splicer.search(ponymail_diff_regex);
    diffs = 0;

    /* While we have more links, ... */
    while (i !== -1) {
      diffs++;

      /* Only parse the first 20 diffs... srsly */
      if (diffs > 25) {
        break;
      }
      console.log(i);
      /* Text preceding the diff? add it to textbits frst */
      if (i > 0) {
        t = splicer.substr(0, i);
        textbits.push(t);
        splicer = splicer.substr(i);
      }

      /* Find the URL and cut it out as a link */
      m = splicer.match(ponymail_diff_regex);
      if (m) {
        diff = m[1];
        i = diff.length;
        t = splicer.substr(0, i);
        textbits.push(new HTML('pre', {class: 'diff'}, color_diff_lines(diff)));
        splicer = splicer.substr(i);
      }

      /* Find the next link */
      i = splicer.search(ponymail_diff_regex);
    }

    /* push the remaining text into textbits */
    textbits.push(splicer);
    return textbits;
}

// Function for turning quotes into quote segments
function fixup_quotes(splicer) {
    if (splicer[splicer.length-1] !== "\n") splicer += "\n"; //tweak to make quotes match the last line if no newline on it.
    var hideQuotes, i, m, qdiv, quote, quotes, t, textbits;
    hideQuotes = true;
    if (prefs.compactQuotes === false && !chatty_layout) {
      hideQuotes = false;
    }
    if (!hideQuotes) return splicer; // We'll bail here for now. Dunno why not.

    /* Array holding text and quotes */
    textbits = [];

    /* Find the first quote, if any */
    i = splicer.search(ponymail_quote_regex);
    quotes = 0;

    /* While we have more quotes, ... */
    while (i !== -1) {
      quotes++;

      /* Only parse the first 50 quotes... srsly */
      if (quotes > 50) {
        break;
      }

      /* Text preceding the quote? add it to textbits first */
      if (i > 0) {
        t = splicer.substr(0, i);
        let diffed = fixup_diffs(cut_trailer(t));
        if (isArray(diffed)) { for(var z = 0; z < diffed.length; z++) textbits.push(fixup_urls(diffed[z]));}
        else textbits.push(fixup_urls(diffed));
        splicer = splicer.substr(i);
      }

      /* Find the quote and cut it out as a div */
      m = splicer.match(ponymail_quote_regex);
      if (m) {
        quote = m[0];
        i = quote.length;
        t = splicer.substr(0, i);
        quote = quote.replace(/(>*\s*\r?\n)+$/g, "");
        qdiv = new HTML('div', {
          "class": "email_quote_parent"
        }, [
          new HTML('button', {
            title: "Toggle quote",
            onclick: "toggle_quote(this)"
          }, new HTML('span', {class:'glyphicon glyphicon-comment'}, " ")), new HTML('br'), new HTML('blockquote', {
            "class": "email_quote",
            style: {
              display: hideQuotes ? 'none' : 'block'
            }
          }, fixup_urls(quote))
        ]);
        textbits.push(qdiv);
        splicer = splicer.substr(i);
      }

      /* Find the next quotes */
      i = splicer.search(ponymail_quote_regex);
    }

    /* push the remaining text into textbits */
    let diffed = fixup_diffs(cut_trailer(splicer));
    if (isArray(diffed)) { for(var z = 0; z < diffed.length; z++) diffed[z] = fixup_urls(diffed[z]);}
    else diffed = fixup_urls(diffed);
    textbits.push(new HTML('span', {}, diffed));
    
    return textbits;
  }
  
function toggle_quote(el) {
    let quote = el.parentNode.childNodes[2];
    if (quote.style.display != 'block') {
        quote.style.display = 'block';
    } else {
        quote.style.display = 'none';
    }
}

/******************************************
 Fetched from source/composer.js
******************************************/

let mua_trigger = 'mailto:';
let mua_list = null;
let mua_mid = null;
let mua_headers = {};

function compose_send() {
    let of = [];
    for (let k in mua_headers) {
        of.push(k + "=" + encodeURIComponent(mua_headers[k]));
    }
    // Push the subject and email body into the form data
    of.push("subject=" + encodeURIComponent(document.getElementById('composer_subject').value));
    of.push("body=" + encodeURIComponent(document.getElementById('composer_body').value));
    if (ponymail_preferences.login && ponymail_preferences.login.alternates && document.getElementById('composer_alt')) {
        of.push("alt=" + encodeURIComponent(document.getElementById('composer_alt').options[document.getElementById('composer_alt').selectedIndex].value));
    }
    
    let request = new XMLHttpRequest();
    request.open("POST", "/api/compose.lua");
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.send(of.join("&")); // send email as a POST string
    
    document.getElementById('composer_modal').style.display = 'none';
    modal("Message dispatched!", "Your email has been sent. Depending on moderation rules, it may take a while before it shows up in the archives.", "help");
}

function compose_email(replyto, list) {
    let email = null;
    let loggedIn = (ponymail_preferences.login && ponymail_preferences.login.credentials) ? true : false;
    if (replyto) email = full_emails[replyto||''];
    let listname = list;
    mua_headers = {};
    if (email) {
        listname = email.list_raw.replace(/[<>]/g, '').replace('.', '@', 1);
        mua_trigger = mua_link(email);
        if (email['message-id'] && email['message-id'].length > 0) mua_headers['in-reply-to'] = email['message-id'];
        if (email['message-id'] && email['message-id'].length > 0) mua_headers.references = email['message-id'];
        mua_headers.eid = email.mid;
    } else {
        mua_trigger = mua_link(null, listname);
    }
    mua_list = listname;
    mua_headers.to = listname;
    mua_mid = email ? email['message-id'] : null;
    
    // Not logged in? MUA it is, then!
    if (!loggedIn) {
        if (email) {
            let a = new HTML('a', {href: mua_trigger}, "Reply via your own email client");
            let p = new HTML('p', {}, [
                                   "In order to reply to emails using the web interface, you need to be ",
                                   new HTML('a', {href: '/oauth.html'}, "logged in first"),
                                   ". You can however still reply to this email using your own email client: ",
                                   a
                                  ]
                             );
            composer("Reply to thread:", p);
            return;
        }
    }
    
    // Replying to an email and logged in?
    let eml_subject = "";
    let eml_body = "";
    let eml_title = `Start a new thread on ${listname}:`;
    if (email) {
        eml_subject = "Re: " + email.subject;
        eml_body = composer_re(email);
        eml_title = `Reply to email on ${listname}:`;
    }
    let form = [];
    form.push(new HTML('b', {}, "Sending as:"));
    let s = new HTML('select', { id: 'composer_alt' });
    s.inject(new HTML('option', {}, ponymail_preferences.login.credentials.email));
    if (ponymail_preferences.login && ponymail_preferences.login.alternates) {
        for (let z = 0; z < ponymail_preferences.login.alternates.length; z++) {
            s.inject(new HTML('option', {}, ponymail_preferences.login.alternates[z]));
        }
    }
    form.push(new HTML('br'));
    form.push(s);
    form.push(new HTML('br'));
    form.push(new HTML('b', {}, "Subject:"));
    form.push(new HTML('br'));
    form.push(new HTML('input', {style: { width: '90%'}, id: 'composer_subject', type: 'text', value: eml_subject}));
    form.push(new HTML('br'));
    form.push(new HTML('b', {}, "Reply:"));
    form.push(new HTML('br'));
    let body = new HTML('textarea', {style: { width: '90%', minHeight: '400px'}, id: 'composer_body'}, eml_body);
    form.push(body);
    
    let btn = new HTML('button', { onclick: 'compose_send();'}, "Send reply");
    form.push(btn);
    form.push("   ");
    form.push(new HTML('a', {href: mua_trigger, style: { marginLeft: '10px'}}, "Or compose via your own email client"));
    
    composer(eml_title, form);
    if (email) document.getElementById('composer_body').focus();

}



// Generic modal function
function composer(title, contents) {
    let modal = document.getElementById('composer_modal');
    if (modal == undefined) {
        modal = new HTML('div', { id: 'composer_modal'}, [
            new HTML('div', {id: 'composer_modal_content'}, [
                    new HTML('span', {id: 'composer_modal_close', onclick: 'document.getElementById("composer_modal").style.display = "none";'}, 'X'),
                    new HTML('h2', {id: 'composer_modal_title'}, title),
                    new HTML('div', {id: 'composer_modal_contents'}, contents)
                    ])
            ]);
        document.body.appendChild(modal);
        
    } else {
        document.getElementById('composer_modal_title').innerText = title;
        document.getElementById('composer_modal_contents').innerHTML = '';
        document.getElementById('composer_modal_contents').inject(contents||'');
    }
    modal.style.display = 'block';
}

// Constructor for email body in replies...
function composer_re(email) {
    let lines = email.body.split(/\r?\n/);
    for (let i = 0; i < lines.length; i++) {
        lines[i] = '> ' + lines[i];
    }
    let re = `\n\nOn ${email.date} ${email.from.replace(/\s*<.+?>/, '')} wrote:\n`;
    re += lines.join("\n");
    return re;
}

// MUA mailto: link generator
function mua_link(email, xlist) {
    if (!email && xlist) {
        return `mailto:${xlist}?subject=Subject+goes+here`;
    }
    let eml_raw_short = composer_re(email);
    let subject = "RE: " + email.subject||'';
    let truncated = false;
    let N = 16000; // Anything above 16K can cause namespace issues with links.
    if (eml_raw_short.length > N) {
        truncated = true;
        eml_raw_short = eml_raw_short.substring(0, N) + "\n[message truncated...]";
    }
    let listname = email.list_raw.replace(/[<>]/g, '').replace('.', '@', 1);
    let xlink = 'mailto:' + listname + "?subject=" + encodeURIComponent(subject) + "&amp;In-Reply-To=" + encodeURIComponent(email['message-id']) + "&body=" + encodeURIComponent(eml_raw_short);
    return xlink;    
}

/******************************************
 Fetched from source/construct-thread.js
******************************************/

let current_open_email = null;

function expand_email_threaded(idx, flat) {
    let placeholder = document.getElementById('email_%u'.format(idx));
    if (placeholder) {
        // Check if email is already visible - if so, hide it!
        if (placeholder.style.display == 'block') {
            console.log("Collapsing thread at index %u".format(idx));
            placeholder.style.display = 'none';
            current_email_idx = undefined;
            return false;
        }
        current_email_idx = idx;
        console.log("Expanding thread at index %u".format(idx));
        placeholder.style.display = 'block';

        // Check if we've already filled out the structure here
        if (placeholder.getAttribute('data-filled') == 'yes') {
            console.log("Already constructed this thread, bailing!");
        } else {
            // Construct the base scaffolding for all emails
            let eml = flat ? current_json.emails[idx] : current_json.thread_struct[idx];
            if (eml) {
                current_open_email = eml.tid || eml.mid;
            }
            let thread = construct_thread(eml);
            placeholder.inject(thread);
            placeholder.setAttribute("data-filled", 'yes');
        }
    }
    return false;
}

function construct_thread(thread, cid, nestlevel, included) {
    // First call on a thread/email, this is indef.
    // Use this to plop a scroll call when loaded
    // to prevent weird cache-scrolling
    let doScroll = false;
    if (cid === undefined) {
        doScroll = true;
    }
    included = included||[];
    cid = (cid || 0) + 1;
    nestlevel = (nestlevel||0) + 1;
    let mw = calc_email_width();
    let max_nesting = ponymail_max_nesting;
    if (mw < 700) {
        max_nesting = Math.floor(mw/250);
    }
    cid %= 5;
    let color = ['286090', 'ccab0a', 'c04331', '169e4e', '6d4ca5'][cid];
    let email = undefined;
    if (nestlevel < max_nesting) {
        email = new HTML('div', { class: 'email_wrapper', id: 'email_%s'.format(thread.tid||thread.id)});
        if (chatty_layout) {
            email.style.border = "none !important";
        } else {
            email.style.borderLeft = '3px solid #%s'.format(color);
        }
    } else {
        email = new HTML('div', { class: 'email_wrapper_nonest', id: 'email_%s'.format(thread.tid||thread.id)});
    }
    let wrapper = new HTML('div', { class: 'email_inner_wrapper', id: 'email_contents_%s'.format(thread.tid||thread.id)});
    email.inject(wrapper);
    if (isArray(thread.children)) {
        thread.children.sort((a,b) => a.epoch - b.epoch);
        for (var i = 0; i < thread.children.length; i++) {
            let reply = construct_thread(thread.children[i], cid, nestlevel, included);
            cid++;
            if (reply) {
                email.inject(reply);
            }
        }
    }
    let tid = thread.tid||thread.id;
    if (!included.includes(tid)) {
        included.push(tid);
        console.log("Loading email %s".format(tid));
        GET("%sapi/email.lua?id=%s".format(apiURL, tid), render_email, {cached: true, scroll: doScroll, id: tid, div: wrapper});
    }
    return email;
}

// Singular thread construction via permalinks
function construct_single_thread(state, json) {
    current_json = json;
    if (json && json.error) {
        modal("An error occured", "Sorry, we hit a snag while trying to load the email(s): \n\n%s".format(json.error), "error");
        return;
    }
    let div = document.getElementById('emails');
    div.innerHTML = "";
    if (chatty_layout) {
        let listname = json.thread.list_raw.replace(/[<>]/g, '').replace('.', '@', 1);
        div.setAttribute("class", "email_placeholder_chatty");
        div.inject(new HTML('h4', {class: 'chatty_title'}, json.emails[0].subject));
        div.inject(new HTML('a', {href: 'list.html?%s'.format(listname), class: 'chatty_title'}, 'Posted to %s'.format(listname)));
    } else {
        div.setAttribute("class", "email_placeholder");
    }
    div.style.display = "block";
    let thread = json.thread;
    let email = construct_thread(thread);
    div.inject(email);
}


/******************************************
 Fetched from source/datepicker.js
******************************************/

var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var datepicker_spawner = null
var calendarpicker_spawner = null
var units = {
    w: 'week',
    d: 'day',
    M: 'month',
    y: 'year'
}

function fixupPicker(obj) {
    obj.addEventListener("focus", function(event){
        $('html').on('hide.bs.dropdown', function (e) {
            return false;
        });
    });
    obj.addEventListener("blur", function(event){
        $('html').unbind('hide.bs.dropdown')
    });
}
// makeSelect: Creates a <select> object with options
function makeSelect(options, id, selval) {
    var sel = document.createElement('select')
    sel.addEventListener("focus", function(event){
        $('html').on('hide.bs.dropdown', function (e) {
            return false;
        });
    });
    sel.addEventListener("blur", function(event){
        $('html').unbind('hide.bs.dropdown')
    });
    sel.setAttribute("name", id)
    sel.setAttribute("id", id)
    // For each options element, create it in the DOM
    for (var key in options) {
        var opt = document.createElement('option')
        // Hash or array?
        if (typeof key == "string") {
            opt.setAttribute("value", key)
            // Option is selected by default?
            if (key == selval) {
                opt.setAttribute("selected", "selected")
            }
        } else {
            // Option is selected by default?
            if (options[key] == selval) {
                opt.setAttribute("selected", "selected")
            }
        }
        opt.text = options[key]
        sel.appendChild(opt)
    }
    return sel
}

// splitDiv: Makes a split div with 2 elements,
// and puts div2 into the right column,
// and 'name' as text in the left one.
function splitDiv(id, name, div2) {
    var div = document.createElement('div')
    var subdiv = document.createElement('div')
    var radio = document.createElement('input')
    radio.setAttribute("type", "radio")
    radio.setAttribute("name", "datepicker_radio")
    radio.setAttribute("value", name)
    radio.setAttribute("id", "datepicker_radio_" + id)
    radio.setAttribute("onclick", "calcTimespan('"+ id + "')")
    var label = document.createElement('label')
    label.innerHTML = "&nbsp; " + name + ": "
    label.setAttribute("for", "datepicker_radio_" + id)
    
    
    subdiv.appendChild(radio)
    subdiv.appendChild(label)
    
    
    subdiv.style.float = "left"
    div2.style.float = "left"
    
    subdiv.style.width = "120px"
    subdiv.style.height = "48px"
    div2.style.height = "48px"
    div2.style.width = "250px"
    
    div.appendChild(subdiv)
    div.appendChild(div2)
    return div
}

// calcTimespan: Calculates the value and representational text
// for the datepicker choice and puts it in the datepicker's
// spawning input/select element.
function calcTimespan(what) {
    var wat = ""
    var tval = ""
    
    // Less than N units ago?
    if (what == 'lt') {
        // Get unit and how many units
        var N = document.getElementById('datepicker_lti').value
        var unit = document.getElementById('datepicker_lts').value
        var unitt = units[unit]
        if (parseInt(N) != 1) {
            unitt += "s"
        }
        
        // If this makes sense, construct a humanly readable and a computer version
        // of the timespan
        if (N.length > 0) {
            wat = "Less than " + N + " " + unitt + " ago"
            tval = "lte=" + N + unit
        }
    }
    
    // More than N units ago?
    if (what == 'mt') {
        // As above, get unit and no of units.
        var N = document.getElementById('datepicker_mti').value
        var unit = document.getElementById('datepicker_mts').value
        var unitt = units[unit]
        if (parseInt(N) != 1) {
            unitt += "s"
        }
        
        // construct timespan val + description
        if (N.length > 0) {
            wat = "More than " + N + " " + unitt + " ago"
            tval = "gte=" + N + unit
        }
    }
    
    // Date range?
    if (what == 'cd') {
        // Get From and To values
        var f = document.getElementById('datepicker_cfrom').value
        var t = document.getElementById('datepicker_cto').value
        // construct timespan val + description if both from and to are valid
        if (f.length > 0 && t.length > 0) {
            wat = "From " + f + " to " + t
            tval = "dfr=" + f + "|dto=" + t
        }
    }
    
    // If we calc'ed a value and spawner exists, update its key/val
    if (datepicker_spawner && what && wat.length > 0) {
        document.getElementById('datepicker_radio_' + what).checked = true
        if (datepicker_spawner.options) {
            datepicker_spawner.options[0].value = tval
            datepicker_spawner.options[0].text = wat
        } else if (datepicker_spawner.value) {
            datepicker_spawner.value = wat
            datepicker_spawner.setAttribute("data", tval)
        }
        
    }
}

// datePicker: spawns a date picker with various
// timespan options right next to the parent caller.
function datePicker(parent, seedPeriod) {
    datepicker_spawner = parent
    var div = document.getElementById('datepicker_popup')
    
    // If the datepicker object doesn't exist, spawn it
    if (!div) {
        div = document.createElement('div')
        var id = parseInt(Math.random() * 10000).toString(16)
        div.setAttribute("id", "datepicker_popup")
        div.setAttribute("class", "datepicker")
    }
    
    // Reset the contents of the datepicker object
    div.innerHTML = ""
    div.style.display = "block"
    
    // Position the datepicker next to whatever called it
    var bb = parent.getBoundingClientRect()
    div.style.top = (bb.bottom + 8) + "px"
    div.style.left = (bb.left + 32) + "px"
    
    
    // -- Less than N $units ago
    var ltdiv = document.createElement('div')
    var lti = document.createElement('input')
    lti.setAttribute("id", "datepicker_lti")
    lti.style.width = "48px"
    lti.setAttribute("onkeyup", "calcTimespan('lt')")
    lti.setAttribute("onblur", "calcTimespan('lt')")
    ltdiv.appendChild(lti)
    
    var lts = makeSelect({
        'd': "Day(s)",
        'w': 'Week(s)',
        'M': "Month(s)",
        'y': "Year(s)"
    }, 'datepicker_lts', 'm')
    lts.setAttribute("onchange", "calcTimespan('lt')")
    ltdiv.appendChild(lts)
    ltdiv.appendChild(document.createTextNode(' ago'))
    
    div.appendChild(splitDiv('lt', 'Less than', ltdiv))
    
    
    // -- More than N $units ago
    var mtdiv = document.createElement('div')
    
    var mti = document.createElement('input')
    mti.style.width = "48px"
    mti.setAttribute("id", "datepicker_mti")
    mti.setAttribute("onkeyup", "calcTimespan('mt')")
    mti.setAttribute("onblur", "calcTimespan('mt')")
    mtdiv.appendChild(mti)
    
    
    var mts = makeSelect({
        'd': "Day(s)",
        'w': 'Week(s)',
        'M': "Month(s)",
        'y': "Year(s)"
    }, 'datepicker_mts', 'm')
    mtdiv.appendChild(mts)
    mts.setAttribute("onchange", "calcTimespan('mt')")
    mtdiv.appendChild(document.createTextNode(' ago'))
    div.appendChild(splitDiv('mt', 'More than', mtdiv))
    
    
    
    // -- Calendar timespan
    // This is just two text fields, the calendarPicker sub-plugin populates them
    var cdiv = document.createElement('div')
    
    var cfrom = document.createElement('input')
    cfrom.style.width = "90px"
    cfrom.setAttribute("id", "datepicker_cfrom")
    cfrom.setAttribute("onfocus", "showCalendarPicker(this)")
    cfrom.setAttribute("onchange", "calcTimespan('cd')")
    cdiv.appendChild(document.createTextNode('From: '))
    cdiv.appendChild(cfrom)
    
    var cto = document.createElement('input')
    cto.style.width = "90px"
    cto.setAttribute("id", "datepicker_cto")
    cto.setAttribute("onfocus", "showCalendarPicker(this)")
    cto.setAttribute("onchange", "calcTimespan('cd')")
    cdiv.appendChild(document.createTextNode('To: '))
    cdiv.appendChild(cto)
    
    div.appendChild(splitDiv('cd', 'Date range', cdiv))
    
    
    
    // -- Magic button that sends the timespan back to the caller
    var okay = document.createElement('input')
    okay.setAttribute("type", "button")
    okay.setAttribute("value", "Okay")
    okay.setAttribute("onclick", "setDatepickerDate()")
    div.appendChild(okay)
    parent.parentNode.appendChild(div)
    document.body.setAttribute("onclick", "")
    window.setTimeout(function() { document.body.setAttribute("onclick", "blurDatePicker(event)") }, 200)
    lti.focus()
    
    // This is for recalcing the set options if spawned from a
    // select/input box with an existing value derived from an
    // earlier call to datePicker
    var ptype = ""
    var pvalue = parent.hasAttribute("data") ? parent.getAttribute("data") : parent.value
    if (pvalue.search(/=|-/) != -1) {
        
        // Less than N units ago?
        if (pvalue.match(/lte/)) {
            var m = pvalue.match(/lte=(\d+)([dMyw])/)
            ptype = 'lt'
            if (m) {
                document.getElementById('datepicker_lti').value = m[1]
                var sel = document.getElementById('datepicker_lts')
                for (var i in sel.options) {
                    if (parseInt(i) >= 0) {
                        if (sel.options[i].value == m[2]) {
                            sel.options[i].selected = "selected"
                        } else {
                            sel.options[i].selected = null
                        }
                    }
                }
            }
            
        }
        
        // More than N units ago?
        if (pvalue.match(/gte/)) {
            ptype = 'mt'
            var m = pvalue.match(/gte=(\d+)([dMyw])/)
            if (m) {
                document.getElementById('datepicker_mti').value = m[1]
                var sel = document.getElementById('datepicker_mts')
                // Go through the unit values, select the one we use
                for (var i in sel.options) {
                    if (parseInt(i) >= 0) {
                        if (sel.options[i].value == m[2]) {
                            sel.options[i].selected = "selected"
                        } else {
                            sel.options[i].selected = null
                        }
                    }
                }
            }
        }
        
        // Date range?
        if (pvalue.match(/dfr/)) {
            ptype = 'cd'
            // Make sure we have both a dfr and a dto here, catch them
            var mf = pvalue.match(/dfr=(\d+-\d+-\d+)/)
            var mt = pvalue.match(/dto=(\d+-\d+-\d+)/)
            if (mf && mt) {
                // easy peasy, just set two text fields!
                document.getElementById('datepicker_cfrom').value = mf[1]
                document.getElementById('datepicker_cto').value = mt[1]
            }
        }
        // Month??
        if (pvalue.match(/(\d{4})-(\d+)/)) {
            ptype = 'cd'
            // Make sure we have both a dfr and a dto here, catch them
            var m = pvalue.match(/(\d{4})-(\d+)/)
            if (m.length == 3) {
                // easy peasy, just set two text fields!
                var dfrom = new Date(parseInt(m[1]),parseInt(m[2])-1,1, 0, 0, 0)
                var dto = new Date(parseInt(m[1]),parseInt(m[2]),0, 23, 59, 59)
                document.getElementById('datepicker_cfrom').value = m[0] + "-" + dfrom.getDate()
                document.getElementById('datepicker_cto').value = m[0] + "-" + dto.getDate()
            }
        }
        calcTimespan(ptype)
    }
}


function datePickerValue(seedPeriod) {
    // This is for recalcing the set options if spawned from a
    // select/input box with an existing value derived from an
    // earlier call to datePicker
    var ptype = ""
    var rv = seedPeriod
    if (seedPeriod && seedPeriod.search && seedPeriod.search(/=|-/) != -1) {
        
        // Less than N units ago?
        if (seedPeriod.match(/lte/)) {
            var m = seedPeriod.match(/lte=(\d+)([dMyw])/)
            ptype = 'lt'
            var unitt = units[m[2]]
            if (parseInt(m[1]) != 1) {
                unitt += "s"
            }
            rv = "Less than " + m[1] + " " + unitt + " ago"
        }
        
        // More than N units ago?
        if (seedPeriod.match(/gte/)) {
            ptype = 'mt'
            var m = seedPeriod.match(/gte=(\d+)([dMyw])/)
            var unitt = units[m[2]]
            if (parseInt(m[1]) != 1) {
                unitt += "s"
            }
            rv = "More than " + m[1] + " " + unitt + " ago"
        }
        
        // Date range?
        if (seedPeriod.match(/dfr/)) {
            ptype = 'cd'
            var mf = seedPeriod.match(/dfr=(\d+-\d+-\d+)/)
            var mt = seedPeriod.match(/dto=(\d+-\d+-\d+)/)
            if (mf && mt) {
                rv = "From " + mf[1] + " to " + mt[1]
            }
        }
        
        // Month??
        if (seedPeriod.match(/^(\d+)-(\d+)$/)) {
            ptype = 'mr' // just a made up thing...(month range)
            var mr = seedPeriod.match(/(\d+)-(\d+)/)
            if (mr) {
                dfrom = new Date(parseInt(mr[1]),parseInt(mr[2])-1,1, 0, 0, 0)
                rv = months[dfrom.getMonth()] + ', ' + mr[1]
            }
        }
        
    }
    return rv
}

function datePickerDouble(seedPeriod) {
    // This basically takes a date-arg and doubles it backwards
    // so >=3M becomes =>6M etc. Also returns the cutoff for
    // the original date and the span in days of the original
    var ptype = ""
    var rv = seedPeriod
    var dbl = seedPeriod
    var tspan = 1
    var dfrom = new Date()
    var dto = new Date()
    
    // datepicker range?
    if (seedPeriod && seedPeriod.search && seedPeriod.search(/=/) != -1) {
        
        // Less than N units ago?
        if (seedPeriod.match(/lte/)) {
            var m = seedPeriod.match(/lte=(\d+)([dMyw])/)
            ptype = 'lt'
            rv = "<" + m[1] + m[2] + " ago"
            dbl = "lte=" + (parseInt(m[1])*2) + m[2]
            
            // N months ago
            if (m[2] == "M") {
                dfrom.setMonth(dfrom.getMonth()-parseInt(m[1]), dfrom.getDate())
            }
            
            // N days ago
            if (m[2] == "d") {
                dfrom.setDate(dfrom.getDate()-parseInt(m[1]))
            }
            
            // N years ago
            if (m[2] == "y") {
                dfrom.setYear(dfrom.getFullYear()-parseInt(m[1]))
            }
            
            // N weeks ago
            if (m[2] == "w") {
                dfrom.setDate(dfrom.getDate()-(parseInt(m[1])*7))
            }
            
            // Calc total duration in days for this time span
            tspan = parseInt((dto.getTime() - dfrom.getTime() + 5000) / (1000*86400))
        }
        
        // More than N units ago?
        if (seedPeriod.match(/gte/)) {
            ptype = 'mt'
            var m = seedPeriod.match(/gte=(\d+)([dMyw])/)
            rv = ">" + m[1] + m[2] + " ago"
            dbl = "gte=" + (parseInt(m[1])*2) + m[2]
            tspan = parseInt(parseInt(m[1]) * 30.4)
            dfrom = null
            
            // Months
            if (m[2] == "M") {
                dto.setMonth(dto.getMonth()-parseInt(m[1]), dto.getDate())
            }
            
            // Days
            if (m[2] == "d") {
                dto.setDate(dto.getDate()-parseInt(m[1]))
            }
            
            // Years
            if (m[2] == "y") {
                dto.setYear(dto.getFullYear()-parseInt(m[1]))
            }
            
            // Weeks
            if (m[2] == "w") {
                dto.setDate(dto.getDate()-(parseInt(m[1])*7))
            }
            
            // Can't really figure out a timespan for this, so...null!
            // This also sort of invalidates use on the trend page, but meh..
            tspan = null
        }
        
        // Date range?
        if (seedPeriod.match(/dfr/)) {
            ptype = 'cd'
            // Find from and to
            var mf = seedPeriod.match(/dfr=(\d+)-(\d+)-(\d+)/)
            var mt = seedPeriod.match(/dto=(\d+)-(\d+)-(\d+)/)
            if (mf && mt) {
                rv = "from " + mf[1] + " to " + mt[1]
                // Starts at 00:00:00 on from date
                dfrom = new Date(parseInt(mf[1]),parseInt(mf[2])-1,parseInt(mf[3]), 0, 0, 0)
                
                // Ends at 23:59:59 on to date
                dto = new Date(parseInt(mt[1]),parseInt(mt[2])-1,parseInt(mt[3]), 23, 59, 59)
                
                // Get duration in days, add 5 seconds to we can floor the value and get an integer
                tspan = parseInt((dto.getTime() - dfrom.getTime() + 5000) / (1000*86400))
                
                // double the distance
                var dpast = new Date(dfrom)
                dpast.setDate(dpast.getDate() - tspan)
                dbl = seedPeriod.replace(/dfr=[^|]+/, "dfr=" + (dpast.getFullYear()) + '-' + (dpast.getMonth()+1) + '-' + dpast.getDate())
            } else {
                tspan = 0
            }
        }
    }
    
    // just N days?
    else if (parseInt(seedPeriod).toString() == seedPeriod.toString()) {
        tspan = parseInt(seedPeriod)
        dfrom.setDate(dfrom.getDate() - tspan)
        dbl = "lte=" + (tspan*2) + "d"
    }
    
    // Specific month?
    else if (seedPeriod.match(/^(\d+)-(\d+)$/)) {
        // just a made up thing...(month range)
        ptype = 'mr' 
        var mr = seedPeriod.match(/(\d+)-(\d+)/)
        if (mr) {
            rv = seedPeriod
            // Same as before, start at 00:00:00
            dfrom = new Date(parseInt(mr[1]),parseInt(mr[2])-1,1, 0, 0, 0)
            // end at 23:59:59
            dto = new Date(parseInt(mr[1]),parseInt(mr[2]),0, 23, 59, 59)
            
            // B-A, add 5 seconds so we can floor the no. of days into an integer neatly
            tspan = parseInt((dto.getTime() - dfrom.getTime() + 5000) / (1000*86400))
            
            // Double timespan
            var dpast = new Date(dfrom)
            dpast.setDate(dpast.getDate() - tspan)
            dbl = "dfr=" + (dpast.getFullYear()) + '-' + (dpast.getMonth()+1) + '-' + dpast.getDate() + "|dto=" + (dto.getFullYear()) + '-' + (dto.getMonth()+1) + '-' + dto.getDate()
        } else {
            tspan = 0
        }
    }
    
    return [dbl, dfrom, dto, tspan]
}

// set date in caller and hide datepicker again.
function setDatepickerDate() {
    calcTimespan()
    blurDatePicker()
}

// findParent: traverse DOM and see if we can find a parent to 'el'
// called 'name'. This is used for figuring out whether 'el' has
// lost focus or not.
function findParent(el, name) {
    if (el.getAttribute && el.getAttribute("id") == name) {
        return true
    }
    if (el.parentNode && el.parentNode.getAttribute) {
        if (el.parentNode.getAttribute("id") != name) {
            return findParent(el.parentNode, name)
        } else {
            return true
        }
    } else {
        return false;
    }
}

// function for hiding the date picker
function blurDatePicker(evt) {
    var es = evt ? (evt.target || evt.srcElement) : null;
    if ((!es || !es.parentNode || (!findParent(es, "datepicker_popup") && !findParent(es, "calendarpicker_popup"))) && !(es ? es : "null").toString().match(/javascript:void/)) {
        document.getElementById('datepicker_popup').style.display = "none"
        $('html').trigger('hide.bs.dropdown')
    }
}

// draws the actual calendar inside a calendarPicker object
function drawCalendarPicker(obj, date) {
    
    
    obj.focus()
    
    // Default to NOW for calendar.
    var now = new Date()
    
    // if called with an existing date (YYYY-MM-DD),
    // convert it to a JS date object and use that for
    // rendering the calendar
    if (date) {
        var ar = date.split(/-/)
        now = new Date(ar[0],parseInt(ar[1])-1,ar[2])
    }
    var days = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    var mat = now
    
    // Go to first day of the month
    mat.setDate(1)
    
    obj.innerHTML = "<h3>" + months[mat.getMonth()] + ", " + mat.getFullYear() + ":</h3>"
    var tm = mat.getMonth()
    
    // -- Nav buttons --
    
    // back-a-year button
    var a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + (mat.getFullYear()-1) + '-' + (mat.getMonth()+1) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.innerHTML = "≪"
    obj.appendChild(a)
    
    // back-a-month button
    a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + mat.getFullYear() + '-' + (mat.getMonth()) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.innerHTML = "&lt;"
    obj.appendChild(a)
    
    // forward-a-month button
    a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + mat.getFullYear() + '-' + (mat.getMonth()+2) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.innerHTML = "&gt;"
    obj.appendChild(a)
    
    // forward-a-year button
    a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + (mat.getFullYear()+1) + '-' + (mat.getMonth()+1) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.innerHTML = "≫"
    obj.appendChild(a)
    obj.appendChild(document.createElement('br'))
    
    
    // Table containing the dates of the selected month
    var table = document.createElement('table')
    
    table.setAttribute("border", "1")
    table.style.margin = "0 auto"
    
    // Add header day names
    var tr = document.createElement('tr');
    for (var m = 0; m < 7; m++) {
        var td = document.createElement('th')
        td.innerHTML = days[m]
        tr.appendChild(td)
    }
    table.appendChild(tr)
    
    // Until we hit the first day in a month, add blank days
    tr = document.createElement('tr');
    var weekday = mat.getDay()
    if (weekday == 0) {
        weekday = 7
    }
    weekday--;
    for (var i = 0; i < weekday; i++) {
        var td = document.createElement('td')
        tr.appendChild(td)
    }
    
    // While still in this month, add day then increment date by 1 day.
    while (mat.getMonth() == tm) {
        weekday = mat.getDay()
        if (weekday == 0) {
            weekday = 7
        }
        weekday--;
        if (weekday == 0) {
            table.appendChild(tr)
            tr = document.createElement('tr');
        }
        td = document.createElement('td')
        // onclick for setting the calendarPicker's parent to this val.
        td.setAttribute("onclick", "setCalendarDate('" + mat.getFullYear() + '-' + (mat.getMonth()+1) + '-' + mat.getDate() + "');")
        td.innerHTML = mat.getDate()
        mat.setDate(mat.getDate()+1)
        tr.appendChild(td)
    }
    
    table.appendChild(tr)
    obj.appendChild(table)
}

// callback for datePicker; sets the cd value to what date was picked
function setCalendarDate(what) {
    $('html').on('hide.bs.dropdown', function (e) {
        return false;
    });
    setTimeout(function() { $('html').unbind('hide.bs.dropdown');}, 250);
    
    
    calendarpicker_spawner.value = what
    var div = document.getElementById('calendarpicker_popup')
    div.parentNode.focus()
    div.style.display = "none"
    calcTimespan('cd')
}

// caller for when someone clicks on a calendarPicker enabled field
function showCalendarPicker(parent, seedDate) {
    calendarpicker_spawner = parent
    
    // If supplied with a YYYY-MM-DD date, use this to seed the calendar
    if (!seedDate) {
        var m = parent.value.match(/(\d+-\d+(-\d+)?)/)
        if (m) {
            seedDate = m[1]
        }
    }
    
    // Show or create the calendar object
    var div = document.getElementById('calendarpicker_popup')
    if (!div) {
        div = document.createElement('div')
        div.setAttribute("id", "calendarpicker_popup")
        div.setAttribute("class", "calendarpicker")
        document.getElementById('datepicker_popup').appendChild(div)
        div.innerHTML = "Calendar goes here..."
    }
    div.style.display = "block"
    var bb = parent.getBoundingClientRect()
    
    // Align with the calling object, slightly below
    div.style.top = (bb.bottom + 8) + "px"
    div.style.left = (bb.right - 32) + "px"
    
    drawCalendarPicker(div, seedDate)    
}

/******************************************
 Fetched from source/init.js
******************************************/

var ponymail_version = "1.0.1-Foal"  // Current version of Pony Mail
var ponymail_name = "Pony Mail" // name of archive (set to "Foo's mail archive" or whatever)

var hits_per_page = 10;
var apiURL = ''; // external API URL. Usually left blank.

// Stuff regarding what we're doing right now
var current_json = {};
var current_state = {};
var current_list = '';
var current_domain = '';
var current_year = 0;
var current_month = 0;
var current_quick_search = '';
var select_primed = false;
var ponymail_preferences = {};
var ponymail_search_list = 'this';

var current_listmode = 'threaded';
var ponymail_max_nesting = 10; // max nesting level before unthreading to save space

// thread state
var current_email_idx = undefined;
var chatty_layout = true;
var ponymail_date_format = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'};
var virtual_inbox_loading = false;
var collated_json = {};

// List auto-picker criteria
var boring_lists = ['commits', 'cvs', 'site-cvs', 'security', 'notifications']; // we'd rather not default to these, noisy!
var favorite_list = 'dev'; // if we have this, default to it
var long_tabs = false; // tab name format (long or short)

console.log("/******* Apache Pony Mail (Foal v/%s) Initializing ********/".format(ponymail_version))
// Adjust titles:
document.title = ponymail_name;
let titles = document.getElementsByClassName("title");
for (var i in titles) {
    titles[i].innerText = ponymail_name;
}

// check local storage for settings
console.log("Checking localStorage availability");
var can_store = false;
if (window.localStorage && window.localStorage.setItem) {
    try {
        window.localStorage.setItem("ponymail_test", "foo");
        can_store = true;
        console.log("localStorage available!");
    } catch (e) {
        console.log("no localStorage available!");
    }
}


console.log("Initializing escrow checks");
window.setInterval(escrow_check, 250);

console.log("Initializing key command logger");
window.addEventListener('keyup', keyCommands);

if (pm_config && pm_config.apiURL) {
    apiURL = pm_config.apiURL;
    console.log("Setting API URL to %s".format(apiURL));
}

window.addEventListener('load',function() {
        document.body.appendChild(new HTML('footer', {class: 'footer'}, [
            new HTML('div', { class: 'container'}, [
                new HTML('p', {class: 'muted'}, "Powered by Apache Pony Mail (Foal v/%s)".format(ponymail_version))
                ]
                )
            ])
        );
    }
    );
console.log("initializing pop state checker");
window.onpopstate = function(event) {
    console.log("Popping state");
    return parseURL({cached: true});
};


/******************************************
 Fetched from source/key-commands.js
******************************************/

// Generic modal function
function modal(title, msg, type, isHTML) {
    let modal = document.getElementById('modal');
    let text = document.getElementById('modal_text');
    if (modal == undefined) {
        text = new HTML('p', {id: 'modal_text'}, "");
        modal = new HTML('div', { id: 'modal'}, [
            new HTML('div', {id: 'modal_content'}, [
                    new HTML('span', {id: 'modal_close', onclick: 'document.getElementById("modal").style.display = "none";'}, 'X'),
                    new HTML('h2', {id: 'modal_title'}, title),
                    new HTML('div', {}, text)
                    ])
            ]);
        document.body.appendChild(modal);
        
    }
    if (type) {
        modal.setAttribute("class", "modal_" + type);
    } else {
        modal.setAttribute("class", undefined);
    }
    modal.style.display = 'block';
    document.getElementById('modal_title').innerText = title;
    // If we trust HTML, use it. Otherwise only show as textNode.
    if (isHTML) {
        text.innerHTML = msg;
    } else {
        msg = msg.replace(/<.*?>/g, ""); // strip HTML tags
        text.innerText = msg;
    }
}

// Helper for determining if an email is open or not...
function anyOpen() {
    let open = (current_email_idx !== undefined) ? true: false;
    console.log("Emails open? " + open);
    return open;
}

// Helper function for hiding windows and open tabs
// Hide previous action on first escape, hide everything on second escape
function hideWindows(force_all) {
    
    // First, check if we want to hide a modal
    let modal = document.getElementById('modal');
    if (modal && modal.style.display == 'block') {
        modal.style.display = 'none';
        if (force_all !== true) return;
    }
    
    // RThen, check if we want to hide a composer modal
    let cmodal = document.getElementById('composer_modal');
    if (cmodal && cmodal.style.display == 'block') {
        cmodal.style.display = 'none';
        if (force_all !== true) return;
    }
    
    // Check Advanced Search
    let as = document.getElementById('advanced_search');
    if (as && as.style.display == 'block') {
        as.style.display = 'none';
        if (force_all !== true) return;
    }
    
    // Check for individually opened email
    if (current_email_idx !== undefined) {
        console.log("Hiding placeholder at index %u".format(current_email_idx));
        let placeholder = document.getElementById('email_%u'.format(current_email_idx));
        if (placeholder) {
            placeholder.style.display = 'none';
        }
        current_email_idx = undefined; // undef this even if we can't find the email
        if (force_all !== true) return;
    }
    
    // if viewing a single thread, disregard the collapses below - the won't make sense!
    if (location.href.match(/thread\.html/)) return;
    
    // Finally, check for other opened emails, close 'em all
    let placeholders = document.getElementsByClassName('email_placeholder');
    for (var i = 0; i < placeholders.length; i++) {
        if (placeholders[i].style.display == 'block') {
            console.log("Hiding placeholder %s".format(placeholders[i].getAttribute('id')));
            placeholders[i].style.display = 'none';
            // Reset scroll cache
            try { window.scrollTo(0,0);} catch (e) {}
        }
    }
    
    placeholders = document.getElementsByClassName('email_placeholder_chatty');
    for (var i = 0; i < placeholders.length; i++) {
        if (placeholders[i].style.display == 'block') {
            console.log("Hiding placeholder %s".format(placeholders[i].getAttribute('id')));
            placeholders[i].style.display = 'none';
            // Reset scroll cache
            try { window.scrollTo(0,0);} catch (e) {}
        }
    }
    
}

// Show keyboard commands
function showHelp() {
    modal("Keyboard shortcuts:", "<pre><kbd>H</kbd>: Show this help window.\n<kbd>C</kbd>: Compose a new email to this list.\n<kbd>R</kbd>: Reply to the currently active thread.\n<kbd>S</kbd>: Go to the search bar.\n<kbd>Escape</kbd>: Hide modals or collapse threads.\n<kbd>RightArrow</kbd>: Go to next bunch of emails in list view.\n<kbd>LeftArrow</kbd>: Go to previous bunch of emails in list view.</pre>", "help", true);
}

// Function for capturing and evaluating key strokes
// If it matches a known shortcut, execute that then..
function keyCommands(e) {
    if (!e.ctrlKey) {
        // Get calling element and its type
        let target = e.target || e.srcElement;
        let type = target.tagName;
        // We won't jump out of an input field!
        if (['INPUT', 'TEXTAREA', 'SELECT'].has(type)) {
            return;
        }
        switch (e.key) {
            case 's':
                document.getElementById('q').focus();
                return;
            case 'h':
                showHelp();
                return;
            case 'c':
                compose_email(null, `${current_list}@${current_domain}`);
                return;
            case 'r':
                console.log(current_open_email);
                if (current_open_email && full_emails[current_open_email]) {
                    compose_email(current_open_email);
                }
                return;
            case 'Escape':
                hideWindows();
                return;
            case 'ArrowRight': // quick-next
                if (current_json) { // IF list view...
                    let blobs = current_json.emails;
                    if (current_listmode == 'threaded') blobs = current_json.thread_struct;
                    let no_emails = blobs.length;
                    if (current_email_idx == undefined && current_json && (current_index_pos + current_per_page) < no_emails) {
                        listview_header({pos: current_index_pos + current_per_page}, current_json);
                    }
                }
                return;
            case 'ArrowLeft': // quick previous
                if (current_json) { // IF list view...
                    let blobs = current_json.emails;
                    if (current_listmode == 'threaded') blobs = current_json.thread_struct;
                    let no_emails = blobs.length;
                    if (current_email_idx == undefined && current_json && (current_index_pos - current_per_page) >= 0) {
                        listview_header({pos: current_index_pos - current_per_page}, current_json);
                    }
                }
                return;
        }
        
    }
}

// swipe left/right for next/previous page on mobile
function ponymail_swipe(event) {
    // Only accept "big" swipes
    let len = Math.abs(event.swipestart.coords[0] - event.swipestop.coords[ 0 ]);
    let direction = event.swipestart.coords[0] > event.swipestop.coords[ 0 ] ? 'left' : 'right';
    console.log("swipe %s of %u pixels detected".format(direction, len));
    if (len < 20) return false;
    if (direction == 'right') {
        if (current_json) { // IF list view...
            let blobs = current_json.emails;
            if (current_listmode == 'threaded') blobs = current_json.thread_struct;
            let no_emails = blobs.length;
            if (current_email_idx == undefined && current_json && (current_index_pos - current_per_page) >= 0) {
                listview_header({pos: current_index_pos - current_per_page}, current_json);
            }
        }
    }
    else if (direction == 'left') {
        if (current_json) { // IF list view...
            let blobs = current_json.emails;
            if (current_listmode == 'threaded') blobs = current_json.thread_struct;
            let no_emails = blobs.length;
            if (current_email_idx == undefined && current_json && (current_index_pos + current_per_page) < no_emails) {
                listview_header({pos: current_index_pos + current_per_page}, current_json);
            }
        }
    }
    return false;
}

/******************************************
 Fetched from source/list-index.js
******************************************/

let list_json = {}

function list_index(state, json) {
    if (json) {
        list_json = json;
    }
    let lists = document.getElementById('list_picker_ul');
    if (state && state.letter) {
        let tab = undefined;
        let tabs = lists.childNodes;
        for (var i = 0; i < tabs.length; i++) {
            let xtab = tabs[i];
            if ((xtab.innerText == state.to || xtab.getAttribute('data-list') == state.to)) {
                tab = xtab;
                tab.setAttribute("class", 'active');
            } else {
                xtab.setAttribute("class", "");
            }
            
        }
        return;
    }
    else {
        let letters = 'abcdefghijklmnopqrstuvwxyz*';
        for (var i = 0; i < letters.length; i++) {
            let letter = letters[i].toUpperCase();
            let li = new HTML('li', {onclick: 'switch_index({letter: "%s"});'.format(letter), class: (letter == 'A') ? 'active' :null}, letter);
            lists.inject(li);
        }
    }
}

let preferred_lists = ['dev', 'users'];
let preferred_no_lists = ['security'];

function best_list(entries) {
    let x = 0;
    let pick = 'dev';
    for (var key in entries) {
        if (preferred_lists.has(key)) return key;
        if (preferred_no_lists.has(key) && Object.keys(entries).length > 1) continue;
        if (entries[key] > x) {
            x = entries[key];
            pick = key;
        }
    }
    return pick;
}

function list_index_onepage(state, json) {
    let obj = document.getElementById('list_index_child');
    obj.style.padding = '8px';
    let domains = Object.keys(json.lists);
    domains.sort();
    let letter = '';
    for (var i = 0; i < domains.length; i++) {
        let domain = domains[i];
        let l = domain[0];
        if (l != letter) {
            letter = l;
            let lhtml = new HTML('h2', {}, l.toUpperCase());
            obj.inject(lhtml);
        }
        let a = new HTML('a', {href: 'list.html?%s@%s'.format(best_list(json.lists[domain]), domain)}, domain);
        obj.inject(['- ', a]);
        obj.inject(new HTML('br'));
    }
}

function prime_list_index() {
    GET('%sapi/preferences.lua'.format(apiURL), list_index_onepage, {});
}


/******************************************
 Fetched from source/listview-flat.js
******************************************/

function calc_per_page() {
    // Figure out how many emails per page
    let body = document.body;
    let html = document.documentElement;
    let height = Math.max( body.scrollHeight, 
                       html.clientHeight, html.scrollHeight);
    let width = Math.max( body.scrollWidth, 
                       html.clientWidth, html.scrollWidth);
    let email_h = 40;
    console.log("window area: %ux%u".format(width, height));
    if (width < 600) { console.log("Using narrow view, halving emails per page..."); email_h = 80;}
    height -= 180;
    let per_page = Math.max(5, Math.floor(height / email_h));
    per_page -= per_page % 5;
    return per_page;
}

function listview_flat(json, start) {
    let list = document.getElementById('emails');
    list.innerHTML = "";
    let per_page = calc_per_page();
    
    let s = start || 0;
    if (json.emails && json.emails.length) {
        for (n = s; n < (s+per_page); n++ ) {
            let z = json.emails.length - n - 1; // reverse order by default
            if (json.emails[z]) {
                let item = listview_flat_element(json.emails[z], z);
                list.inject(item);
                
                // Hidden placeholder for expanding email(s)
                let placeholder = new HTML('div', {class: chatty_layout ? 'email_placeholder_chatty' : 'email_placeholder', id: 'email_%u'.format(z)});
                list.inject(placeholder);
            }
        }
    } else {
        list.inject(txt("No emails found..."));
    }
}

function listview_flat_element(eml, idx) {
    
    let link_wrapper = new HTML('a', {href:'thread/%s'.format(eml.id), onclick:'return(expand_email_threaded(%u, true));'.format(idx)});
    
    let element = new HTML('div', { class: "listview_email_flat"}, " ");
    let date = new Date(eml.epoch*1000.0);
    let now = new Date();
    
    // Add gravatar
    let gravatar = new HTML('img', { class:"gravatar", src: "https://secure.gravatar.com/avatar/%s.jpg?s=96&r=g&d=mm".format(eml.gravatar)});
    element.inject(gravatar);
    
    
    // Add author
    let authorName = eml.from.replace(/\s*<.+>/, "").replace(/"/g, '');
    let authorEmail = eml.from.match(/\s*<(.+@.+)>\s*/);
    if (authorName.length == 0) authorName = authorEmail ? authorEmail[1] : "(No author?)";
    let author = new HTML('span', { class: "listview_email_author"}, authorName);
    element.inject(author);
    
    
    // Combined space for subject + body teaser
    let as = new HTML('div', {class: 'listview_email_as'});
    
    let suba = new HTML('a', {}, eml.subject === '' ? '(No subject)' : eml.subject);
    let subject = new HTML('div', {class: 'listview_email_subject email_unread'}, suba);
    as.inject(subject);
    
    let body = new HTML('div', {class: 'listview_email_body'}, eml.body);
    as.inject(body);
    
    element.inject(as);
    
    // Labels
    let labels = new HTML('div', {class: 'listview_email_labels'});
    let dl = new HTML('span', { class: 'label label-default'}, date.ISOBare());
    if (now - date < 86400000) {
        dl.setAttribute("class", "label label-primary");
    }
    labels.inject(dl);
    
    element.inject(labels);
    link_wrapper.inject(element);
    
    return link_wrapper;
}


/******************************************
 Fetched from source/listview-header.js
******************************************/

let prev_listview_json = {};
let prev_listview_state = {};
let current_index_pos = 0;
let current_per_page = 0;

function listview_header(state, json) {
    let list_title = json.list;
    prev_listview_json = json;
    prev_listview_state = state;
    if (current_list == 'virtual' && current_domain == 'inbox') {
        list_title = "Virtual inbox, past 30 days";
    }
    let blobs = json.emails;
    if (current_listmode == 'threaded') blobs = json.thread_struct;
    
    if (current_year && current_month) {
        list_title += ", %s %u".format(months[current_month-1], current_year);
    } else {
      list_title += ", past month";
    }

    if (json.searchParams.q && json.searchParams.q.length || (json.searchParams.d||"").match(/=/)) {
        list_title = "Custom search";
    }

    document.getElementById('listview_title').innerText = list_title + ":";
    let download = new HTML('button', { title: 'Download as mbox archive', download: 'true'}, new HTML('span', {class: 'glyphicon glyphicon-save'}, " "));
    document.getElementById('listview_title').inject(download);
    download.addEventListener('click', () => {
        dl_url = pm_config.apiURL + 'api/mbox.lua?';
        for (let key in json.searchParams || {}) {
            dl_url += key + "=" + encodeURIComponent(json.searchParams[key]) + "&";
        }
        location.href = dl_url;
    });
    
    let chevrons = document.getElementById('listview_chevrons');
    let per_page = calc_per_page();
    current_per_page = per_page;
    current_index_pos = state.pos || 0;
    let first = 1;
    if (state && state.pos) {
        first = 1 + state.pos;
    }
    chevrons.innerHTML = "Showing <b>%u through %u</b> of <b>%u</b> topics&nbsp;".format(first, Math.min(first + per_page - 1, blobs.length), blobs.length||0);
    
    let pprev = Math.max(0, first - per_page - 1);
    let cback = new HTML('button', { onclick: 'listview_header({pos: %u}, current_json);'.format(pprev), disabled: (first == 1) ? 'true': null}, new HTML('span', {class: 'glyphicon glyphicon-chevron-left'}, " "));
    chevrons.inject(cback);
    
    let pnext = first + per_page - 1;
    let cforward = new HTML('button', { onclick: 'listview_header({pos: %u}, current_json);'.format(pnext),  disabled: (first+per_page-1 >= blobs.length) ? 'true': null}, new HTML('span', {class: 'glyphicon glyphicon-chevron-right'}, " "));
    chevrons.inject(cforward);
    
    let crefresh = new HTML('button', { onclick: 'parseURL();', title: 'Refresh results', style: {marginLeft: '8px'}}, new HTML('span', {class: 'glyphicon glyphicon-refresh'}, " "));
    chevrons.inject(crefresh);
    
    if (state && state.pos != undefined) {
        if (current_listmode == 'threaded') {
            listview_threaded(json, state.pos);
        } else {
            listview_flat(json, state.pos);
        }
    }
    
    let tm = document.getElementById('threaded_mobile_img');
    if (tm) {
      if (current_listmode == 'threaded') tm.setAttribute("src", "images/threading_enabled.png");
      else tm.setAttribute("src", "images/threading_disabled.png");
    }
}

function listview_list_lists(state, json) {
    let lists = document.getElementById('list_picker_ul');
    let searching = (state && state.search === true) ? true : false;
    if (state && state.to) {
        let tab = undefined;
        let tabs = lists.childNodes;
        for (var i = 0; i < tabs.length; i++) {
            let xtab = tabs[i];
            if ((state.to == 'search' && xtab.getAttribute('id') == 'tab_search') || (xtab.innerText == state.to || xtab.getAttribute('data-list') == state.to)) {
                tab = xtab;
                tab.setAttribute("class", state.to == 'search' ? 'search' : 'active');
            } else if (xtab.getAttribute("class") != 'list_all_narrow' && xtab.getAttribute("class") != 'others') {
                xtab.setAttribute("class", "");
            }
            
        }
        return;
    }
    if (!json) {
        json = ponymail_preferences;
    }
    if (lists) {
    	lists.innerHTML = "";

    	if (isHash(json.lists) && json.lists[current_domain]) {
        	lists_sorted = [];
        	for (var list in json.lists[current_domain]) {
            	lists_sorted.push([list, json.lists[current_domain][list]]);
        	}
        	lists_sorted.sort((a,b) => b[1] - a[1]);
        	let alists = [];
        	for (var i = 0; i < lists_sorted.length; i++) alists.push(lists_sorted[i][0]);
        	if (current_list != '*' && current_domain != '*') {
            	alists.remove(current_list);
            	alists.unshift(current_list);
        	}
        	let maxlists = (searching && 3 || 4);
        	for (var i = 0; i < alists.length; i++) {
            	if (i >= maxlists) break;
            	let listname = alists[i];
            	let listnametxt = listname;
            	if (long_tabs) { listnametxt = '%s@%s'.format(listname, current_domain);}
            	let li = new HTML('li', {onclick: 'switch_list(this, "tab");', class: (listname == current_list && !searching) ? 'active' :null}, listnametxt);
            	li.setAttribute("data-list", '%s@%s'.format(listname, current_domain));
            	lists.inject(li);
        	}
	        
        	if (alists.length > maxlists) {
            	let other_lists_sorted = [];
            	for (var i = maxlists; i < alists.length; i++) {
                	other_lists_sorted.push(alists[i]);
            	}
            	other_lists_sorted.sort();
            	let li = new HTML('li', {class: 'others'});
            	let otherlists = new HTML('select', {class: 'listview_others', onchange: 'switch_list(this.value);'});
            	otherlists.inject(new HTML('option', { disabled: 'disabled', selected: 'selected'}, 'Other lists (%u):'.format(other_lists_sorted.length)));
            	li.inject(otherlists);
            	for (var i = 0; i < other_lists_sorted.length; i++) {
	               let listname = other_lists_sorted[i];
               	let opt = new HTML('option', {value: "%s@%s".format(listname, current_domain)}, listname);
               		otherlists.inject(opt);
            	}
            	lists.inject(li);
        	}
        	// All lists, for narrow UI
        	let all_lists_narrow = [];
        	for (var i = 0; i < alists.length; i++) {
            	all_lists_narrow.push(alists[i]);
        	}
        	all_lists_narrow.sort();
        	let li = new HTML('li', {class: 'list_all_narrow'});
        	let otherlists = new HTML('select', {class: 'listview_others', onchange: 'switch_list(this.value);'});
        	otherlists.inject(new HTML('option', { disabled: 'disabled', selected: 'selected'}, "%s@%s".format(current_list, current_domain)));
        	li.inject(otherlists);
        	for (var i = 0; i < all_lists_narrow.length; i++) {
         	  let listname = all_lists_narrow[i];
           	let opt = new HTML('option', {value: "%s@%s".format(listname, current_domain)}, listname);
           	otherlists.inject(opt);
	        }
        	lists.inject(li);
        }
    }
    if (searching) {
        let li = new HTML('li', {onclick: 'switch_list(this, "tab");', id: 'tab_search', class: 'search'}, "Search: %s".format(state.query));
        li.setAttribute("data-url", state.url);
        li.setAttribute("data-href", location.href);
        lists.inject(li);
    }
    
    // Populate the project selector
    if (isHash(json.lists)) {
        let no_projects = 0;
        let select = document.getElementById('project_select');
        if (!select || select_primed) return;
        let opts = {}
        let doms = [];
        for (var domain in json.lists) {
            let option = new HTML('option', { value: domain }, domain);
            opts[domain] = option;
            doms.push(domain);
            no_projects++;
        }
        if (no_projects > 1 || current_domain == '*') {
            select.innerHTML = "";
            let title = new HTML('option', { disabled: 'disabled', selected: 'true', value: ''}, "Available projects (%u):".format(no_projects));
            select.inject(title);
            doms.sort();
            for (var i = 0; i < doms.length; i++) {
                select.inject(opts[doms[i]]);
            }
            select.style.display = "inline-block";
            select_primed = true; // mark it primed so we don't generate it again later
        }
    }
}


function switch_project(domain) {
    // TODO: improve this
  if (ponymail_preferences && ponymail_preferences.lists[domain]) {
    // Switch to the most populous, but not commits/cvs
    let lists_sorted = [];
    for (var list in ponymail_preferences.lists[domain]) {
        lists_sorted.push([list, ponymail_preferences.lists[domain][list]]);
    }
    lists_sorted.sort((a,b) => b[1] - a[1]);
    let lists = [];
    for (var i = 0; i < lists_sorted.length; i++) lists.push(lists_sorted[i][0]);
    let listname = lists[0];
    let n = 1;
    if (lists.length > n) {
        while (boring_lists.has(listname) && lists.length > n) {
            listname = lists[n];
            n++;
        }
        if (lists.has(favorite_list)) {
            listname = favorite_list;
        }
    }
    switch_list('%s@%s'.format(listname, domain));
  } else {
    switch_list('dev@%s'.format(domain));
  }
}

function switch_list(list, from) {
    let listid = list;
    if (typeof list == 'object') {
        let dataURL = list.getAttribute('data-url');
        if (dataURL) {
            GET(dataURL, renderListView, {search: true, cached: true});
            let newhref = list.getAttribute('data-href');
            if (location.href !== newhref) {
              window.history.pushState({}, null, newhref);
            }
            listview_list_lists({to: 'search'});
            return;
        }
        listid = list.getAttribute("data-list") || list.innerText;
    }
    let bits = listid.split("@");
    current_list = bits[0];
    current_domain = bits[1];
    current_year = 0;
    current_month = 0;
    
    let newhref = "list.html?%s".format(listid);
    if (location.href !== newhref) {
      window.history.pushState({}, null, newhref);
    }

    console.log("Switching list to %s...".format(listid));
    listview_list_lists({to: from ? listid : undefined});
    post_prime({cached: true, from: from});
}

window.addEventListener('orientationchange', function() {
    window.setTimeout(function() {
        if (anyOpen() == false) {
            listview_header(prev_listview_state, prev_listview_json); 
        }
    }, 100);
}, false);



/******************************************
 Fetched from source/listview-threaded.js
******************************************/

function calc_email_width() {
    // Figure out how many emails per page
    let body = document.body;
    let html = document.documentElement;
    let width = Math.max( body.scrollWidth, body.offsetWidth, 
                       html.clientWidth, html.scrollWidth, html.offsetWidth );
    return width;
}

function listview_threaded(json, start) {
    let list = document.getElementById('emails');
    list.innerHTML = "";
    let per_page = calc_per_page();
    
    let s = start || 0;
    if (json.thread_struct && json.thread_struct.length) {
        for (n = s; n < (s+per_page); n++ ) {
            let z = json.thread_struct.length - n - 1; // reverse order by default
            if (json.thread_struct[z]) {
                let item = listview_threaded_element(json.thread_struct[z], z);
                list.inject(item);
                // Hidden placeholder for expanding email(s)
                let placeholder = new HTML('div', {class: chatty_layout ? 'email_placeholder_chatty' : 'email_placeholder', id: 'email_%u'.format(z)});
                list.inject(placeholder);
            }
        }
    } else {
        list.inject(txt("No emails found..."));
    }
}

function find_email(id) {
    let json = current_json;
    for (var i = 0; i < json.emails.length; i++) {
        if (json.emails[i].id == id) return json.emails[i];
    }
    return null;
}

function count_replies(thread) {
    let reps = 0;
    if (isArray(thread.children)) {
        for (let i = 0; i < thread.children.length; i++) {
            if (thread.children[i].tid == thread.tid) reps--;
            if (true) {
                reps++;
                reps += count_replies(thread.children[i]);
            }
        }
    }
    return reps;
}

function count_people(thread, hash) {
    let ppl = hash || {};
    let eml = find_email(thread.tid);
    if (eml) ppl[eml.from]  = true;
    if (isArray(thread.children)) {
        for (let i = 0; i < thread.children.length; i++) {
            if (true) {
                count_people(thread.children[i], ppl);
            }
        }
    }
    let n = 0;
    for (var _ in ppl) n++;
    return n;
}


function last_email(thread) {
    let newest = thread.epoch;
    if (isArray(thread.children)) {
        for (let i = 0; i < thread.children.length; i++) {
            newest = Math.max(newest, last_email(thread.children[i]));
        }
    }
    return newest;
}



function listview_threaded_element(thread, idx) {
    let eml = find_email(thread.tid);
    if (!eml) { return; }
    
    let link_wrapper = new HTML('a', {href:'thread/%s'.format(eml.id), onclick:'return(expand_email_threaded(%u));'.format(idx)});
    
    let element = new HTML('div', { class: "listview_email_flat"}, " ");
    let date = new Date(eml.epoch*1000.0);
    let now = new Date();
    
    // Add gravatar
    let gravatar = new HTML('img', { class:"gravatar", src: "https://secure.gravatar.com/avatar/%s.jpg?s=96&r=g&d=mm".format(eml.gravatar)});
    element.inject(gravatar);
    
    
    // Add author
    let authorName = eml.from.replace(/\s*<.+>/, "").replace(/"/g, '');
    let authorEmail = eml.from.match(/\s*<(.+@.+)>\s*/);
    if (authorName.length == 0) authorName = authorEmail ? authorEmail[1] : "(No author?)";
    let author = new HTML('span', { class: "listview_email_author"}, authorName);
    element.inject(author);
    
    // If needed, inject ML name
    if (current_domain == 'inbox' || current_list == '*') {
        author.style.lineHeight = '16px';
        author.inject(new HTML('br'));
        author.inject(new HTML('span', { class: "label label-primary", style: "font-style: italic; font-size: 1rem;"}, eml.list_raw.replace(/[<>]/g, '').replace('.','@',1)));
    }
    
    
    
    // Combined space for subject + body teaser
    let as = new HTML('div', {class: 'listview_email_as'});
    
    let suba = new HTML('a', {},  eml.subject === '' ? '(No subject)' : eml.subject);
    if (current_json.name == '*' || current_json.domain == '*') {
        let kbd = new HTML('kbd', {class: 'listview_kbd'}, eml.list_raw.replace(/[<>]/g, '').replace('.','@',1))
        suba = [kbd, suba];
    }
    let subject = new HTML('div', {class: 'listview_email_subject email_unread'}, suba);
    as.inject(subject);
    
    let body = new HTML('div', {class: 'listview_email_body'}, eml.body);
    as.inject(body);
    
    element.inject(as);
    
    // Labels
    let labels = new HTML('div', {class: 'listview_email_labels'});
    
    
    // Participants
    let ppl = count_people(thread);
    let ptitle = (ppl == 1) ? "one participant" : "%u participants".format(ppl);
    let people = new HTML('span', { class: 'label label-default', title: ptitle}, [
        new HTML('span', { class: 'glyphicon glyphicon-user'}, ' '),
        " %u".format(ppl)
                                                                 ]);
    labels.inject(people);
    
    // Replies
    let reps = count_replies(thread);
    let rtitle = (reps == 1) ? "one reply" : "%u replies".format(reps);
    let repl = new HTML('span', { class: 'label label-default', title: rtitle}, [
        new HTML('span', { class: 'glyphicon glyphicon-envelope'}, ' '),
        " %u".format(reps)
                                                                 ]);
    labels.inject(repl);
    
    // Date
    date = new Date(last_email(thread) * 1000.0);
    let dl = new HTML('span', { class: 'label label-default'}, date.ISOBare());
    if (now - date < 86400000) {
        dl.setAttribute("class", "label label-primary");
    }
    labels.inject(dl);
    
    element.inject(labels);
    link_wrapper.inject(element);
    
    return link_wrapper;
}


/******************************************
 Fetched from source/preferences.js
******************************************/

// logout: log out a user
// call the logout URL, then refresh this page - much simple!
function logout() {
    GET("/api/preferences.lua?logout=true", () => location.href = document.location);
}

function init_preferences(state, json) {
    ponymail_preferences = json || {};
    // First, load session local settings, if possible
    if (can_store) {
        let local_preferences = window.localStorage.getItem('ponymail_preferences');
        if (local_preferences) {
            ljson = JSON.parse(local_preferences);
            if (ljson.chatty_layout !== undefined) {
                chatty_layout = ljson.chatty_layout;
            }
        }
    }
    
    // color some links
    let cl = document.getElementById('chatty_link');
    if (cl) {
      cl.setAttribute("class", chatty_layout ? "enabled" : "disabled");
    }
    
    if (ponymail_preferences.login && ponymail_preferences.login.credentials) {
      let prefsmenu = document.getElementById('prefs_dropdown');
      let uimg = document.getElementById('uimg');
      uimg.setAttribute("src", "images/user.png");
      uimg.setAttribute("title", "Logged in as %s".format(ponymail_preferences.login.credentials.fullname));
      
      // Generate user menu
      prefsmenu.innerHTML = "";
      
      
      let logout = new HTML('a', { href: "javascript:void(logout());"}, "Log out");
      let li = new HTML('li', {}, logout)
      prefsmenu.inject(li);
      
    } else {
      let prefsmenu = document.getElementById('prefs_dropdown');
      if (prefsmenu) {
        prefsmenu.innerHTML = "";
        let login = new HTML('a', { href: "javascript:location.href='oauth.html';"}, "Log In");
        let li = new HTML('li', {}, login)
        prefsmenu.inject(li);
      }
    }
    
    if (json) {
      listview_list_lists(state, json);
      if (state && state.prime) {
        // If lists is accessible, show it
        if (json.lists[current_domain] && json.lists[current_domain][current_list] != undefined) {
          post_prime(state);
        } else {// otherwise, bork
          if (current_list.length > 0 && (!json.lists[current_domain] || Object.keys(json.lists[current_domain]).length > 0)) {
            let eml = document.getElementById('emails');
            eml.innerText = "We couldn't find this list. It may not exist or require you to be logged in with specific credentials.";
            eml.inject(new HTML('br'));
            eml.inject(new HTML('a', {href: 'oauth.html', onclick:'location.href="oauth.html";'}, "Click here to log in via OAuth"));
          } else {
            console.log(current_domain);
            let first_list = Object.keys(json.lists[current_domain])[0];
            location.href = `?${first_list}@${current_domain}`;
          }
        }
      }
    }
}

function save_preferences() {
    if (can_store) {
        let ljson = {
            chatty_layout: chatty_layout
        };
        let lstring = JSON.stringify(ljson);
        window.localStorage.setItem('ponymail_preferences', lstring);
        console.log("Saved local preferences");
    }
}


function set_theme(theme) {
    current_listmode = theme;
    renderListView(current_state, current_json);
    save_preferences();
}

function set_skin(skin) {
  chatty_layout = !chatty_layout;
  let cl = document.getElementById('chatty_link');
  if (cl) {
    cl.setAttribute("class", chatty_layout ? "enabled" : "disabled");
  }
  hideWindows(true);
  renderListView(current_state, current_json);
  save_preferences();
}

// set_skin, but for permalinks
function set_skin_permalink(skin) {
  chatty_layout = !chatty_layout;
  let cl = document.getElementById('chatty_link');
  if (cl) {
    cl.setAttribute("class", chatty_layout ? "enabled" : "disabled");
  }
  hideWindows(true);
  save_preferences();
  parse_permalink();
}

/******************************************
 Fetched from source/primer.js
******************************************/

/* List View Rendering main func */
function renderListView(state, json) {
    if (json) {
        current_json = json;
    }
    current_state = state;
    async_escrow['rendering'] = new Date();
    if (!state || state.update_calendar !== false) {
        renderCalendar(json.firstYear,json.firstMonth,json.lastYear, json.lastMonth);
    }
    // sort threads by date
    if (isArray(json.thread_struct)) {
        current_json.thread_struct.sort((a,b) => last_email(a) - last_email(b));
    }
    listview_header(state, json);
    if (current_listmode == 'threaded') { listview_threaded(json, 0); }
    else { listview_flat(json, 0);}
    
    sidebar_stats(json); // This comes last, takes the longest with WC enabled.
    delete async_escrow['rendering'];
    
    if (state && state.to) {
      listview_list_lists(state);
    }
}

/* Primer function for List View
 * Fetches the following:
 * - user preferences (api/preferences.lua)
 * - pony mail list DB (api/pminfo.lua)
 * - emails from this list (api/stats.lua)
 * When done, we create the scaffolding and list view
 */
function primeListView(state) {
    console.log("Priming user interface for List View..");
    state = state || {};
    state.prime = true;
    GET('%sapi/preferences.lua'.format(apiURL), init_preferences, state);
}

// callback from when prefs have loaded
function post_prime(state) {
  let sURL = '%sapi/stats.lua?list=%s&domain=%s'.format(apiURL, current_list, current_domain);
    if (current_year && current_month) {
        sURL += "&d=%u-%u".format(current_year, current_month);
    }
    if (! (state && state.search)) {
      if (state && state.array) {
        collated_json = {};
        virtual_inbox_loading = true;
        for (var i = 0; i < state.array.length; i++) {
          let list = state.array[i].split('@');
          sURL = '%sapi/stats.lua?list=%s&domain=%s'.format(apiURL, list[0], list[1]);
          GET(sURL, render_virtual_inbox, state);
        }
      } else {
        GET(sURL, renderListView, state);
      }
    } else {
      search(state.query, state.date);
    }
}


function parseURL(state) {
  let bits = window.location.search.substr(1).split(":", 3);
  let list = bits[0];
  let month = bits[1];
  let query = bits[2];
  let list_array = null;
  state = state || {};
  current_query = query || "";
  current_month = 0;
  current_year = 0;
  
  // If "month" (year-month) is specified,
  // we should set the current vars
  if (month) {
    try {
        let dbits = month.split("-");
        current_year = dbits[0];
        current_month = dbits[1];
    } catch (e) {}
  }
  // Is this a valid list?
  if (list !== '') {
    // multi-list??
    if (list.match(/,/)) {
      state.array = list.split(',');
      current_domain = 'inbox';
      current_list = 'virtual';
    } else {
      let lbits = list.split("@");
      if (lbits.length > 1) {
        current_list = lbits[0];
        current_domain = lbits[1];
      } else {
        current_domain = lbits;
        current_list = '';
      }
    }
  }
  // Are we initiating a search?
  if (query) {
    state.search = true;
    state.query = query;
    state.date = month;
  }
  primeListView(state);
};



// Parse a permalink and fetch the thread
function parse_permalink() {
  // message id is the bit after the last /
  let mid = location.href.split('/').pop();
  init_preferences(); // blank call to load defaults like social rendering
  GET('%sapi/preferences.lua'.format(apiURL), init_preferences, null);
  // Fetch the thread data and pass to build_single_thread
  GET('%sapi/thread.lua?id=%s'.format(apiURL, mid), construct_single_thread, {cached: true});
}


// Virtual inbox ŕendering
function render_virtual_inbox(state, json) {
    if (json) {
        collated_json.emails = collated_json.emails || [];
        collated_json.thread_struct = collated_json.thread_struct || [];
        for (var i = 0; i < json.emails.length; i++) {
          collated_json.emails.push(json.emails[i]);
        }
        for (var i = 0; i < json.thread_struct.length; i++) {
          collated_json.thread_struct.push(json.thread_struct[i]);
        }
    }
    
    for (var k in async_escrow) {
        return;
    }
    
    if (true) {
      console.log("Rendering multi-list")
      current_json = collated_json;
      current_json.participants = [];
      
      async_escrow['rendering'] = new Date();
      if (!state || state.update_calendar !== false) {
          renderCalendar(json.firstYear,json.firstMonth,json.lastYear, json.lastMonth);
      }
      // sort threads by date
      if (isArray(json.thread_struct)) {
          current_json.thread_struct.sort((a,b) => last_email(a) - last_email(b));
      }
      listview_header(state, current_json);
      if (current_listmode == 'threaded') { listview_threaded(current_json, 0); }
      else { listview_flat(current_json, 0);}
      
      sidebar_stats(current_json); // This comes last, takes the longest with WC enabled.
      delete async_escrow['rendering'];
    }
}

/******************************************
 Fetched from source/render-email.js
******************************************/

let full_emails = {};

async function render_email(state, json) {
    let div = state.div;
    full_emails[json.mid] = json; // Save for composer if replying later...
    if (state.scroll) {
        let rect = div.getBoundingClientRect();
        try {
            window.setTimeout(function() { window.scrollTo(0, rect.top - 48);}, 200);
            console.log("Scrolled to %u".format(rect.top - 48));
        } catch (e) {}
    }
    if (chatty_layout) {
        return render_email_chatty(state, json);
    }
    
    // Author
    let author_field = new HTML('div', {class: 'email_kv'});
    let author_key = new HTML('div', {class: 'email_key'}, "From: ");
    let author_value = new HTML('div', {class: 'email_value'}, json.from);
    author_field.inject([author_key, author_value]);
    div.inject(author_field);
    
    // Subject
    let subject_field = new HTML('div', {class: 'email_kv'});
    let subject_key = new HTML('div', {class: 'email_key'}, "Subject: ");
    let subject_value = new HTML('div', {class: 'email_value'}, json.subject == '' ? '(No subject)' : json.subject);
    subject_field.inject([subject_key, subject_value]);
    div.inject(subject_field);
    
    // Date
    let date_field = new HTML('div', {class: 'email_kv'});
    let date_key = new HTML('div', {class: 'email_key'}, "Date: ");
    let date_value = new HTML('div', {class: 'email_value'}, new Date(json.epoch * 1000.0).ISOBare());
    date_field.inject([date_key, date_value]);
    div.inject(date_field);
    
    
    // List
    let listname = json.list_raw.replace(".", "@", 1).replace(/[<>]/g, "");
    let list_field = new HTML('div', {class: 'email_kv'});
    let list_key = new HTML('div', {class: 'email_key'}, "List: ");
    let list_value = new HTML('div', {class: 'email_value'},
        new HTML('a', {href: 'list?%s'.format(listname)}, listname)
        );
    list_field.inject([list_key, list_value]);
    div.inject(list_field);
    
    // Private email??
    if (json.private === true) {
        let priv_field = new HTML('div', {class: 'email_kv'});
        let priv_key = new HTML('div', {class: 'email_key'}, "Private: ");
        let priv_value = new HTML('div', {class: 'email_value_emphasis'}, "YES");
        priv_field.inject([priv_key, priv_value]);
        div.inject(priv_field);
    }
    
    // Attachments?
    if (json.attachments && json.attachments.length > 0) {
        let attach_field = new HTML('div', {class: 'email_kv'});
        let attach_key = new HTML('div', {class: 'email_key'}, "Attachment(s): ");
        let alinks = [];
        for (let n = 0; n < json.attachments.length; n++) {
            let attachment = json.attachments[n];
            let link = `${pm_config.apiURL}api/email.lua?attachment=true&id=${json.mid}&file=${attachment.hash}`;
            let a = new HTML('a', {href: link, target: '_blank'}, attachment.filename);
            alinks.push(a);
            let fs = ` ${attachment.size} bytes`;
            if (attachment.size >= 1024) fs = ` ${Math.floor(attachment.size/1024)} KB`;
            if (attachment.size >= 1024*1024) fs = ` ${Math.floor(attachment.size/(1024*10.24))/100} MB`;
            alinks.push (fs);
            alinks.push(new HTML('br'));
        }
        let attach_value = new HTML('div', {class: 'email_value'}, alinks);
        attach_field.inject([attach_key, attach_value]);
        div.inject(attach_field);
    }
    
    let text = new HTML('pre', {}, fixup_quotes(json.body));
    div.inject(text);
    
    
    let toolbar = new HTML('div', {class: 'toolbar'});
    
    // reply to email button
    let replybutton = new HTML('button', { title: "Reply to this email", onclick: `compose_email('${json.mid}');`, class: 'btn toolbar_btn toolbar_button_reply'}, new HTML('span', { class: 'glyphicon glyphicon-pencil'}, ' '));
    toolbar.inject(replybutton);
    
    // permalink button
    let linkbutton = new HTML('a', { href: 'thread/%s'.format(json.mid), title: "Permanent link to this email", class: 'btn toolbar_btn toolbar_button_link'}, new HTML('span', { class: 'glyphicon glyphicon-link'}, ' '));
    toolbar.inject(linkbutton);
    
    // Source-view button
    let sourcebutton = new HTML('a', { href: '%sapi/source.lua?id=%s'.format(apiURL, json.mid), title: "View raw source", class: 'btn toolbar_btn toolbar_button_source'}, new HTML('span', { class: 'glyphicon glyphicon-file'}, ' '));
    toolbar.inject(sourcebutton);
    
    text.inject(toolbar);
}



async function render_email_chatty(state, json) {
    let div = state.div;
    div.parentNode.style.border = 'none';
    
    // Author
    let when = new Date(json.epoch * 1000.0);
    let ldate = when.toISOString();
    try {
        ldate = "%s %s".format(when.toLocaleDateString('en-US', ponymail_date_format), when.toLocaleTimeString());
    } catch (e) {
        
    }
    
    let author_field = new HTML('div', {class: 'chatty_author'});
    let gravatar = new HTML('img', { class:"chatty_gravatar", src: "https://secure.gravatar.com/avatar/%s.jpg?s=96&r=g&d=mm".format(json.gravatar)});
    let author_name = json.from.replace(/\s*<.+>/, "").replace(/"/g, '');
    let author_email = json.from.match(/\s*<(.+@.+)>\s*/);
    if (author_name.length == 0) author_name = author_email ? author_email[1] : "(No author?)";
    let author_nametag = new HTML('div', {class: 'chatty_author_name'}, [
                                  new HTML('b', {}, author_name),
                                  " - %s".format(ldate)
                                  ]);
    author_field.inject([gravatar, author_nametag]);
    div.inject(author_field);
    let chatty_body = fixup_quotes(json.body);
    if (json.mid == current_open_email) {
        let header = new HTML('h4', {class: 'chatty_title_inline'}, json.subject);
        chatty_body.unshift(header);
    }
    let text = new HTML('pre', {class: 'chatty_body'}, chatty_body);
    div.inject(text);

    // Private text?
    if (json.private === true) {
      text.style.backgroundImage = "url(images/private.png)";
    }
    
    // Attachments?
    if (json.attachments && json.attachments.length > 0) {
        let attach_field = new HTML('div', {class: 'email_kv'});
        let attach_key = new HTML('div', {class: 'email_key'}, "Attachment(s):");
        let alinks = [];
        for (let n = 0; n < json.attachments.length; n++) {
            let attachment = json.attachments[n];
            let link = `${pm_config.apiURL}api/email.lua?attachment=true&id=${json.mid}&file=${attachment.hash}`;
            let a = new HTML('a', {href: link, target: '_blank'}, attachment.filename);
            alinks.push(a);
            let fs = ` ${attachment.size} bytes`;
            if (attachment.size >= 1024) fs = ` ${Math.floor(attachment.size/1024)} KB`;
            if (attachment.size >= 1024*1024) fs = ` ${Math.floor(attachment.size/(1024*10.24))/100} MB`;
            alinks.push (fs);
            alinks.push(new HTML('br'));
        }
        let attach_value = new HTML('div', {class: 'email_value'}, alinks);
        attach_field.inject([attach_key, attach_value]);
        text.inject(attach_field);
    }
    
    let toolbar = new HTML('div', {class: 'toolbar_chatty'});
    
    // reply to email button
    let replybutton = new HTML('button', { title: "Reply to this email", onclick: `compose_email('${json.mid}');`, class: 'btn toolbar_btn toolbar_button_reply'}, new HTML('span', { class: 'glyphicon glyphicon-pencil'}, ' '));
    toolbar.inject(replybutton);
    
    // permalink button
    let linkbutton = new HTML('a', { href: 'thread/%s'.format(json.mid), title: "Permanent link to this email", class: 'btn toolbar_btn toolbar_button_link'}, new HTML('span', { class: 'glyphicon glyphicon-link'}, ' '));
    toolbar.inject(linkbutton);
    
    // Source-view button
    let sourcebutton = new HTML('a', { href: '%sapi/source.lua?id=%s'.format(apiURL, json.mid), title: "View raw source", class: 'btn toolbar_btn toolbar_button_source'}, new HTML('span', { class: 'glyphicon glyphicon-file'}, ' '));
    toolbar.inject(sourcebutton);

    // Admin button?
    let adminbutton = new HTML('a', { href: '#', title: "Administrative control", class: 'btn toolbar_btn toolbar_button_admin'}, new HTML('span', { class: 'glyphicon glyphicon-cog'}, ' '));
    toolbar.inject(adminbutton);
    
    text.inject(toolbar);
}



/******************************************
 Fetched from source/scaffolding-html.js
******************************************/

/**
 * HTML: DOM creator class
 * args:
 * - type: HTML element type (div, table, p etc) to produce
 * - params: hash of element params to add (class, style etc)
 * - children: optional child or children objects to insert into the new element
 * Example:
 * div = new HTML('div', {
 *    class: "footer",
 *    style: {
 *        fontWeight: "bold"
 *    }
#}, "Some text inside a div")
 */

var txt = (msg) => document.createTextNode(msg);

var HTML = (function() {
  function HTML(type, params, children) {

    /* create the raw element, or clone if passed an existing element */
    var child, j, len, val;
    if (typeof type === 'object') {
      this.element = type.cloneNode();
    } else {
      this.element = document.createElement(type);
    }

    /* If params have been passed, set them */
    if (isHash(params)) {
      for (var key in params) {
        val = params[key];

        /* Standard string value? */
        if (typeof val === "string" || typeof val === 'number') {
          this.element.setAttribute(key, val);
        } else if (isArray(val)) {

          /* Are we passing a list of data to set? concatenate then */
          this.element.setAttribute(key, val.join(" "));
        } else if (isHash(val)) {

          /* Are we trying to set multiple sub elements, like a style? */
          for (var subkey in val) {
            let subval = val[subkey];
            if (!this.element[key]) {
              throw "No such attribute, " + key + "!";
            }
            this.element[key][subkey] = subval;
          }
        }
      }
    }

    /* If any children have been passed, add them to the element */
    if (children) {

      /* If string, convert to textNode using txt() */
      if (typeof children === "string") {
        this.element.inject(txt(children));
      } else {

        /* If children is an array of elems, iterate and add */
        if (isArray(children)) {
          for (j = 0, len = children.length; j < len; j++) {
            child = children[j];

            /* String? Convert via txt() then */
            if (typeof child === "string") {
              this.element.inject(txt(child));
            } else {

              /* Plain element, add normally */
              this.element.inject(child);
            }
          }
        } else {

          /* Just a single element, add it */
          this.element.inject(children);
        }
      }
    }
    return this.element;
  }

  return HTML;

})();

/**
 * prototype injector for HTML elements:
 * Example: mydiv.inject(otherdiv)
 */

HTMLElement.prototype.inject = function(child) {
  var item, j, len;
  if (isArray(child)) {
    for (j = 0, len = child.length; j < len; j++) {
      item = child[j];
      if (typeof item === 'string') {
        item = txt(item);
      }
      this.appendChild(item);
    }
  } else {
    if (typeof child === 'string') {
      child = txt(child);
    }
    this.appendChild(child);
  }
  return child;
};



/**
 * prototype for emptying an html element
 */

HTMLElement.prototype.empty = function() {
  var ndiv;
  ndiv = this.cloneNode();
  this.parentNode.replaceChild(ndiv, this);
  return ndiv;
};

function toggleView(id) {
  let obj = document.getElementById(id);
  if (obj) {
    obj.style.display = (obj.style.display == 'block') ? 'none' : 'block';
  }
}


/******************************************
 Fetched from source/search.js
******************************************/

function search(query, date) {
    let list = current_list;
    let global = false;
    let domain = current_domain;
    if (ponymail_search_list == 'global') {
        list = '*';
        domain = '*';
        global = true;
    }
    if (ponymail_search_list == 'domain') {
        list = '*';
        global = true;
    }
    let sURL = '%sapi/stats.lua?d=%s&list=%s&domain=%s&q=%s'.format(apiURL, date, list, domain, query);
    GET(sURL, renderListView, {search: true, global: global});
    let listid = '%s@%s'.format(list, domain);
    let newhref = "list?%s:%s:%s".format(listid, date, query);
    if (location.href !== newhref) {
      window.history.pushState({}, null, newhref);
    }

    listview_list_lists({url: sURL, search: true, query: query});
    hideWindows(true);
    document.getElementById('q').value = query;
    return false;
}

// set the list(s) to search, update links
function search_set_list(what) {
    ponymail_search_list = what;
    let links = document.getElementsByClassName('searchlistoption');
    let whatxt = "this list"
    for (var i = 0; i < links.length; i++) {
        let el = links[i];
        if (el.getAttribute("id").match(what)) {
            el.setAttribute("class", "searchlistoption checked");
            whatxt = el.innerText.toLowerCase();
        } else {
            el.setAttribute("class", "searchlistoption");
        }
    }
    document.getElementById('q').setAttribute("placeholder", "Search %s...".format(whatxt));
}


/******************************************
 Fetched from source/sidebar-calendar.js
******************************************/

var months_shortened = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var default_start_year = 1990;
var default_end_year = 2100;
var calendar_index = 0;
var calendar_years_shown = 4;

function renderCalendar(FY, FM, LY, LM) {
    calendar_index = 0;
    
    // Only render if calendar div is present
    let cal = document.getElementById('sidebar_calendar');
    if (!cal) {return;}
    
    let now = new Date();
    let CY = now.getFullYear();
    let CM = now.getMonth();
    let SY = Math.min(LY, CY); // last year in calendar, considering current date

    let cdiv = new HTML('div', { class: 'sidebar_calendar' })
    let N = 0;
    
    // Chevron for moving to later years
    let chevron = new HTML('div', { class: 'sidebar_calendar_chevron'});
        chevron.inject(new HTML('span', { onclick: 'calendar_scroll(this, -4);', style: {display: 'none'}, id: 'sidebar_calendar_up' , class: 'glyphicon glyphicon-collapse-up', title: "Show later years"}, " "));
        cdiv.inject(chevron);
    
    // Create divs for each year, assign all visible
    for (var Y = SY; Y >= FY; Y--) {
        let ydiv = new HTML('div', { class: 'sidebar_calendar_year', id: 'sidebar_calendar_'+N++ });
        ydiv.inject(txt(Y));
        ydiv.inject(new HTML('br'));
        for (var i = 0; i < months_shortened.length; i++) {
            let mon = months_shortened[i];
            let mdiv = new HTML('div', { onclick: 'calendar_click(%u, %u);'.format(Y, i+1), class: 'sidebar_calendar_month'}, mon);
            
            // Mark out-of-bounds segments
            if ( (Y == SY && i >= LM) || (Y == CY && i > CM) ) {
                mdiv.setAttribute("class", "sidebar_calendar_month_nothing");
            }
            if (Y == FY && ((i+1) < FM)) {
                mdiv.setAttribute("class", "sidebar_calendar_month_nothing");
            }
            ydiv.inject(mdiv);
        }
        cdiv.inject(ydiv);
    }
    
    cal.innerHTML = "<p style='text-align: center;'>Archives (%u - %u):</p>".format(FY, SY);
    cal.inject(cdiv);
    
        
    chevron = new HTML('div', { class: 'sidebar_calendar_chevron'});
    chevron.inject(new HTML('span', { onclick: 'calendar_scroll(this, 4);', style: {display: 'none'}, id: 'sidebar_calendar_down', class: 'glyphicon glyphicon-collapse-down', title: "Show earlier years"}, " "));
    cdiv.inject(chevron);
    
    // If we have > 4 years, hide the rest
    if (N > calendar_years_shown) {
        for (var i = calendar_years_shown; i < N; i++) {
            let obj = document.getElementById('sidebar_calendar_'+i);
            if (obj) {
                obj.style.display = "none";
            }
        }
        document.getElementById('sidebar_calendar_down').style.display = 'block';
    }
}

function calendar_scroll(me, x) {
    let years = document.getElementsByClassName('sidebar_calendar_year');
    calendar_index = Math.max(Math.min(years.length-x, calendar_index + x), 0);
    if (calendar_index > 0) {
        document.getElementById('sidebar_calendar_up').style.display = 'block';
    } else {
        document.getElementById('sidebar_calendar_up').style.display = 'none';
    }
    if (calendar_index < (years.length-x)) {
        document.getElementById('sidebar_calendar_down').style.display = 'block';
    } else {
        document.getElementById('sidebar_calendar_down').style.display = 'none';
    }
    
    
    for (var i = 0; i < years.length; i++) {
        let year = years[i];
        if (typeof(year) == 'object') {
            if (i >= calendar_index && i < (calendar_index+Math.abs(x))) {
                year.style.display = "block";
            } else {
                year.style.display = "none";
            }
        }    
    }
    
}

function calendar_click(year, month) {
    current_year = year;
    current_month = month;
    searching = false;
    let newhref = "list.html?%s@%s:%u-%u".format(current_list, current_domain, year, month);
    if (location.href !== newhref) {
      window.history.pushState({}, null, newhref);
    }
    GET('%sapi/stats.lua?list=%s&domain=%s&d=%u-%u'.format(apiURL, current_list, current_domain, year, month), renderListView, {to: '%s@%s'.format(current_list, current_domain), update_calendar: false});
}

/******************************************
 Fetched from source/sidebar-stats.js
******************************************/

async function sidebar_stats(json) {
    let obj = document.getElementById('sidebar_stats');
    if (!obj) { return; }
    
    obj.innerHTML = ""; // clear stats bar
    
    if (!json.emails || isHash(json.emails) || json.emails.length == 0) {
        obj.innerText = "No emails found...";
        return;
    }
    
    // Top 10 participants
    obj.inject("Found %u emails by %u authors, divided into %u topics.".format(json.emails.length, json.numparts, json.no_threads));
    obj.inject(new HTML('h5', {}, "Most active authors:"));
    for (var i=0; i < json.participants.length; i++) {
        if (i >= 5) {
            break;
        }
        let par = json.participants[i];
        if (par.name.length > 24) {
            par.name = par.name.substr(0, 23) + "...";
        }
        if (par.name.length == 0) {
            par.name = par.email;
        }
        pdiv = new HTML('div', {class:"sidebar_stats_participant"});
        pimg = new HTML('img', { class:"gravatar_sm", src: "https://secure.gravatar.com/avatar/%s.jpg?s=64&r=g&d=mm".format(par.gravatar)})
        pdiv.inject(pimg);
        pdiv.inject(new HTML('b', {}, par.name+": "));
        pdiv.inject(new HTML('br'));
        pdiv.inject("%u emails sent".format(par.count));
        obj.inject(pdiv);
    }
    
    // Word cloud, if applicable
    let wc = document.getElementById('sidebar_wordcloud');
    if (wc && json.cloud) {
        wc.innerHTML = "";
        wc.inject(new HTML('h5', {}, "Popular topics:"));
        // word cloud is delayed by 50ms to let the rest render first
        // this is a chrome-specific slowdown we're addressing.
        window.setTimeout(function() {wordCloud(json.cloud, 220, 100, wc);}, 50);
    }
}
