From 0a60d711ff37ac6370aaa06e3556a57a54305e83 Mon Sep 17 00:00:00 2001
From: Henrique Dias <hacdias@gmail.com>
Date: Sun, 26 Mar 2017 11:24:21 +0100
Subject: [PATCH] pre-build.sh

Former-commit-id: 58220a0ee1c48708eed3d172d6884a9f3617ffe9 [formerly 0d570e5a54030b9c4f7e280b55816a221438df72] [formerly 3c420b9ecd469d03c3ddfafeb33d4451a2315d55 [formerly 191a3791e0edc4f474e9d86f85002d404a306710]]
Former-commit-id: 0f82a221f0201448eecd54e98ac95fcdfea7ede0 [formerly 67ce3f7f0945b90ced9d7b11017286753afd8075]
Former-commit-id: a91572e8026c2290095d02bf3ef125591145dbc7
---
 _embed/public/js/common.js      | 580 ++++++++++++++++----------------
 _embed/public/js/editor.js      | 310 ++++++++---------
 _embed/public/js/listing.js     | 575 ++++++++++++++++---------------
 assets/binary.go.REMOVED.git-id |   2 +-
 filemanager.go                  |   5 -
 page/version.go                 |   4 +-
 pre-build.sh                    |  11 +
 7 files changed, 746 insertions(+), 741 deletions(-)
 create mode 100644 pre-build.sh

diff --git a/_embed/public/js/common.js b/_embed/public/js/common.js
index 603bbfa9..b2017220 100644
--- a/_embed/public/js/common.js
+++ b/_embed/public/js/common.js
@@ -1,72 +1,72 @@
-'use strict';
+'use strict'
 
-var tempID = "_fm_internal_temporary_id",
-  ssl = (location.protocol === 'https:'),
+var tempID = '_fm_internal_temporary_id',
+  ssl = (window.location.protocol === 'https:'),
   templates = {},
   selectedItems = [],
   overlay,
-  clickOverlay;
+  clickOverlay
 
 // Removes an element, if exists, from an array
 Array.prototype.removeElement = function (element) {
-  var i = this.indexOf(element);
-  if(i != -1)
-    this.splice(i, 1);
+  var i = this.indexOf(element)
+  if (i !== -1)
+    this.splice(i, 1)
 }
 
 // Replaces an element inside an array by another
 Array.prototype.replaceElement = function (oldElement, newElement) {
-  var i = this.indexOf(oldElement);
-  if(i != -1)
-    this[i] = newElement;
+  var i = this.indexOf(oldElement)
+  if (i != -1)
+    this[i] = newElement
 }
 
 // Sends a costum event to itself
 Document.prototype.sendCostumEvent = function (text) {
-  this.dispatchEvent(new CustomEvent(text));
+  this.dispatchEvent(new CustomEvent(text))
 }
 
 // Gets the content of a cookie
 Document.prototype.getCookie = function (name) {
-  var re = new RegExp("(?:(?:^|.*;\\s*)" + name + "\\s*\\=\\s*([^;]*).*$)|^.*$");
-  return document.cookie.replace(re, "$1");
+  var re = new RegExp('(?:(?:^|.*;\\s*)' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$')
+  return document.cookie.replace(re, '$1')
 }
 
 // Remove the last directory of an url
 var removeLastDirectoryPartOf = function (url) {
-  var arr = url.split('/');
-  if(arr.pop() === "") {
-    arr.pop();
+  var arr = url.split('/')
+  if (arr.pop() === '') {
+    arr.pop()
   }
-  return(arr.join('/'));
+  return (arr.join('/'))
 }
 
-function getCSSRule(rules) {
-  for(let i = 0; i < rules.length; i++) {
-    rules[i] = rules[i].toLowerCase();
+function getCSSRule (rules) {
+  for (let i = 0; i < rules.length; i++) {
+    rules[i] = rules[i].toLowerCase()
   }
 
   var result = null,
-    find = Array.prototype.find;
+    find = Array.prototype.find
 
   find.call(document.styleSheets, styleSheet => {
     result = find.call(styleSheet.cssRules, cssRule => {
-      let found = false;
+      let found = false
 
-      if(cssRule instanceof CSSStyleRule) {
-        for(let i = 0; i < rules.length; i++) {
-          if(cssRule.selectorText.toLowerCase() == rules[i])
-            found = true;
+      if (cssRule instanceof CSSStyleRule) {
+        for (let i = 0; i < rules.length; i++) {
+          if (cssRule.selectorText.toLowerCase() == rules[i])
+            found = true
         }
       }
 
-      return found;
-    });
+      return found
+    })
 
-    return result != null;
-  });
+    return result != null
+  })
 
-  return result;
+  return result
 }
 
 /* * * * * * * * * * * * * * * *
@@ -75,53 +75,53 @@ function getCSSRule(rules) {
  *                             *
  * * * * * * * * * * * * * * * */
 var buttons = {
-  previousState: {},
-};
+  previousState: {}
+}
 
 buttons.setLoading = function (name) {
-  if(typeof this[name] === 'undefined') return;
-  let i = this[name].querySelector('i');
+  if (typeof this[name] === 'undefined') return
+  let i = this[name].querySelector('i')
 
-  this.previousState[name] = i.innerHTML;
-  i.style.opacity = 0;
+  this.previousState[name] = i.innerHTML
+  i.style.opacity = 0
 
   setTimeout(function () {
-    i.classList.add('spin');
-    i.innerHTML = 'autorenew';
-    i.style.opacity = 1;
-  }, 200);
+    i.classList.add('spin')
+    i.innerHTML = 'autorenew'
+    i.style.opacity = 1
+  }, 200)
 }
 
 // Changes an element to done animation
 buttons.setDone = function (name, success = true) {
-  let i = this[name].querySelector('i');
+  let i = this[name].querySelector('i')
 
-  i.style.opacity = 0;
+  i.style.opacity = 0
 
   let thirdStep = () => {
-    i.innerHTML = this.previousState[name];
-    i.style.opacity = null;
+    i.innerHTML = this.previousState[name]
+    i.style.opacity = null
 
-    if(selectedItems.length == 0 && document.getElementById('listing'))
-      document.sendCostumEvent('changed-selected');
+    if (selectedItems.length == 0 && document.getElementById('listing'))
+      document.sendCostumEvent('changed-selected')
   }
 
   let secondStep = () => {
-    i.style.opacity = 0;
-    setTimeout(thirdStep, 200);
+    i.style.opacity = 0
+    setTimeout(thirdStep, 200)
   }
 
   let firstStep = () => {
-    i.classList.remove('spin');
+    i.classList.remove('spin')
     i.innerHTML = success ?
       'done' :
-      'close';
-    i.style.opacity = 1;
-    setTimeout(secondStep, 1000);
+      'close'
+    i.style.opacity = 1
+    setTimeout(secondStep, 1000)
   }
 
-  setTimeout(firstStep, 200);
-  return false;
+  setTimeout(firstStep, 200)
+  return false
 }
 
 /* * * * * * * * * * * * * * * *
@@ -129,84 +129,84 @@ buttons.setDone = function (name, success = true) {
  *            WEBDAV           *
  *                             *
  * * * * * * * * * * * * * * * */
-var webdav = {};
+var webdav = {}
 
 webdav.convertURL = function (url) {
-  return window.location.origin + url.replace(baseURL + "/", webdavURL + "/");
+  return window.location.origin + url.replace(baseURL + '/', webdavURL + '/')
 }
 
 webdav.move = function (oldLink, newLink) {
   return new Promise((resolve, reject) => {
     let request = new XMLHttpRequest(),
-      destination = newLink.replace(baseURL + "/", webdavURL + "/");
+      destination = newLink.replace(baseURL + '/', webdavURL + '/')
 
-    destination = window.location.origin + destination.substring(prefixURL.length);
+    destination = window.location.origin + destination.substring(prefixURL.length)
 
-    request.open('MOVE', webdav.convertURL(oldLink), true);
-    request.setRequestHeader('Destination', destination);
+    request.open('MOVE', webdav.convertURL(oldLink), true)
+    request.setRequestHeader('Destination', destination)
     request.onload = () => {
-      if(request.status == 201 || request.status == 204) {
-        resolve();
+      if (request.status == 201 || request.status == 204) {
+        resolve()
       } else {
-        reject(request.statusText);
+        reject(request.statusText)
       }
     }
-    request.onerror = () => reject(request.statusText);
-    request.send();
-  });
+    request.onerror = () => reject(request.statusText)
+    request.send()
+  })
 }
 
 webdav.put = function (link, body, headers = {}) {
   return new Promise((resolve, reject) => {
-    let request = new XMLHttpRequest();
-    request.open('PUT', webdav.convertURL(link), true);
+    let request = new XMLHttpRequest()
+    request.open('PUT', webdav.convertURL(link), true)
 
-    for(let key in headers) {
-      request.setRequestHeader(key, headers[key]);
+    for (let key in headers) {
+      request.setRequestHeader(key, headers[key])
     }
 
     request.onload = () => {
-      if(request.status == 201) {
-        resolve();
+      if (request.status == 201) {
+        resolve()
       } else {
-        reject(request.statusText);
+        reject(request.statusText)
       }
     }
-    request.onerror = () => reject(request.statusText);
-    request.send(body);
-  });
+    request.onerror = () => reject(request.statusText)
+    request.send(body)
+  })
 }
 
 webdav.delete = function (link) {
   return new Promise((resolve, reject) => {
-    let request = new XMLHttpRequest();
-    request.open('DELETE', webdav.convertURL(link), true);
+    let request = new XMLHttpRequest()
+    request.open('DELETE', webdav.convertURL(link), true)
     request.onload = () => {
-      if(request.status == 204) {
-        resolve();
+      if (request.status == 204) {
+        resolve()
       } else {
-        reject(request.statusText);
+        reject(request.statusText)
       }
     }
-    request.onerror = () => reject(request.statusText);
-    request.send();
-  });
+    request.onerror = () => reject(request.statusText)
+    request.send()
+  })
 }
 
 webdav.new = function (link) {
   return new Promise((resolve, reject) => {
-    let request = new XMLHttpRequest();
-    request.open((link.endsWith("/") ? "MKCOL" : "PUT"), webdav.convertURL(link), true);
+    let request = new XMLHttpRequest()
+    request.open((link.endsWith('/') ? 'MKCOL' : 'PUT'), webdav.convertURL(link), true)
     request.onload = () => {
-      if(request.status == 201) {
-        resolve();
+      if (request.status == 201) {
+        resolve()
       } else {
-        reject(request.statusText);
+        reject(request.statusText)
       }
     }
-    request.onerror = () => reject(request.statusText);
-    request.send();
-  });
+    request.onerror = () => reject(request.statusText)
+    request.send()
+  })
 }
 
 /* * * * * * * * * * * * * * * *
@@ -214,150 +214,150 @@ webdav.new = function (link) {
  *            EVENTS           *
  *                             *
  * * * * * * * * * * * * * * * */
-function closePrompt(event) {
-  let prompt = document.querySelector('.prompt');
+function closePrompt (event) {
+  let prompt = document.querySelector('.prompt')
 
-  if(!prompt)
-    return;
+  if (!prompt)
+    return
 
-  if(typeof event != 'undefined') {
-    event.preventDefault();
+  if (typeof event != 'undefined') {
+    event.preventDefault()
   }
 
-  document.querySelector('.overlay').classList.remove('active');
-  prompt.classList.remove('active');
+  document.querySelector('.overlay').classList.remove('active')
+  prompt.classList.remove('active')
 
   setTimeout(() => {
-    prompt.remove();
-  }, 100);
+    prompt.remove()
+  }, 100)
 }
 
-function notImplemented(event) {
-  event.preventDefault();
-  clickOverlay.click();
+function notImplemented (event) {
+  event.preventDefault()
+  clickOverlay.click()
 
-  let clone = document.importNode(templates.info.content, true);
-  clone.querySelector('h3').innerHTML = 'Not implemented';
-  clone.querySelector('p').innerHTML = "Sorry, but this feature wasn't implemented yet.";
+  let clone = document.importNode(templates.info.content, true)
+  clone.querySelector('h3').innerHTML = 'Not implemented'
+  clone.querySelector('p').innerHTML = "Sorry, but this feature wasn't implemented yet."
 
   document.querySelector('body').appendChild(clone)
-  document.querySelector('.overlay').classList.add('active');
-  document.querySelector('.prompt').classList.add('active');
+  document.querySelector('.overlay').classList.add('active')
+  document.querySelector('.prompt').classList.add('active')
 }
 
 // Prevent Default event
 var preventDefault = function (event) {
-  event.preventDefault();
+  event.preventDefault()
 }
 
-function logoutEvent(event) {
-  let request = new XMLHttpRequest();
-  request.open('GET', window.location.pathname, true, "username", "password");
-  request.send();
+function logoutEvent (event) {
+  let request = new XMLHttpRequest()
+  request.open('GET', window.location.pathname, true, 'username', 'password')
+  request.send()
   request.onreadystatechange = function () {
-    if(request.readyState == 4) {
-      window.location = "/";
+    if (request.readyState == 4) {
+      window.location = '/'
     }
   }
 }
 
-function openEvent(event) {
-  if(event.currentTarget.classList.contains('disabled'))
-    return false;
+function openEvent (event) {
+  if (event.currentTarget.classList.contains('disabled'))
+    return false
 
-  let link = '?raw=true';
+  let link = '?raw=true'
 
-  if(selectedItems.length) {
-    link = document.getElementById(selectedItems[0]).dataset.url + link;
+  if (selectedItems.length) {
+    link = document.getElementById(selectedItems[0]).dataset.url + link
   } else {
-    link = window.location.pathname + link;
+    link = window.location.pathname + link
   }
 
-  window.open(link);
-  return false;
+  window.open(link)
+  return false
 }
 
-function deleteOnSingleFile() {
-  closePrompt();
-  buttons.setLoading('delete');
+function deleteOnSingleFile () {
+  closePrompt()
+  buttons.setLoading('delete')
 
-  let promises = [];
+  let promises = []
 
   webdav.delete(window.location.pathname)
     .then(() => {
-      window.location.pathname = removeLastDirectoryPartOf(window.location.pathname);
+      window.location.pathname = removeLastDirectoryPartOf(window.location.pathname)
     })
     .catch(e => {
-      buttons.setDone('delete', false);
+      buttons.setDone('delete', false)
       console.log(e)
     })
 }
 
-function deleteOnListing() {
-  closePrompt();
-  buttons.setLoading('delete');
+function deleteOnListing () {
+  closePrompt()
+  buttons.setLoading('delete')
 
-  let promises = [];
+  let promises = []
 
-  for(let id of selectedItems) {
-    promises.push(webdav.delete(document.getElementById(id).dataset.url));
+  for (let id of selectedItems) {
+    promises.push(webdav.delete(document.getElementById(id).dataset.url))
   }
 
   Promise.all(promises)
     .then(() => {
-      listing.reload();
-      buttons.setDone('delete');
+      listing.reload()
+      buttons.setDone('delete')
     })
     .catch(e => {
-      console.log(e);
-      buttons.setDone('delete', false);
+      console.log(e)
+      buttons.setDone('delete', false)
     })
 }
 
 // Handles the delete button event
-function deleteEvent(event) {
-  let single = false;
+function deleteEvent (event) {
+  let single = false
 
-  if(!selectedItems.length) {
-    selectedItems = ["placeholder"];
-    single = true;
+  if (!selectedItems.length) {
+    selectedItems = ['placeholder']
+    single = true
   }
 
-  let clone = document.importNode(templates.question.content, true);
-  clone.querySelector('h3').innerHTML = 'Delete files';
+  let clone = document.importNode(templates.question.content, true)
+  clone.querySelector('h3').innerHTML = 'Delete files'
 
-  if(single) {
-    clone.querySelector('form').addEventListener('submit', deleteOnSingleFile);
-    clone.querySelector('p').innerHTML = `Are you sure you want to delete this file/folder?`;
+  if (single) {
+    clone.querySelector('form').addEventListener('submit', deleteOnSingleFile)
+    clone.querySelector('p').innerHTML = `Are you sure you want to delete this file/folder?`
   } else {
-    clone.querySelector('form').addEventListener('submit', deleteOnListing);
-    clone.querySelector('p').innerHTML = `Are you sure you want to delete ${selectedItems.length} file(s)?`;
+    clone.querySelector('form').addEventListener('submit', deleteOnListing)
+    clone.querySelector('p').innerHTML = `Are you sure you want to delete ${selectedItems.length} file(s)?`
   }
 
-  clone.querySelector('input').remove();
-  clone.querySelector('.ok').innerHTML = 'Delete';
+  clone.querySelector('input').remove()
+  clone.querySelector('.ok').innerHTML = 'Delete'
 
-  document.body.appendChild(clone);
-  document.querySelector('.overlay').classList.add('active');
-  document.querySelector('.prompt').classList.add('active');
+  document.body.appendChild(clone)
+  document.querySelector('.overlay').classList.add('active')
+  document.querySelector('.prompt').classList.add('active')
 
-  return false;
+  return false
 }
 
-function resetSearchText() {
-  let box = document.querySelector('#search > div div');
+function resetSearchText () {
+  let box = document.querySelector('#search > div div')
 
-  if(user.AllowCommands) {
-    box.innerHTML = `Search or use one of your supported commands: ${user.Commands.join(", ")}.`;
+  if (user.AllowCommands) {
+    box.innerHTML = `Search or use one of your supported commands: ${user.Commands.join(", ")}.`
   } else {
-    box.innerHTML = "Type and press enter to search.";
+    box.innerHTML = 'Type and press enter to search.'
   }
 }
 
-function searchEvent(event) {
-  if(this.value.length == 0) {
-    resetSearchText();
-    return;
+function searchEvent (event) {
+  if (this.value.length == 0) {
+    resetSearchText()
+    return
   }
 
   let value = this.value,
@@ -365,143 +365,143 @@ function searchEvent(event) {
     scrollable = document.querySelector('#search > div'),
     box = document.querySelector('#search > div div'),
     pieces = value.split(' '),
-    supported = false;
+    supported = false
 
   user.Commands.forEach(function (cmd) {
-    if(cmd == pieces[0]) {
-      supported = true;
+    if (cmd == pieces[0]) {
+      supported = true
     }
-  });
+  })
 
-  if(!supported || !user.AllowCommands) {
-    box.innerHTML = "Press enter to search."
+  if (!supported || !user.AllowCommands) {
+    box.innerHTML = 'Press enter to search.'
   } else {
-    box.innerHTML = "Press enter to execute."
+    box.innerHTML = 'Press enter to execute.'
   }
 
-  if(event.keyCode == 13) {
-    box.innerHTML = '';
-    search.classList.add('ongoing');
+  if (event.keyCode == 13) {
+    box.innerHTML = ''
+    search.classList.add('ongoing')
 
-    let url = window.location.host + window.location.pathname;
+    let url = window.location.host + window.location.pathname
 
-    if(document.getElementById("editor")) {
-      url = removeLastDirectoryPartOf(url);
+    if (document.getElementById('editor')) {
+      url = removeLastDirectoryPartOf(url)
     }
 
-    let protocol = ssl ? 'wss:' : 'ws:';
+    let protocol = ssl ? 'wss:' : 'ws:'
 
-    if(supported && user.AllowCommands) {
-      let conn = new WebSocket(`${protocol}//${url}?command=true`);
+    if (supported && user.AllowCommands) {
+      let conn = new WebSocket(`${protocol}//${url}?command=true`)
 
       conn.onopen = function () {
-        conn.send(value);
-      };
+        conn.send(value)
+      }
 
       conn.onmessage = function (event) {
-        box.innerHTML = event.data;
-        scrollable.scrollTop = scrollable.scrollHeight;
+        box.innerHTML = event.data
+        scrollable.scrollTop = scrollable.scrollHeight
       }
 
       conn.onclose = function (event) {
-        search.classList.remove('ongoing');
-        listing.reload();
+        search.classList.remove('ongoing')
+        listing.reload()
       }
 
-      return;
+      return
     }
 
-    box.innerHTML = '<ul></ul>';
+    box.innerHTML = '<ul></ul>'
 
     let ul = box.querySelector('ul'),
-      conn = new WebSocket(`${protocol}//${url}?search=true`);
+      conn = new WebSocket(`${protocol}//${url}?search=true`)
 
     conn.onopen = function () {
-      conn.send(value);
-    };
+      conn.send(value)
+    }
 
     conn.onmessage = function (event) {
-      ul.innerHTML += '<li><a href="' + event.data + '">' + event.data + '</a></li>';
-      scrollable.scrollTop = scrollable.scrollHeight;
+      ul.innerHTML += '<li><a href="' + event.data + '">' + event.data + '</a></li>'
+      scrollable.scrollTop = scrollable.scrollHeight
     }
 
     conn.onclose = function (event) {
-      search.classList.remove('ongoing');
+      search.classList.remove('ongoing')
     }
   }
 }
 
-function setupSearch() {
-  let search = document.getElementById("search"),
-    searchInput = search.querySelector("input"),
-    searchDiv = search.querySelector("div"),
+function setupSearch () {
+  let search = document.getElementById('search'),
+    searchInput = search.querySelector('input'),
+    searchDiv = search.querySelector('div'),
     hover = false,
-    focus = false;
+    focus = false
 
-  resetSearchText();
+  resetSearchText()
 
   searchInput.addEventListener('focus', event => {
-    focus = true;
-    search.classList.add('active');
-  });
+    focus = true
+    search.classList.add('active')
+  })
 
   searchDiv.addEventListener('mouseover', event => {
-    hover = true;
-    search.classList.add('active');
-  });
+    hover = true
+    search.classList.add('active')
+  })
 
   searchInput.addEventListener('blur', event => {
-    focus = false;
-    if(hover)
-      return;
-    search.classList.remove('active');
-  });
+    focus = false
+    if (hover)
+      return
+    search.classList.remove('active')
+  })
 
   search.addEventListener('mouseleave', event => {
-    hover = false;
-    if(focus)
-      return;
-    search.classList.remove('active');
-  });
+    hover = false
+    if (focus)
+      return
+    search.classList.remove('active')
+  })
 
-  search.addEventListener("click", event => {
-    search.classList.add("active");
-    search.querySelector("input").focus();
-  });
+  search.addEventListener('click', event => {
+    search.classList.add('active')
+    search.querySelector('input').focus()
+  })
 
-  searchInput.addEventListener('keyup', searchEvent);
+  searchInput.addEventListener('keyup', searchEvent)
 }
 
-function closeHelp(event) {
-  event.preventDefault();
+function closeHelp (event) {
+  event.preventDefault()
 
-  document.querySelector('.help').classList.remove('active');
-  document.querySelector('.overlay').classList.remove('active');
+  document.querySelector('.help').classList.remove('active')
+  document.querySelector('.overlay').classList.remove('active')
 }
 
-function openHelp(event) {
-  closePrompt(event);
+function openHelp (event) {
+  closePrompt(event)
 
-  document.querySelector('.help').classList.add('active');
-  document.querySelector('.overlay').classList.add('active');
+  document.querySelector('.help').classList.add('active')
+  document.querySelector('.overlay').classList.add('active')
 }
 
 window.addEventListener('keydown', (event) => {
-  if(event.keyCode == 27) {
-    if(document.querySelector('.help.active')) {
-      closeHelp(event);
+  if (event.keyCode == 27) {
+    if (document.querySelector('.help.active')) {
+      closeHelp(event)
     }
   }
 
-  if(event.keyCode == 46) {
-    deleteEvent(event);
+  if (event.keyCode == 46) {
+    deleteEvent(event)
   }
 
-  if(event.keyCode == 112) {
-    event.preventDefault();
-    openHelp(event);
+  if (event.keyCode == 112) {
+    event.preventDefault()
+    openHelp(event)
   }
-});
+})
 
 /* * * * * * * * * * * * * * * *
  *                             *
@@ -509,64 +509,64 @@ window.addEventListener('keydown', (event) => {
  *                             *
  * * * * * * * * * * * * * * * */
 
-document.addEventListener("DOMContentLoaded", function (event) {
-  overlay = document.querySelector('.overlay');
-  clickOverlay = document.querySelector('#click-overlay');
+document.addEventListener('DOMContentLoaded', function (event) {
+  overlay = document.querySelector('.overlay')
+  clickOverlay = document.querySelector('#click-overlay')
 
-  buttons.logout = document.getElementById("logout");
-  buttons.open = document.getElementById("open");
-  buttons.delete = document.getElementById("delete");
-  buttons.previous = document.getElementById("previous");
+  buttons.logout = document.getElementById('logout')
+  buttons.open = document.getElementById('open')
+  buttons.delete = document.getElementById('delete')
+  buttons.previous = document.getElementById('previous')
 
   // Attach event listeners
-  buttons.logout.addEventListener("click", logoutEvent);
-  buttons.open.addEventListener("click", openEvent);
+  buttons.logout.addEventListener('click', logoutEvent)
+  buttons.open.addEventListener('click', openEvent)
 
-  templates.question = document.querySelector('#question-template');
-  templates.info = document.querySelector('#info-template');
-  templates.move = document.querySelector("#move-template");
+  templates.question = document.querySelector('#question-template')
+  templates.info = document.querySelector('#info-template')
+  templates.move = document.querySelector('#move-template')
 
-  if(user.AllowEdit) {
-    buttons.delete.addEventListener("click", deleteEvent);
+  if (user.AllowEdit) {
+    buttons.delete.addEventListener('click', deleteEvent)
   }
 
   let dropdownButtons = document.querySelectorAll('.action[data-dropdown]')
   Array.from(dropdownButtons).forEach(button => {
-    button.addEventListener("click", event => {
-      button.querySelector('ul').classList.toggle("active");
-      clickOverlay.classList.add('active');
+    button.addEventListener('click', event => {
+      button.querySelector('ul').classList.toggle('active')
+      clickOverlay.classList.add('active')
 
       clickOverlay.addEventListener('click', event => {
-        button.querySelector('ul').classList.remove("active");
-        clickOverlay.classList.remove('active');
+        button.querySelector('ul').classList.remove('active')
+        clickOverlay.classList.remove('active')
       })
-    });
-  });
-
-  overlay.addEventListener('click', event => {
-    if(document.querySelector('.help.active')) {
-      closeHelp(event);
-      return;
-    }
-
-    closePrompt(event);
-  })
-
-  let mainActions = document.getElementById('main-actions');
-
-  document.getElementById('more').addEventListener('click', event => {
-    event.preventDefault();
-    event.stopPropagation();
-
-    clickOverlay.classList.add('active');
-    mainActions.classList.add('active');
-
-    clickOverlay.addEventListener('click', event => {
-      mainActions.classList.remove('active');
-      clickOverlay.classList.remove('active');
     })
   })
 
-  setupSearch();
-  return false;
-});
\ No newline at end of file
+  overlay.addEventListener('click', event => {
+    if (document.querySelector('.help.active')) {
+      closeHelp(event)
+      return
+    }
+
+    closePrompt(event)
+  })
+
+  let mainActions = document.getElementById('main-actions')
+
+  document.getElementById('more').addEventListener('click', event => {
+    event.preventDefault()
+    event.stopPropagation()
+
+    clickOverlay.classList.add('active')
+    mainActions.classList.add('active')
+
+    clickOverlay.addEventListener('click', event => {
+      mainActions.classList.remove('active')
+      clickOverlay.classList.remove('active')
+    })
+  })
+
+  setupSearch()
+  return false
+})
diff --git a/_embed/public/js/editor.js b/_embed/public/js/editor.js
index 820663c6..38ff40c7 100644
--- a/_embed/public/js/editor.js
+++ b/_embed/public/js/editor.js
@@ -1,197 +1,197 @@
-'use strict';
+'use strict'
 
-var editor = {};
+var editor = {}
 
 editor.textareaAutoGrow = function () {
   let autogrow = function () {
     console.log(this.style.height)
-    this.style.height = 'auto';
-    this.style.height = (this.scrollHeight) + 'px';
+    this.style.height = 'auto'
+    this.style.height = (this.scrollHeight) + 'px'
   }
 
-  let textareas = document.getElementsByTagName('textarea');
+  let textareas = document.getElementsByTagName('textarea')
 
   let addAutoGrow = () => {
     Array.from(textareas).forEach(textarea => {
-      autogrow.bind(textarea)();
-      textarea.addEventListener('keyup', autogrow);
-    });
+      autogrow.bind(textarea)()
+      textarea.addEventListener('keyup', autogrow)
+    })
   }
 
-  addAutoGrow();
+  addAutoGrow()
   window.addEventListener('resize', addAutoGrow)
 }
 
 editor.toggleSourceEditor = function (event) {
-  event.preventDefault();
+  event.preventDefault()
 
-  if(document.querySelector('[data-kind="content-only"]')) {
-    window.location = window.location.pathname + "?visual=true"
-    return;
-  }
-
-  window.location = window.location.pathname + "?visual=false"
-}
-
-function deleteFrontMatterItem(event) {
-  event.preventDefault();
-  document.getElementById(this.dataset.delete).remove();
-}
-
-function makeFromBaseTemplate(id, type, name, parent) {
-  let clone = document.importNode(templates.base.content, true);
-  clone.querySelector('fieldset').id = id;
-  clone.querySelector('fieldset').dataset.type = type;
-  clone.querySelector('h3').innerHTML = name;
-  clone.querySelector('.delete').dataset.delete = id;
-  clone.querySelector('.delete').addEventListener('click', deleteFrontMatterItem);
-  clone.querySelector('.add').addEventListener('click', addFrontMatterItem);
-
-  if(parent.classList.contains("frontmatter")) {
-    parent.insertBefore(clone, document.querySelector('div.button.add'));
+  if (document.querySelector('[data-kind="content-only"]')) {
+    window.location = window.location.pathname + '?visual=true'
     return
   }
 
-  parent.appendChild(clone);
+  window.location = window.location.pathname + '?visual=false'
 }
 
-function makeFromArrayItemTemplate(id, number, parent) {
-  let clone = document.importNode(templates.arrayItem.content, true);
-  clone.querySelector('[data-type="array-item"]').id = `${id}-${number}`;
-  clone.querySelector('input').name = id;
-  clone.querySelector('input').id = id;
-  clone.querySelector('div.action').dataset.delete = `${id}-${number}`;
-  clone.querySelector('div.action').addEventListener('click', deleteFrontMatterItem);
-  parent.querySelector('.group').appendChild(clone)
-  document.getElementById(`${id}-${number}`).querySelector('input').focus();
+function deleteFrontMatterItem (event) {
+  event.preventDefault()
+  document.getElementById(this.dataset.delete).remove()
 }
 
-function makeFromObjectItemTemplate(id, name, parent) {
-  let clone = document.importNode(templates.objectItem.content, true);
-  clone.querySelector('.block').id = `block-${id}`;
-  clone.querySelector('.block').dataset.content = id;
-  clone.querySelector('label').for = id;
-  clone.querySelector('label').innerHTML = name;
-  clone.querySelector('input').name = id;
-  clone.querySelector('input').id = id;
-  clone.querySelector('.action').dataset.delete = `block-${id}`;
-  clone.querySelector('.action').addEventListener('click', deleteFrontMatterItem);
+function makeFromBaseTemplate (id, type, name, parent) {
+  let clone = document.importNode(templates.base.content, true)
+  clone.querySelector('fieldset').id = id
+  clone.querySelector('fieldset').dataset.type = type
+  clone.querySelector('h3').innerHTML = name
+  clone.querySelector('.delete').dataset.delete = id
+  clone.querySelector('.delete').addEventListener('click', deleteFrontMatterItem)
+  clone.querySelector('.add').addEventListener('click', addFrontMatterItem)
+
+  if (parent.classList.contains('frontmatter')) {
+    parent.insertBefore(clone, document.querySelector('div.button.add'))
+    return
+  }
 
   parent.appendChild(clone)
-  document.getElementById(id).focus();
 }
 
-function addFrontMatterItemPrompt(parent) {
-  return function (event) {
-    event.preventDefault();
+function makeFromArrayItemTemplate (id, number, parent) {
+  let clone = document.importNode(templates.arrayItem.content, true)
+  clone.querySelector('[data-type="array-item"]').id = `${id}-${number}`
+  clone.querySelector('input').name = id
+  clone.querySelector('input').id = id
+  clone.querySelector('div.action').dataset.delete = `${id}-${number}`
+  clone.querySelector('div.action').addEventListener('click', deleteFrontMatterItem)
+  parent.querySelector('.group').appendChild(clone)
+  document.getElementById(`${id}-${number}`).querySelector('input').focus()
+}
 
-    let value = event.currentTarget.querySelector('input').value;
-    if(value === '') {
-      return true;
+function makeFromObjectItemTemplate (id, name, parent) {
+  let clone = document.importNode(templates.objectItem.content, true)
+  clone.querySelector('.block').id = `block-${id}`
+  clone.querySelector('.block').dataset.content = id
+  clone.querySelector('label').for = id
+  clone.querySelector('label').innerHTML = name
+  clone.querySelector('input').name = id
+  clone.querySelector('input').id = id
+  clone.querySelector('.action').dataset.delete = `block-${id}`
+  clone.querySelector('.action').addEventListener('click', deleteFrontMatterItem)
+
+  parent.appendChild(clone)
+  document.getElementById(id).focus()
+}
+
+function addFrontMatterItemPrompt (parent) {
+  return function (event) {
+    event.preventDefault()
+
+    let value = event.currentTarget.querySelector('input').value
+    if (value === '') {
+      return true
     }
 
-    closePrompt(event);
+    closePrompt(event)
 
     let name = value.substring(0, value.lastIndexOf(':')),
-      type = value.substring(value.lastIndexOf(':') + 1, value.length);
+      type = value.substring(value.lastIndexOf(':') + 1, value.length)
 
-    if(type !== "" && type !== "array" && type !== "object") {
-      name = value;
+    if (type !== '' && type !== 'array' && type !== 'object') {
+      name = value
     }
 
-    name = name.replace(' ', '_');
+    name = name.replace(' ', '_')
 
-    let id = name;
+    let id = name
 
-    if(parent.id != '') {
-      id = parent.id + "." + id;
+    if (parent.id != '') {
+      id = parent.id + '.' + id
     }
 
-    if(type == "array" || type == "object") {
-      if(parent.dataset.type == "parent") {
-        makeFromBaseTemplate(id, type, name, document.querySelector('.frontmatter'));
-        return;
+    if (type == 'array' || type == 'object') {
+      if (parent.dataset.type == 'parent') {
+        makeFromBaseTemplate(id, type, name, document.querySelector('.frontmatter'))
+        return
       }
 
-      makeFromBaseTemplate(id, type, name, block);
-      return;
+      makeFromBaseTemplate(id, type, name, block)
+      return
     }
 
-    let group = parent.querySelector('.group');
+    let group = parent.querySelector('.group')
 
-    if(group == null) {
-      parent.insertAdjacentHTML('afterbegin', '<div class="group"></div>');
-      group = parent.querySelector('.group');
+    if (group == null) {
+      parent.insertAdjacentHTML('afterbegin', '<div class="group"></div>')
+      group = parent.querySelector('.group')
     }
 
-    makeFromObjectItemTemplate(id, name, group);
+    makeFromObjectItemTemplate(id, name, group)
   }
 }
 
-function addFrontMatterItem(event) {
-  event.preventDefault();
+function addFrontMatterItem (event) {
+  event.preventDefault()
 
   let parent = event.currentTarget.parentNode,
-    type = parent.dataset.type;
+    type = parent.dataset.type
 
   // If the block is an array
-  if(type === "array") {
-    let id = parent.id + "[]",
+  if (type === 'array') {
+    let id = parent.id + '[]',
       count = parent.querySelectorAll('.group > div').length,
-      fieldsets = parent.getElementsByTagName("fieldset");
+      fieldsets = parent.getElementsByTagName('fieldset')
 
-    if(fieldsets.length > 0) {
+    if (fieldsets.length > 0) {
       let itemType = fieldsets[0].dataset.type,
-        itemID = parent.id + "[" + fieldsets.length + "]",
-        itemName = fieldsets.length;
+        itemID = parent.id + '[' + fieldsets.length + ']',
+        itemName = fieldsets.length
 
-      makeFromBaseTemplate(itemID, itemType, itemName, parent);
+      makeFromBaseTemplate(itemID, itemType, itemName, parent)
     } else {
-      makeFromArrayItemTemplate(id, count, parent);
+      makeFromArrayItemTemplate(id, count, parent)
     }
 
-    return;
+    return
   }
 
-  if(type == "object" || type == "parent") {
-    let clone = document.importNode(templates.question.content, true);
-    clone.querySelector('form').id = tempID;
-    clone.querySelector('h3').innerHTML = 'New field';
-    clone.querySelector('p').innerHTML = 'Write the field name and then press enter. If you want to create an array or an object, end the name with <code>:array</code> or <code>:object.</code>';
-    clone.querySelector('.ok').innerHTML = 'Create';
-    clone.querySelector('form').addEventListener('submit', addFrontMatterItemPrompt(parent));
+  if (type == 'object' || type == 'parent') {
+    let clone = document.importNode(templates.question.content, true)
+    clone.querySelector('form').id = tempID
+    clone.querySelector('h3').innerHTML = 'New field'
+    clone.querySelector('p').innerHTML = 'Write the field name and then press enter. If you want to create an array or an object, end the name with <code>:array</code> or <code>:object.</code>'
+    clone.querySelector('.ok').innerHTML = 'Create'
+    clone.querySelector('form').addEventListener('submit', addFrontMatterItemPrompt(parent))
     clone.querySelector('form').classList.add('active')
-    document.querySelector('body').appendChild(clone);
+    document.querySelector('body').appendChild(clone)
 
-    document.querySelector('.overlay').classList.add('active');
-    document.getElementById(tempID).classList.add('active');
+    document.querySelector('.overlay').classList.add('active')
+    document.getElementById(tempID).classList.add('active')
   }
 
-  return false;
+  return false
 }
 
-document.addEventListener("DOMContentLoaded", (event) => {
-  if(!document.getElementById('editor')) return;
+document.addEventListener('DOMContentLoaded', (event) => {
+  if (!document.getElementById('editor')) return
 
-  editor.textareaAutoGrow();
+  editor.textareaAutoGrow()
 
-  templates.arrayItem = document.getElementById("array-item-template");
-  templates.base = document.getElementById('base-template');
-  templates.objectItem = document.getElementById("object-item-template");
-  templates.temporary = document.getElementById('temporary-template');
+  templates.arrayItem = document.getElementById('array-item-template')
+  templates.base = document.getElementById('base-template')
+  templates.objectItem = document.getElementById('object-item-template')
+  templates.temporary = document.getElementById('temporary-template')
 
-  buttons.save = document.querySelector('#save');
-  buttons.editSource = document.querySelector('#edit-source');
+  buttons.save = document.querySelector('#save')
+  buttons.editSource = document.querySelector('#edit-source')
 
-  if(buttons.editSource) {
+  if (buttons.editSource) {
     buttons.editSource.addEventListener('click', editor.toggleSourceEditor)
   }
 
   let container = document.getElementById('editor'),
     kind = container.dataset.kind,
-    rune = container.dataset.rune;
+    rune = container.dataset.rune
 
-  if(kind != 'frontmatter-only') {
+  if (kind != 'frontmatter-only') {
     let editor = document.querySelector('.content #ace'),
       mode = editor.dataset.mode,
       textarea = document.querySelector('textarea[name="content"]'),
@@ -199,80 +199,80 @@ document.addEventListener("DOMContentLoaded", (event) => {
       options = {
         wrap: true,
         maxLines: Infinity,
-        theme: "ace/theme/github",
+        theme: 'ace/theme/github',
         showPrintMargin: false,
-        fontSize: "1em",
+        fontSize: '1em',
         minLines: 20
-      };
+    }
 
-    aceEditor.getSession().setMode("ace/mode/" + mode);
-    aceEditor.getSession().setValue(textarea.value);
+    aceEditor.getSession().setMode('ace/mode/' + mode)
+    aceEditor.getSession().setValue(textarea.value)
     aceEditor.getSession().on('change', function () {
-      textarea.value = aceEditor.getSession().getValue();
-    });
+      textarea.value = aceEditor.getSession().getValue()
+    })
 
-    if(mode == "markdown") options.showGutter = false;
-    aceEditor.setOptions(options);
+    if (mode == 'markdown') options.showGutter = false
+    aceEditor.setOptions(options)
   }
 
-  let deleteFrontMatterItemButtons = document.getElementsByClassName('delete');
+  let deleteFrontMatterItemButtons = document.getElementsByClassName('delete')
   Array.from(deleteFrontMatterItemButtons).forEach(button => {
-    button.addEventListener('click', deleteFrontMatterItem);
-  });
+    button.addEventListener('click', deleteFrontMatterItem)
+  })
 
-  let addFrontMatterItemButtons = document.getElementsByClassName('add');
+  let addFrontMatterItemButtons = document.getElementsByClassName('add')
   Array.from(addFrontMatterItemButtons).forEach(button => {
-    button.addEventListener('click', addFrontMatterItem);
-  });
+    button.addEventListener('click', addFrontMatterItem)
+  })
 
   let saveContent = function () {
-    let data = form2js(document.querySelector('form'));
+    let data = form2js(document.querySelector('form'))
 
-    if(typeof data.content === "undefined" && kind != 'frontmatter-only') {
-      data.content = "";
+    if (typeof data.content === 'undefined' && kind !== 'frontmatter-only') {
+      data.content = ''
     }
 
-    if(typeof data.content === "number") {
-      data.content = data.content.toString();
+    if (typeof data.content === 'number') {
+      data.content = data.content.toString()
     }
 
-    let request = new XMLHttpRequest();
+    let request = new XMLHttpRequest()
 
     buttons.setLoading('save')
 
     webdav.put(window.location.pathname, JSON.stringify(data), {
-        'Kind': kind,
-        'Rune': rune
-      })
+      'Kind': kind,
+      'Rune': rune
+    })
       .then(() => {
         buttons.setDone('save')
       })
       .catch(e => {
-        console.log(e);
+        console.log(e)
         buttons.setDone('save', false)
       })
   }
 
   document.querySelector('#save').addEventListener('click', event => {
-    event.preventDefault();
-    saveContent();
-  });
+    event.preventDefault()
+    saveContent()
+  })
 
   document.querySelector('form').addEventListener('submit', (event) => {
-    event.preventDefault();
-    saveContent();
-  });
+    event.preventDefault()
+    saveContent()
+  })
 
   window.addEventListener('keydown', (event) => {
-    if(event.ctrlKey || event.metaKey) {
-      switch(String.fromCharCode(event.which).toLowerCase()) {
-      case 's':
-        event.preventDefault();
-        saveContent();
-        break;
+    if (event.ctrlKey || event.metaKey) {
+      switch (String.fromCharCode(event.which).toLowerCase()) {
+        case 's':
+          event.preventDefault()
+          saveContent()
+          break
       }
     }
-  });
+  })
 
-  return false;
-});
+  return false
+})
diff --git a/_embed/public/js/listing.js b/_embed/public/js/listing.js
index d1f339bf..8d534651 100644
--- a/_embed/public/js/listing.js
+++ b/_embed/public/js/listing.js
@@ -1,23 +1,23 @@
-'use strict';
+'use strict'
 
 var listing = {
   selectMultiple: false
-};
+}
 
 listing.reload = function (callback) {
-  let request = new XMLHttpRequest();
+  let request = new XMLHttpRequest()
 
-  request.open('GET', window.location);
-  request.setRequestHeader('Minimal', 'true');
-  request.send();
+  request.open('GET', window.location)
+  request.setRequestHeader('Minimal', 'true')
+  request.send()
   request.onreadystatechange = function () {
-    if(request.readyState == 4) {
-      if(request.status == 200) {
-        document.querySelector('body main').innerHTML = request.responseText;
-        listing.addDoubleTapEvent();
+    if (request.readyState === 4) {
+      if (request.status === 200) {
+        document.querySelector('body main').innerHTML = request.responseText
+        listing.addDoubleTapEvent()
 
-        if(typeof callback == 'function') {
-          callback();
+        if (typeof callback === 'function') {
+          callback()
         }
       }
     }
@@ -25,281 +25,281 @@ listing.reload = function (callback) {
 }
 
 listing.itemDragStart = function (event) {
-  let el = event.target;
+  let el = event.target
 
-  for(let i = 0; i < 5; i++) {
-    if(!el.classList.contains('item')) {
-      el = el.parentElement;
+  for (let i = 0; i < 5; i++) {
+    if (!el.classList.contains('item')) {
+      el = el.parentElement
     }
   }
 
-  event.dataTransfer.setData("id", el.id);
-  event.dataTransfer.setData("name", el.querySelector('.name').innerHTML);
+  event.dataTransfer.setData('id', el.id)
+  event.dataTransfer.setData('name', el.querySelector('.name').innerHTML)
 }
 
 listing.itemDragOver = function (event) {
-  event.preventDefault();
-  let el = event.target;
+  event.preventDefault()
+  let el = event.target
 
-  for(let i = 0; i < 5; i++) {
-    if(!el.classList.contains('item')) {
-      el = el.parentElement;
+  for (let i = 0; i < 5; i++) {
+    if (!el.classList.contains('item')) {
+      el = el.parentElement
     }
   }
 
-  el.style.opacity = 1;
+  el.style.opacity = 1
 }
 
 listing.itemDrop = function (e) {
-  e.preventDefault();
+  e.preventDefault()
 
   let el = e.target,
-    id = e.dataTransfer.getData("id"),
-    name = e.dataTransfer.getData("name");
+    id = e.dataTransfer.getData('id'),
+    name = e.dataTransfer.getData('name')
 
-  if(id == "" || name == "") return;
+  if (id == '' || name == '') return
 
-  for(let i = 0; i < 5; i++) {
-    if(!el.classList.contains('item')) {
-      el = el.parentElement;
+  for (let i = 0; i < 5; i++) {
+    if (!el.classList.contains('item')) {
+      el = el.parentElement
     }
   }
 
-  if(el.id === id) return;
+  if (el.id === id) return
 
   let oldLink = document.getElementById(id).dataset.url,
-    newLink = el.dataset.url + name;
+    newLink = el.dataset.url + name
 
   webdav.move(oldLink, newLink)
     .then(() => listing.reload())
-    .catch(e => console.log(e));
+    .catch(e => console.log(e))
 }
 
 listing.documentDrop = function (event) {
-  event.preventDefault();
+  event.preventDefault()
   let dt = event.dataTransfer,
     files = dt.files,
     el = event.target,
-    items = document.getElementsByClassName('item');
+    items = document.getElementsByClassName('item')
 
-  for(let i = 0; i < 5; i++) {
-    if(el != null && !el.classList.contains('item')) {
-      el = el.parentElement;
+  for (let i = 0; i < 5; i++) {
+    if (el != null && !el.classList.contains('item')) {
+      el = el.parentElement
     }
   }
 
-  if(files.length > 0) {
-    if(el != null && el.classList.contains('item') && el.dataset.dir == "true") {
-      listing.handleFiles(files, el.querySelector('.name').innerHTML + "/");
-      return;
+  if (files.length > 0) {
+    if (el != null && el.classList.contains('item') && el.dataset.dir == 'true') {
+      listing.handleFiles(files, el.querySelector('.name').innerHTML + '/')
+      return
     }
 
-    listing.handleFiles(files, "");
+    listing.handleFiles(files, '')
   } else {
     Array.from(items).forEach(file => {
-      file.style.opacity = 1;
-    });
+      file.style.opacity = 1
+    })
   }
 }
 
 listing.rename = function (event) {
-  if(!selectedItems.length || selectedItems.length > 1) {
-    return false;
+  if (!selectedItems.length || selectedItems.length > 1) {
+    return false
   }
 
-  let item = document.getElementById(selectedItems[0]);
+  let item = document.getElementById(selectedItems[0])
 
-  if(item.classList.contains('disabled')) {
-    return false;
+  if (item.classList.contains('disabled')) {
+    return false
   }
 
   let link = item.dataset.url,
     field = item.querySelector('.name'),
-    name = field.innerHTML;
+    name = field.innerHTML
 
   let submit = (event) => {
-    event.preventDefault();
+    event.preventDefault()
 
     let newName = event.currentTarget.querySelector('input').value,
-      newLink = removeLastDirectoryPartOf(link) + "/" + newName;
+      newLink = removeLastDirectoryPartOf(link) + '/' + newName
 
-    closePrompt(event);
-    buttons.setLoading('rename');
+    closePrompt(event)
+    buttons.setLoading('rename')
 
     webdav.move(link, newLink).then(() => {
       listing.reload(() => {
-        newName = btoa(newName);
-        selectedItems = [newName];
-        document.getElementById(newName).setAttribute("aria-selected", true);
-        listing.handleSelectionChange();
-      });
+        newName = btoa(newName)
+        selectedItems = [newName]
+        document.getElementById(newName).setAttribute('aria-selected', true)
+        listing.handleSelectionChange()
+      })
 
-      buttons.setDone('rename');
+      buttons.setDone('rename')
     }).catch(error => {
-      field.innerHTML = name;
-      buttons.setDone('rename', false);
-      console.log(error);
-    });
+      field.innerHTML = name
+      buttons.setDone('rename', false)
+      console.log(error)
+    })
 
-    return false;
+    return false
   }
 
-  let clone = document.importNode(templates.question.content, true);
-  clone.querySelector('h3').innerHTML = 'Rename';
-  clone.querySelector('input').value = name;
-  clone.querySelector('.ok').innerHTML = 'Rename';
-  clone.querySelector('form').addEventListener('submit', submit);
+  let clone = document.importNode(templates.question.content, true)
+  clone.querySelector('h3').innerHTML = 'Rename'
+  clone.querySelector('input').value = name
+  clone.querySelector('.ok').innerHTML = 'Rename'
+  clone.querySelector('form').addEventListener('submit', submit)
 
   document.querySelector('body').appendChild(clone)
-  document.querySelector('.overlay').classList.add('active');
-  document.querySelector('.prompt').classList.add('active');
+  document.querySelector('.overlay').classList.add('active')
+  document.querySelector('.prompt').classList.add('active')
 
-  return false;
+  return false
 }
 
 listing.handleFiles = function (files, base) {
-  buttons.setLoading('upload');
+  buttons.setLoading('upload')
 
-  let promises = [];
+  let promises = []
 
-  for(let file of files) {
-    promises.push(webdav.put(window.location.pathname + base + file.name, file));
+  for (let file of files) {
+    promises.push(webdav.put(window.location.pathname + base + file.name, file))
   }
 
   Promise.all(promises)
     .then(() => {
-      listing.reload();
-      buttons.setDone('upload');
+      listing.reload()
+      buttons.setDone('upload')
     })
     .catch(e => {
-      console.log(e);
-      buttons.setDone('upload', false);
+      console.log(e)
+      buttons.setDone('upload', false)
     })
 
-  return false;
+  return false
 }
 
 listing.unselectAll = function () {
-  let items = document.getElementsByClassName('item');
+  let items = document.getElementsByClassName('item')
   Array.from(items).forEach(link => {
-    link.setAttribute("aria-selected", false);
-  });
+    link.setAttribute('aria-selected', false)
+  })
 
-  selectedItems = [];
+  selectedItems = []
 
-  listing.handleSelectionChange();
-  return false;
+  listing.handleSelectionChange()
+  return false
 }
 
 listing.handleSelectionChange = function (event) {
-  listing.redefineDownloadURLs();
+  listing.redefineDownloadURLs()
 
   let selectedNumber = selectedItems.length,
-    fileAction = document.getElementById("file-only");
+    fileAction = document.getElementById('file-only')
 
-  if(selectedNumber) {
-    fileAction.classList.remove("disabled");
+  if (selectedNumber) {
+    fileAction.classList.remove('disabled')
 
-    if(selectedNumber > 1) {
-      buttons.open.classList.add("disabled");
-      buttons.rename.classList.add("disabled");
+    if (selectedNumber > 1) {
+      buttons.open.classList.add('disabled')
+      buttons.rename.classList.add('disabled')
     }
 
-    if(selectedNumber == 1) {
-      if(document.getElementById(selectedItems[0]).dataset.dir == "true") {
-        buttons.open.classList.add("disabled");
+    if (selectedNumber == 1) {
+      if (document.getElementById(selectedItems[0]).dataset.dir == 'true') {
+        buttons.open.classList.add('disabled')
       } else {
-        buttons.open.classList.remove("disabled");
+        buttons.open.classList.remove('disabled')
       }
 
-      buttons.rename.classList.remove("disabled");
+      buttons.rename.classList.remove('disabled')
     }
 
-    return false;
+    return false
   }
 
-  fileAction.classList.add("disabled");
-  return false;
+  fileAction.classList.add('disabled')
+  return false
 }
 
 listing.redefineDownloadURLs = function () {
-  let files = "";
+  let files = ''
 
-  for(let i = 0; i < selectedItems.length; i++) {
-    let url = document.getElementById(selectedItems[i]).dataset.url;
-    files += url.replace(window.location.pathname, "") + ",";
+  for (let i = 0; i < selectedItems.length; i++) {
+    let url = document.getElementById(selectedItems[i]).dataset.url
+    files += url.replace(window.location.pathname, '') + ','
   }
 
-  files = files.substring(0, files.length - 1);
-  files = encodeURIComponent(files);
+  files = files.substring(0, files.length - 1)
+  files = encodeURIComponent(files)
 
-  let links = document.querySelectorAll("#download ul a");
+  let links = document.querySelectorAll('#download ul a')
   Array.from(links).forEach(link => {
-    link.href = "?download=" + link.dataset.format + "&files=" + files;
-  });
+    link.href = '?download=' + link.dataset.format + '&files=' + files
+  })
 }
 
 listing.openItem = function (event) {
-  window.location = event.currentTarget.dataset.url;
+  window.location = event.currentTarget.dataset.url
 }
 
 listing.selectItem = function (event) {
-  let el = event.currentTarget;
+  let el = event.currentTarget
 
-  if(selectedItems.length != 0) event.preventDefault();
-  if(selectedItems.indexOf(el.id) == -1) {
-    if(!event.ctrlKey && !listing.selectMultiple) listing.unselectAll();
+  if (selectedItems.length != 0) event.preventDefault()
+  if (selectedItems.indexOf(el.id) == -1) {
+    if (!event.ctrlKey && !listing.selectMultiple) listing.unselectAll()
 
-    el.setAttribute("aria-selected", true);
-    selectedItems.push(el.id);
+    el.setAttribute('aria-selected', true)
+    selectedItems.push(el.id)
   } else {
-    el.setAttribute("aria-selected", false);
-    selectedItems.removeElement(el.id);
+    el.setAttribute('aria-selected', false)
+    selectedItems.removeElement(el.id)
   }
 
-  listing.handleSelectionChange();
-  return false;
+  listing.handleSelectionChange()
+  return false
 }
 
 listing.newFileButton = function (event) {
-  event.preventDefault();
+  event.preventDefault()
 
-  let clone = document.importNode(templates.question.content, true);
-  clone.querySelector('h3').innerHTML = 'New file';
-  clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir.';
-  clone.querySelector('.ok').innerHTML = 'Create';
-  clone.querySelector('form').addEventListener('submit', listing.newFilePrompt);
+  let clone = document.importNode(templates.question.content, true)
+  clone.querySelector('h3').innerHTML = 'New file'
+  clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir.'
+  clone.querySelector('.ok').innerHTML = 'Create'
+  clone.querySelector('form').addEventListener('submit', listing.newFilePrompt)
 
   document.querySelector('body').appendChild(clone)
-  document.querySelector('.overlay').classList.add('active');
-  document.querySelector('.prompt').classList.add('active');
+  document.querySelector('.overlay').classList.add('active')
+  document.querySelector('.prompt').classList.add('active')
 }
 
 listing.newFilePrompt = function (event) {
-  event.preventDefault();
-  buttons.setLoading('new');
+  event.preventDefault()
+  buttons.setLoading('new')
 
-  let name = event.currentTarget.querySelector('input').value;
+  let name = event.currentTarget.querySelector('input').value
 
   webdav.new(window.location.pathname + name)
     .then(() => {
-      buttons.setDone('new');
-      listing.reload();
+      buttons.setDone('new')
+      listing.reload()
     })
     .catch(e => {
-      console.log(e);
-      buttons.setDone('new', false);
-    });
+      console.log(e)
+      buttons.setDone('new', false)
+    })
 
-  closePrompt(event);
-  return false;
+  closePrompt(event)
+  return false
 }
 
 listing.updateColumns = function (event) {
   let columns = Math.floor(document.getElementById('listing').offsetWidth / 300),
-    items = getCSSRule(['#listing.mosaic .item', '.mosaic#listing .item']);
+    items = getCSSRule(['#listing.mosaic .item', '.mosaic#listing .item'])
 
-  items.style.width = `calc(${100/columns}% - 1em)`;
+  items.style.width = `calc(${100/columns}% - 1em)`
 }
 
 listing.addDoubleTapEvent = function () {
@@ -307,273 +307,272 @@ listing.addDoubleTapEvent = function () {
     touches = {
       id: '',
       count: 0
-    };
+  }
 
   Array.from(items).forEach(file => {
     file.addEventListener('touchstart', event => {
-      if(touches.id != file.id) {
-        touches.id = file.id;
-        touches.count = 1;
+      if (touches.id != file.id) {
+        touches.id = file.id
+        touches.count = 1
 
         setTimeout(() => {
-          touches.count = 0;
+          touches.count = 0
         }, 300)
 
-        return;
+        return
       }
 
-      touches.count++;
+      touches.count++
 
-      if(touches.count > 1) {
-        window.location = file.dataset.url;
+      if (touches.count > 1) {
+        window.location = file.dataset.url
       }
-    });
-  });
+    })
+  })
 }
 
 // Keydown events
 window.addEventListener('keydown', (event) => {
-  if(event.keyCode == 27) {
-    listing.unselectAll();
+  if (event.keyCode == 27) {
+    listing.unselectAll()
 
-    if(document.querySelectorAll('.prompt').length) {
-      closePrompt(event);
+    if (document.querySelectorAll('.prompt').length) {
+      closePrompt(event)
     }
   }
 
-  if(event.keyCode == 113) {
-    listing.rename();
+  if (event.keyCode == 113) {
+    listing.rename()
   }
 
-  if(event.ctrlKey || event.metaKey) {
-    switch(String.fromCharCode(event.which).toLowerCase()) {
-    case 's':
-      event.preventDefault();
-      window.location = "?download=true"
+  if (event.ctrlKey || event.metaKey) {
+    switch (String.fromCharCode(event.which).toLowerCase()) {
+      case 's':
+        event.preventDefault()
+        window.location = '?download=true'
     }
   }
-});
+})
 
-window.addEventListener("resize", () => {
-  listing.updateColumns();
-});
+window.addEventListener('resize', () => {
+  listing.updateColumns()
+})
 
 listing.selectMoveFolder = function (event) {
-  if(event.target.getAttribute("aria-selected") === "true") {
-    event.target.setAttribute("aria-selected", false);
-    return;
+  if (event.target.getAttribute('aria-selected') === 'true') {
+    event.target.setAttribute('aria-selected', false)
+    return
   } else {
-    if(document.querySelector(".file-list li[aria-selected=true]")) {
-      document.querySelector(".file-list li[aria-selected=true]").setAttribute("aria-selected", false);
+    if (document.querySelector('.file-list li[aria-selected=true]')) {
+      document.querySelector('.file-list li[aria-selected=true]').setAttribute('aria-selected', false)
     }
-    event.target.setAttribute("aria-selected", true);
-    return;
+    event.target.setAttribute('aria-selected', true)
+    return
   }
 }
 
 listing.getJSON = function (link) {
   return new Promise((resolve, reject) => {
-    let request = new XMLHttpRequest();
-    request.open("GET", link);
-    request.setRequestHeader("Accept", "application/json");
+    let request = new XMLHttpRequest()
+    request.open('GET', link)
+    request.setRequestHeader('Accept', 'application/json')
     request.onload = () => {
-      if(request.status == 200) {
-        resolve(request.responseText);
+      if (request.status == 200) {
+        resolve(request.responseText)
       } else {
-        reject(request.statusText);
+        reject(request.statusText)
       }
     }
-    request.onerror = () => reject(request.statusText);
-    request.send();
-  });
+    request.onerror = () => reject(request.statusText)
+    request.send()
+  })
 }
 
 listing.moveMakeItem = function (url, name) {
-  let node = document.createElement("li"),
-    count = 0;
+  let node = document.createElement('li'),
+    count = 0
 
-  node.dataset.url = url;
-  node.innerHTML = name;
-  node.setAttribute("aria-selected", false);
+  node.dataset.url = url
+  node.innerHTML = name
+  node.setAttribute('aria-selected', false)
 
-  node.addEventListener("dblclick", listing.moveDialogNext);
-  node.addEventListener("click", listing.selectMoveFolder);
+  node.addEventListener('dblclick', listing.moveDialogNext)
+  node.addEventListener('click', listing.selectMoveFolder)
   node.addEventListener('touchstart', event => {
-    count++;
+    count++
 
     setTimeout(() => {
-      count = 0;
+      count = 0
     }, 300)
 
-    if(count > 1) {
-      listing.moveDialogNext(event);
+    if (count > 1) {
+      listing.moveDialogNext(event)
     }
-  });
+  })
 
-  return node;
+  return node
 }
 
 listing.moveDialogNext = function (event) {
   let request = new XMLHttpRequest(),
-    prompt = document.querySelector("form.prompt.active"),
-    list = prompt.querySelector("div.file-list ul");
+    prompt = document.querySelector('form.prompt.active'),
+    list = prompt.querySelector('div.file-list ul')
 
-  prompt.addEventListener("submit", listing.moveSelected);
+  prompt.addEventListener('submit', listing.moveSelected)
 
   listing.getJSON(event.target.dataset.url)
     .then((data) => {
-      let dirs = 0;
+      let dirs = 0
 
-      prompt.querySelector("ul").innerHTML = "";
-      prompt.querySelector('code').innerHTML = event.target.dataset.url;
+      prompt.querySelector('ul').innerHTML = ''
+      prompt.querySelector('code').innerHTML = event.target.dataset.url
 
-      if(event.target.dataset.url != baseURL + "/") {
-        let node = listing.moveMakeItem(removeLastDirectoryPartOf(event.target.dataset.url) + "/", "..")
-        list.appendChild(node);
+      if (event.target.dataset.url != baseURL + '/') {
+        let node = listing.moveMakeItem(removeLastDirectoryPartOf(event.target.dataset.url) + '/', '..')
+        list.appendChild(node)
       }
 
-      if(JSON.parse(data) == null) {
-        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
-        return;
+      if (JSON.parse(data) == null) {
+        prompt.querySelector('p').innerHTML = `There aren't any folders in this directory.`
+        return
       }
 
-      for(let f of JSON.parse(data)) {
-        if(f.IsDir === true) {
-          dirs++;
-          list.appendChild(listing.moveMakeItem(f.URL, f.Name));
+      for (let f of JSON.parse(data)) {
+        if (f.IsDir === true) {
+          dirs++
+          list.appendChild(listing.moveMakeItem(f.URL, f.Name))
         }
       }
 
-      if(dirs === 0)
-        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
+      if (dirs === 0)
+        prompt.querySelector('p').innerHTML = `There aren't any folders in this directory.`
     })
-    .catch(e => console.log(e));
+    .catch(e => console.log(e))
 }
 
 listing.moveSelected = function (event) {
-  event.preventDefault();
+  event.preventDefault()
 
-  let promises = [];
-  buttons.setLoading("move");
+  let promises = []
+  buttons.setLoading('move')
 
-  for(let file of selectedItems) {
+  for (let file of selectedItems) {
     let fileElement = document.getElementById(file),
-      destFolder = event.target.querySelector("p code").innerHTML;
+      destFolder = event.target.querySelector('p code').innerHTML
 
-    if(event.currentTarget.querySelector("li[aria-selected=true]") != null) {
-      destFolder = event.currentTarget.querySelector("li[aria-selected=true]").dataset.url;
+    if (event.currentTarget.querySelector('li[aria-selected=true]') != null) {
+      destFolder = event.currentTarget.querySelector('li[aria-selected=true]').dataset.url
     }
 
-    let destPath = "/" + destFolder + "/" + fileElement.querySelector(".name").innerHTML;
-    destPath = destPath.replace('//', '/');
+    let destPath = '/' + destFolder + '/' + fileElement.querySelector('.name').innerHTML
+    destPath = destPath.replace('//', '/')
 
-    promises.push(webdav.move(fileElement.dataset.url, destPath));
+    promises.push(webdav.move(fileElement.dataset.url, destPath))
   }
 
   Promise.all(promises)
     .then(() => {
-      closePrompt(event);
-      buttons.setDone("move");
-      listing.reload();
+      closePrompt(event)
+      buttons.setDone('move')
+      listing.reload()
     })
     .catch(e => {
-      console.log(e);
+      console.log(e)
     })
 }
 
 listing.moveEvent = function (event) {
-  if(event.currentTarget.classList.contains("disabled"))
-    return;
+  if (event.currentTarget.classList.contains('disabled'))
+    return
 
   listing.getJSON(window.location.pathname)
     .then((data) => {
       let prompt = document.importNode(templates.move.content, true),
-        list = prompt.querySelector("div.file-list ul"),
-        dirs = 0;
+        list = prompt.querySelector('div.file-list ul'),
+        dirs = 0
 
-      prompt.querySelector("form").addEventListener("submit", listing.moveSelected);
-      prompt.querySelector('code').innerHTML = window.location.pathname;
+      prompt.querySelector('form').addEventListener('submit', listing.moveSelected)
+      prompt.querySelector('code').innerHTML = window.location.pathname
 
-      if(window.location.pathname !== baseURL + "/") {
-        list.appendChild(listing.moveMakeItem(removeLastDirectoryPartOf(window.location.pathname) + "/", ".."));
+      if (window.location.pathname !== baseURL + '/') {
+        list.appendChild(listing.moveMakeItem(removeLastDirectoryPartOf(window.location.pathname) + '/', '..'))
       }
 
-      for(let f of JSON.parse(data)) {
-        if(f.IsDir === true) {
-          dirs++;
-          list.appendChild(listing.moveMakeItem(f.URL, f.Name));
+      for (let f of JSON.parse(data)) {
+        if (f.IsDir === true) {
+          dirs++
+          list.appendChild(listing.moveMakeItem(f.URL, f.Name))
         }
       }
 
-      if(dirs === 0) {
-        prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
+      if (dirs === 0) {
+        prompt.querySelector('p').innerHTML = `There aren't any folders in this directory.`
       }
 
-      document.body.appendChild(prompt);
-      document.querySelector(".overlay").classList.add("active");
-      document.querySelector(".prompt").classList.add("active");
+      document.body.appendChild(prompt)
+      document.querySelector('.overlay').classList.add('active')
+      document.querySelector('.prompt').classList.add('active')
     })
-    .catch(e => console.log(e));
+    .catch(e => console.log(e))
 }
 
 document.addEventListener('DOMContentLoaded', event => {
-  listing.updateColumns();
-  listing.addDoubleTapEvent();
+  listing.updateColumns()
+  listing.addDoubleTapEvent()
 
-  buttons.rename = document.getElementById("rename");
-  buttons.upload = document.getElementById("upload");
-  buttons.new = document.getElementById('new');
-  buttons.download = document.getElementById('download');
-  buttons.move = document.getElementById("move");
+  buttons.rename = document.getElementById('rename')
+  buttons.upload = document.getElementById('upload')
+  buttons.new = document.getElementById('new')
+  buttons.download = document.getElementById('download')
+  buttons.move = document.getElementById('move')
 
-  buttons.move.addEventListener("click", listing.moveEvent);
+  buttons.move.addEventListener('click', listing.moveEvent)
 
   document.getElementById('multiple-selection-activate').addEventListener('click', event => {
-    listing.selectMultiple = true;
-    clickOverlay.click();
+    listing.selectMultiple = true
+    clickOverlay.click()
 
-    document.getElementById('multiple-selection').classList.add('active');
-    document.querySelector('body').style.paddingBottom = "4em";
+    document.getElementById('multiple-selection').classList.add('active')
+    document.querySelector('body').style.paddingBottom = '4em'
   })
 
   document.getElementById('multiple-selection-cancel').addEventListener('click', event => {
-    listing.selectMultiple = false;
+    listing.selectMultiple = false
 
-    document.querySelector('body').style.paddingBottom = "0";
-    document.getElementById('multiple-selection').classList.remove('active');
+    document.querySelector('body').style.paddingBottom = '0'
+    document.getElementById('multiple-selection').classList.remove('active')
   })
 
-  if(user.AllowEdit) {
-    buttons.rename.addEventListener("click", listing.rename);
+  if (user.AllowEdit) {
+    buttons.rename.addEventListener('click', listing.rename)
   }
 
-  let items = document.getElementsByClassName('item');
+  let items = document.getElementsByClassName('item')
 
-  if(user.AllowNew) {
-    buttons.upload.addEventListener("click", (event) => {
-      document.getElementById("upload-input").click();
-    });
+  if (user.AllowNew) {
+    buttons.upload.addEventListener('click', (event) => {
+      document.getElementById('upload-input').click()
+    })
 
-    buttons.new.addEventListener('click', listing.newFileButton);
+    buttons.new.addEventListener('click', listing.newFileButton)
 
     // Drag and Drop
-    document.addEventListener("dragover", function (event) {
-      event.preventDefault();
-    }, false);
+    document.addEventListener('dragover', function (event) {
+      event.preventDefault()
+    }, false)
 
-    document.addEventListener("dragenter", (event) => {
+    document.addEventListener('dragenter', (event) => {
       Array.from(items).forEach(file => {
-        file.style.opacity = 0.5;
-      });
-    }, false);
+        file.style.opacity = 0.5
+      })
+    }, false)
 
-    document.addEventListener("dragend", (event) => {
+    document.addEventListener('dragend', (event) => {
       Array.from(items).forEach(file => {
-        file.style.opacity = 1;
-      });
-    }, false);
+        file.style.opacity = 1
+      })
+    }, false)
 
-    document.addEventListener("drop", listing.documentDrop, false);
+    document.addEventListener('drop', listing.documentDrop, false)
   }
-
-});
+})
diff --git a/assets/binary.go.REMOVED.git-id b/assets/binary.go.REMOVED.git-id
index 0a512d2f..9393f263 100644
--- a/assets/binary.go.REMOVED.git-id
+++ b/assets/binary.go.REMOVED.git-id
@@ -1 +1 @@
-75755022adfcafcbf6d563ce4af52fc022e6f163
\ No newline at end of file
+407ca3a29b2bf1bf0e7fb611b732dffd77ed0083
\ No newline at end of file
diff --git a/filemanager.go b/filemanager.go
index a06bc4dc..ab508eae 100644
--- a/filemanager.go
+++ b/filemanager.go
@@ -1,8 +1,3 @@
-//go:generate go get github.com/jteeuwen/go-bindata/go-bindata
-//go:generate go get github.com/bountylabs/gitversion
-//go:generate go-bindata -pkg assets -prefix "_embed" -o assets/binary.go _embed/templates/... _embed/public/js/... _embed/public/css/... _embed/public/ace/src-min/...
-//go:generate gitversion -s -o page/version.go -p page
-
 // Package filemanager provides middleware for managing files in a directory
 // when directory path is requested instead of a specific file. Based on browse
 // middleware.
diff --git a/page/version.go b/page/version.go
index 702e24fc..8c105721 100644
--- a/page/version.go
+++ b/page/version.go
@@ -1,5 +1,5 @@
 package page
 
-var GIT_COMMIT_HASH = "6b261bb"
+var GIT_COMMIT_HASH = "df081c8"
 var CIRCLE_BUILD_NUM = ""
-var GENERATED int64 = 1490520061033206900
+var GENERATED int64 = 1490523864386631900
diff --git a/pre-build.sh b/pre-build.sh
new file mode 100644
index 00000000..35f74e4e
--- /dev/null
+++ b/pre-build.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+go get github.com/jteeuwen/go-bindata/go-bindata
+go get github.com/bountylabs/gitversion
+
+go-bindata -pkg assets -prefix "_embed" \
+  -o assets/binary.go -ignore "^.*theme-([^g]|g[^i]|gi[^t]|git[^h]|gith[^u]|githu[^b]).*\.js$" \
+  _embed/templates/... _embed/public/js/... _embed/public/css/... _embed/public/ace/src-min/...
+
+gitversion -s -o page/version.go -p page
+git add -A