code:
var draggable = {};

draggable.setDraggable = function(element, dragElement) {

  var dragglableInfo = {};

  var stopMoving = function() {

    if (!dragglableInfo.shouldMove) {
      return;
    }

    dragglableInfo.shouldMove = false
    draggable.lockedDrag = false

    var body = document.getElementsByTagName('body')[0];

    body.onmouseup = dragglableInfo.originalMouseUp;

  };

  var startMoving = function(evt) {

    if (dragglableInfo.shouldMove || draggable.lockedDrag) {
      return;
    }

    evt.preventDefault();

    draggable.lockedDrag = true;

    var body = document.getElementsByTagName('body')[0];

    dragglableInfo.originalMouseUp = body.onmouseup;

    body.onmouseup = function() {
      stopMoving();
    };

    dragglableInfo.shouldMove = true;

    evt = evt || window.event;

    var rect = element.getBoundingClientRect();

    dragglableInfo.diffX = evt.clientX - rect.left;
    dragglableInfo.diffY = evt.clientY - rect.top;

  };

  var move = function(evt) {

    if (!dragglableInfo.shouldMove) {
      return;
    }

    evt = evt || window.event;

    var newX = evt.clientX - dragglableInfo.diffX;
    var newY = evt.clientY - dragglableInfo.diffY;

    if (newX < 0) {
      newX = 0;
    }

    if (newY < 0) {
      newY = 0;
    }

    var upperXLimit = document.body.clientWidth - element.offsetWidth;

    if (newX > upperXLimit) {
      newX = upperXLimit;
    }

    var upperYLimit = window.innerHeight - element.offsetHeight;

    if (newY > upperYLimit) {
      newY = upperYLimit;
    }

    element.style.left = newX + 'px';
    element.style.top = newY + 'px';

  };

  dragElement.onmousedown = startMoving
  document.getElementsByTagName('body')[0].addEventListener('mousemove', move);

};


code:
var edit = {};

edit.init = function() {

  api.convertButton('saveFormButton', edit.save);

  edit.messageLimit = +document.getElementById('labelMessageLength').innerHTML;
  api.boardUri = document.getElementById('boardIdentifier').value;

  var threadElement = document.getElementById('threadIdentifier');

  if (threadElement) {
    api.threadId = threadElement.value;
  } else {
    api.postId = document.getElementById('postIdentifier').value;
  }

};

edit.save = function() {

  var typedMessage = document.getElementById('fieldMessage').value.trim();

  var typedSubject = document.getElementById('fieldSubject').value.trim();

  if (typedSubject.length > 128) {
    alert('Subject too long, keep it under 128 characters.');
  } else if (!typedMessage.length) {
    alert('A message is mandatory.');
  } else if (typedMessage.length > edit.messageLimit) {
    alert('Message too long, keep it under ' + edit.messageLimit
        + ' characters.');
  } else {

    var parameters = {
      boardUri : api.boardUri,
      message : typedMessage,
      subject : typedSubject
    };

    if (api.postId) {
      parameters.postId = api.postId;
    } else {
      parameters.threadId = api.threadId;
    }

    api.formApiRequest('saveEdit', parameters, function requestComplete(status,
        data) {

      if (status === 'ok') {
        alert('Posting edited.');
      } else {
        alert(status + ': ' + JSON.stringify(data));
      }
    });

  }

};

edit.init();

repo_name: milk/PenumbraLynx

license: mit


code:
var embed = {};

embed.init = function() {

  var messageElements = document.getElementsByClassName("divMessage");

  for (var i = 0; i < messageElements.length; ++i) {
    var linkElements = messageElements[i].getElementsByTagName("a");

    for (var j = 0; j < linkElements.length; ++j)
      embed.processLinkForEmbed(linkElements[j]);
  }

};

embed.processLinkForEmbed = function(linkElement) {

  var url = linkElement.href;
  var domain = embed.getDomain(url);

  if (!domain) {
    return;
  }

  var domainSrcFunction = embed.domainFunctionMap[domain];

  if (!domainSrcFunction) {
    return;

  }

  var embedSrc = domainSrcFunction(url);

  if (!embedSrc) {
    return;
  }

  linkElement.parentNode.insertBefore(embed.buildEmbed(650, 350, embedSrc),
      linkElement.nextSibling);

};

embed.buildEmbed = function(width, height, src) {

  var html = '<iframe';
  html += ' width="' + width + '"';
  html += ' height="' + height + '"';
  html += ' src="' + src + '"';
  html += ' frameborder="0"';
  html += ' allowfullscreen';
  html += '></iframe>';

  var wrapperElement = document.createElement('div');
  wrapperElement.style.display = 'inline';

  var divElement = document.createElement('div');
  divElement.style.display = 'none';

  var buttonElement = document.createElement('span');
  buttonElement.innerHTML = '[Embed]';
  buttonElement.className = 'embedButton glowOnHover';

  buttonElement.onclick = function() {
    if (divElement.style.display === 'none') {
      divElement.style.display = 'block';
      divElement.innerHTML = html;
      buttonElement.innerHTML = '[Remove]';
    }

    else {
      divElement.style.display = 'none';
      divElement.innerHTML = null;
      buttonElement.innerHTML = '[Embed]';
    }
  };

  // note: append order
  wrapperElement.appendChild(buttonElement);
  wrapperElement.appendChild(divElement);

  return wrapperElement;

};

// substrings to the first occurrence of an input string if present
embed.getUntil = function(string, input) {

  var inputIndex = string.indexOf(input);

  return inputIndex !== -1 ? string.substring(0, inputIndex) : string;

};

embed.getDomain = function(url) {
  return url.match(/\b(?!www.)\b([a-z0-9]+\.)*[a-z0-9]+\.[a-z]+/i)[0];
};

embed.getSrcYouTubeCommon = function(url, secure, domain) {

  var videoId = url.split('v=')[1];

  if (!videoId) {
    return;
  }

  videoId = embed.getUntil(videoId, '&');

  var embedSrc = secure ? 'https' : 'http';
  embedSrc += '://' + domain + '/embed/' + videoId;

  var startTime = embed.getYouTubeStartTime(url);

  if (startTime) {
    embedSrc += '?start=' + startTime;
  }

  return embedSrc;

};

embed.getSrcYouTube = function(url) {
  return embed.getSrcYouTubeCommon(url, true, 'www.youtube.com');
};

embed.getSrcInvidious = function(url) {
  return embed.getSrcYouTubeCommon(url, true, 'www.invidio.us');
};

embed.getSrcYouTubeShortened = function(url) {

  var videoId = url.split('/')[3];

  if (!videoId) {
    return;
  }

  // trim any params in the url
  videoId = embed.getUntil(videoId, '?');

  var embedSrc = 'https://www.youtube.com/embed/' + videoId;

  var startTime = embed.getYouTubeStartTime(url);

  if (startTime) {
    embedSrc += '?start=' + startTime;
  }

  return embedSrc;

};

embed.getSrcBitChute = function(url) {

  if (!url.includes('/video/')) {
    return;
  }

  var videoId = url.split('/')[4];

  if (!videoId) {
    return;
  }

  return 'https://www.bitchute.com/embed/' + videoId;

};

embed.getSrcLiveLeak = function(url) {

  var videoId = url.split('t=')[1];

  if (!videoId) {
    return;
  }

  return 'https://www.liveleak.com/e/' + embed.getUntil(videoId, '&');

};

// translate ?t=XhXmXs to raw seconds (the only input supported by youtube's
// embed start time)
// todo: recode with loop
embed.getYouTubeStartTime = function(url) {

  var startTime = url.split('t=')[1];

  if (!startTime) {
    return;
  }

  startTime = embed.getUntil(startTime, '&');

  var totalSeconds = 0;

  var hours = startTime.match(/(\d+)(?:h)/);

  if (hours) {
    totalSeconds += parseInt(hours[1]) * 3600;
  }

  var minutes = startTime.match(/(\d+)(?:m)/);

  if (minutes) {
    totalSeconds += parseInt(minutes[1]) * 60;
  }

  var seconds = startTime.match(/(\d+)(?:s)/);

  if (seconds) {
    totalSeconds += parseInt(seconds[1]);
  }

  return totalSeconds;

};

embed.domainFunctionMap = {};

embed.domainFunctionMap['youtube.com'] = embed.getSrcYouTube;
embed.domainFunctionMap['youtu.be'] = embed.getSrcYouTubeShortened;
embed.domainFunctionMap['invidio.us'] = embed.getSrcInvidious;
embed.domainFunctionMap['bitchute.com'] = embed.getSrcBitChute;
embed.domainFunctionMap['liveleak.com'] = embed.getSrcLiveLeak;

embed.init();


code:
var favouriteBoards = {};

favouriteBoards.init = function() {

  favouriteBoards.setFavouriteBoards();

  var boardLabel = document.getElementById('labelName')
      || document.getElementById('labelBoard');

  if (boardLabel) {

    var savedFavouriteBoards = JSON.parse(localStorage.savedFavouriteBoards
        || '[]');

    var favouriteButton = document.createElement('span');
    favouriteButton.id = 'favouriteButton';
    boardLabel.parentNode.appendChild(favouriteButton);

    if (savedFavouriteBoards.indexOf(api.boardUri) > -1) {
      favouriteButton.className = 'checkedFavouriteButton';
    }

    favouriteButton.onclick = function() {
      savedFavouriteBoards = JSON.parse(localStorage.savedFavouriteBoards
          || '[]');

      var index = savedFavouriteBoards.indexOf(api.boardUri);

      if (index > -1) {
        savedFavouriteBoards.splice(index, 1);
        favouriteButton.removeAttribute('class');
      } else {
        savedFavouriteBoards.push(api.boardUri);
        savedFavouriteBoards.sort();
        favouriteButton.className = 'checkedFavouriteButton';
      }

      localStorage.setItem('savedFavouriteBoards', JSON
          .stringify(savedFavouriteBoards));

      favouriteBoards.setFavouriteBoards();

    };

  }

};

favouriteBoards.setFavouriteBoards = function() {

  var savedFavouriteBoards = JSON.parse(localStorage.savedFavouriteBoards
      || '[]');

  var boardsSpan = document.getElementById('navBoardsSpan');

  while (boardsSpan.hasChildNodes()) {
    boardsSpan.removeChild(boardsSpan.lastChild);
  }

  if (savedFavouriteBoards.length) {

    var firstBracket = document.createElement('span');
    firstBracket.innerHTML = '[';
    boardsSpan.appendChild(firstBracket);

    boardsSpan.appendChild(document.createTextNode(' '));

    for (var i = 0; i < savedFavouriteBoards.length; i++) {

      var link = document.createElement('a');
      link.href = '/' + savedFavouriteBoards[i];
      link.innerHTML = savedFavouriteBoards[i];
      boardsSpan.appendChild(link);

      boardsSpan.appendChild(document.createTextNode(' '));

      if (i < savedFavouriteBoards.length - 1) {

        var divider = document.createElement('span');
        divider.innerHTML = '/';
        boardsSpan.appendChild(divider);

        boardsSpan.appendChild(document.createTextNode(' '));
      }

    }

    var secondBracket = document.createElement('span');
    secondBracket.innerHTML = ']';
    boardsSpan.appendChild(secondBracket);
  }

};

favouriteBoards.init();


code:
var filterManagement = {};

filterManagement.init = function() {

  var boardIdentifier = document.getElementById('boardIdentifier')

  api.boardUri = boardIdentifier ? boardIdentifier.value : '';

  api.convertButton('addFormButton', filterManagement.addFilter,
      'addFilterField');

  var filtersDiv = document.getElementById('divFilters');

  for (var j = 0; j < filtersDiv.childNodes.length; j++) {
    filterManagement.processFilterCell(filtersDiv.childNodes[j]);
  }

  filterManagement.divFilters = filtersDiv;

};

filterManagement.processFilterCell = function(cell) {

  var button = cell.getElementsByClassName('deleteFormButton')[0];

  api.convertButton(button, function() {
    filterManagement.removeFilter(cell);
  });

};

filterManagement.removeFilter = function(cell) {

  api.formApiRequest('deleteFilter', {
    boardUri : api.boardUri,
    filterIdentifier : cell.getElementsByClassName('filterIdentifier')[0].value
  }, function requestComplete(status, data) {

    if (status === 'ok') {
      cell.remove();
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

filterManagement.seekCell = function(filter) {

  var candidates = document.getElementsByClassName('labelOriginal');

  for (var i = 0; i < candidates.length; i++) {

    if (candidates[i].innerHTML === filter) {
      return candidates[i];
    }

  }

};

filterManagement.addFilter = function() {

  var typedOriginal = document.getElementById('fieldOriginalTerm').value.trim();
  var typedReplacement = document.getElementById('fieldReplacementTerm').value
      .trim();
  var caseInsensitive = document.getElementById('checkboxCaseInsensitive').checked;

  if (!typedOriginal.length || !typedReplacement.length) {
    alert('Both fields are mandatory.');
    return;
  } else if (typedOriginal.length > 32 || typedReplacement.length > 32) {
    alert('Both fields cannot exceed 32 characters.');
    return;
  }

  api
      .formApiRequest(
          'createFilter',
          {
            boardUri : api.boardUri,
            originalTerm : typedOriginal,
            caseInsensitive : caseInsensitive,
            replacementTerm : typedReplacement
          },
          function requestComplete(status, data) {

            if (status === 'ok') {

              document.getElementById('fieldOriginalTerm').value = '';
              document.getElementById('fieldReplacementTerm').value = '';

              var existing = filterManagement.seekCell(typedOriginal);

              if (existing) {
                existing.parentNode.parentNode
                    .getElementsByClassName('labelReplacement')[0].innerHTML = typedReplacement;

                return;
              }

              var form = document.createElement('form');
              form.className = 'filterCell';
              form.action = '/deleteFilter.js';
              form.method = 'post';
              form.enctype = 'multipart/form-data';

              var originalPara = document.createElement('p');
              originalPara.innerHTML = 'Original term: ';
              form.appendChild(originalPara);

              var originalLabel = document.createElement('span');
              originalLabel.className = 'labelOriginal';
              originalLabel.innerHTML = typedOriginal;
              originalPara.appendChild(originalLabel);

              var replacementPara = document.createElement('p');
              replacementPara.innerHTML = 'Replacement term: ';
              form.appendChild(replacementPara);

              var replacementLabel = document.createElement('span');
              replacementLabel.className = 'labelReplacement';
              replacementLabel.innerHTML = typedReplacement;
              replacementPara.appendChild(replacementLabel);

              if (caseInsensitive) {
                var casePara = document.createElement('p');
                casePara.innerHTML = 'Case-insensitive';
                casePara.className = 'labelCaseInsensitive';
                form.appendChild(casePara);
              }

              var boardIdentifier = document.createElement('input');
              boardIdentifier.value = api.boardUri;
              boardIdentifier.name = 'boardUri';
              boardIdentifier.type = 'hidden';
              boardIdentifier.className = 'boardIdentifier';
              form.appendChild(boardIdentifier);

              var filterIdentifier = document.createElement('input');
              filterIdentifier.value = typedOriginal;
              filterIdentifier.name = 'filterIdentifier';
              filterIdentifier.type = 'hidden';
              filterIdentifier.className = 'filterIdentifier';
              form.appendChild(filterIdentifier);

              var submitButton = document.createElement('button');
              submitButton.type = 'submit';
              submitButton.className = 'deleteFormButton';
              submitButton.innerHTML = 'Delete';
              form.appendChild(submitButton);

              filterManagement.divFilters.appendChild(form);

              filterManagement.processFilterCell(form);

            } else {
              alert(status + ': ' + JSON.stringify(data));
            }
          });

}

filterManagement.init();


code:
var flags = {};

flags.init = function() {

  flags.maxLength = +document.getElementById('maxNameLengthLabel').innerHTML;
  flags.selectedFiles = [];

  api.boardUri = document.getElementById('boardIdentifier').value;

  api.convertButton('addFormButton', flags.uploadFlags);

  flags.flagsDiv = document.getElementById('flagsDiv');

  var flagCells = document.getElementsByClassName('flagCell');

  for (var i = 0; i < flagCells.length; i++) {
    flags.processFlagCell(flagCells[i]);
  }

  var dragAndDrop = document.getElementById('dragAndDropDiv');
  dragAndDrop.className = '';

  var dropZone = document.getElementById('dropzone');

  var defaultFileChooser = document.getElementById('files');

  defaultFileChooser.setAttribute('multiple', true);
  defaultFileChooser.style.display = 'none';

  defaultFileChooser.onchange = function() {

    for (var i = 0; i < defaultFileChooser.files.length; i++) {
      flags.addSelectedFlag(defaultFileChooser.files[i]);
    }

    defaultFileChooser.type = "text";
    defaultFileChooser.type = "file";
  };

  dropZone.onclick = function() {
    defaultFileChooser.click();
  };

  dropZone.addEventListener('dragover', function handleDragOver(event) {

    event.stopPropagation();
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';

  }, false);

  dropZone.addEventListener('drop', function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    for (var i = 0; i < evt.dataTransfer.files.length; i++) {
      flags.addSelectedFlag(evt.dataTransfer.files[i])
    }

  }, false);

  document.getElementById('nameLabel').style.display = 'none';

};

flags.addSelectedFlag = function(file) {

  if (file.type.indexOf('image/')) {
    alert('You can only upload images for flags');
    return;
  }

  var selectedDiv = document.getElementById('selectedDiv');

  var cell = document.createElement('div');
  cell.className = 'selectedCell';

  var removeButton = document.createElement('div');
  removeButton.className = 'removeButton';
  removeButton.innerHTML = '✖';
  cell.appendChild(removeButton);

  var nameField = document.createElement('input');
  nameField.className = 'nameField';
  nameField.type = 'text';
  nameField.addEventListener('keydown', function(event) {

    if (event.key === 'Enter') {
      flags.uploadFlags();
    }

  });
  nameField.value = file.name.substring(0, file.name.lastIndexOf('.'));
  cell.appendChild(nameField);

  cell.appendChild(document.createElement('br'));

  var dndThumb = document.createElement('img');
  dndThumb.className = 'dragAndDropThumb';
  cell.appendChild(dndThumb);

  removeButton.onclick = function() {
    var index = flags.selectedFiles.indexOf(file);

    selectedDiv.removeChild(cell);

    flags.selectedFiles.splice(flags.selectedFiles.indexOf(file), 1);
  };

  flags.selectedFiles.push(file);

  var fileReader = new FileReader();

  fileReader.onloadend = function() {

    dndThumb.src = fileReader.result;

    selectedDiv.appendChild(cell);

  };

  fileReader.readAsDataURL(file);

};

flags.processFlagCell = function(cell) {

  var button = cell.getElementsByClassName('deleteFormButton')[0];

  api.convertButton(button, function() {
    flags.removeFlag(cell);
  });

};

flags.removeFlag = function(cell) {

  api.formApiRequest('deleteFlag', {
    flagId : cell.getElementsByClassName('idIdentifier')[0].value,
  }, function requestComplete(status, data) {

    if (status === 'ok') {
      cell.remove();
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

flags.showNewFlag = function(typedName, id) {

  var form = document.createElement('form');
  form.method = 'post';
  form.enctype = 'multipart/form-data';
  form.action = '/deleteFlag.js';
  form.className = 'flagCell';

  var flagName = document.createElement('div');
  flagName.innerHTML = typedName;
  flagName.className = 'nameLabel';
  form.appendChild(flagName);

  var flagImage = document.createElement('img');
  flagImage.className = 'flagImg';
  flagImage.src = '/' + api.boardUri + '/flags/' + id;
  form.appendChild(flagImage);

  form.appendChild(document.createElement('br'));

  var flagIdentifier = document.createElement('input');
  flagIdentifier.className = 'idIdentifier';
  flagIdentifier.value = id;
  flagIdentifier.type = 'hidden';
  form.appendChild(flagIdentifier);

  var deleteButton = document.createElement('button');
  deleteButton.type = 'submit';
  deleteButton.className = 'deleteFormButton';
  deleteButton.innerHTML = 'Delete';
  form.appendChild(deleteButton);

  form.appendChild(document.createElement('hr'));

  flags.flagsDiv.appendChild(form);

  flags.processFlagCell(form);

};

flags.uploadFlags = function() {

  if (!flags.selectedFiles.length) {
    return;
  }

  var typedName = document.getElementsByClassName('nameField')[0].value.trim();

  if (typedName.length > flags.maxLength) {
    alert('Flag name too long, keep it under ' + flags.maxLength
        + ' characters.');
    return;
  } else if (!typedName.length) {
    alert('A name is mandatory for the flag.');
    return;
  }

  api.formApiRequest('createFlag', {
    files : [ {
      content : flags.selectedFiles[0]
    } ],
    flagName : typedName,
    boardUri : api.boardUri,
  }, function requestComplete(status, data) {

    if (status === 'ok') {

      document.getElementsByClassName('removeButton')[0].onclick();

      flags.showNewFlag(typedName, data);

      flags.uploadFlags();

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

flags.init();


code:
var gallery = {};

gallery.init = function() {

  gallery.galleryFiles = [];
  gallery.currentIndex = 0;

  var imageLinks = document.getElementsByClassName('imgLink');

  for (var i = 0; i < imageLinks.length; i++) {

    var link = imageLinks[i];

    if (link.dataset.filemime && link.dataset.filemime.indexOf('image/') > -1) {
      gallery.addGalleryFile(link.href);
    }
  }

  var backLink = document.getElementById('linkBack');

  var galleryLink = document.createElement('a');
  galleryLink.title = 'Gallery mode.\nLeft/right arrow: previous/next\nUp/down arrow: skip 10 previous/next\nHome/End: first/last\nEsc: exit\nDelete: remove from gallery';
  galleryLink.id = 'galleryLink';
  galleryLink.className = 'coloredIcon';
  backLink.parentNode.insertBefore(galleryLink, backLink);

  backLink.parentNode.insertBefore(document.createTextNode(' '), backLink);

  var separator = document.createElement('span');
  separator.innerHTML = '/';
  backLink.parentNode.insertBefore(separator, backLink);

  backLink.parentNode.insertBefore(document.createTextNode(' '), backLink);

  var outerPanel;

  galleryLink.onclick = function() {

    if (!gallery.galleryFiles.length) {
      alert('No images to see');
      return;
    }

    outerPanel = document.createElement('div');
    outerPanel.className = 'modalPanel';
    document.body.appendChild(outerPanel);

    var innerPanel = document.createElement('div');
    innerPanel.className = 'modalInnerPanel';
    outerPanel.appendChild(innerPanel);

    gallery.galleryImage = document.createElement('img');
    gallery.galleryImage.className = 'galleryImage';
    innerPanel.appendChild(gallery.galleryImage);

    gallery.previousImage = document.createElement('img');
    gallery.previousImage.style.display = 'none';
    gallery.nextImage = document.createElement('img');
    gallery.nextImage.style.display = 'none';

    innerPanel.appendChild(gallery.nextImage);
    innerPanel.appendChild(gallery.previousImage);

    gallery.displayImage(gallery.currentIndex);

    gallery.viewingGallery = true;

  }

  document.body.addEventListener('keydown', function clicked(event) {

    if (!gallery.viewingGallery) {
      return;
    }

    switch (event.key) {

    case 'Escape': {
      outerPanel.remove();
      gallery.viewingGallery = false;
      event.preventDefault();

      break;
    }

    case 'Home': {
      gallery.displayImage(0);
      event.preventDefault();
      break;
    }

    case 'End': {
      gallery.displayImage(gallery.galleryFiles.length - 1);
      event.preventDefault();
      break;
    }

    case 'ArrowDown': {
      gallery.displayImage(gallery.currentIndex + 10);
      event.preventDefault();
      break;
    }

    case 'ArrowUp': {
      gallery.displayImage(gallery.currentIndex - 10);
      event.preventDefault();
      break;
    }

    case 'ArrowLeft': {
      gallery.displayImage(gallery.currentIndex - 1);
      event.preventDefault();
      break;
    }

    case 'ArrowRight': {
      gallery.displayImage(gallery.currentIndex + 1);
      event.preventDefault();
      break;
    }

    case 'Delete': {
      gallery.galleryFiles.splice(gallery.currentIndex, 1);

      if (!gallery.galleryFiles.length) {
        outerPanel.remove();
        return;
      } else {
        gallery.displayImage(gallery.currentIndex);
      }
      event.preventDefault();

      break;
    }

    }

  });

};

gallery.displayImage = function(index) {

  if (index < 0) {
    index = 0;
  } else if (index >= gallery.galleryFiles.length) {
    index = gallery.galleryFiles.length - 1;
  }

  gallery.currentIndex = index;

  gallery.galleryImage.src = gallery.galleryFiles[index];

  if (index > 0) {
    gallery.previousImage.src = gallery.galleryFiles[index - 1];
  }

  if (index < gallery.galleryFiles.length - 1) {
    gallery.nextImage.src = gallery.galleryFiles[index + 1];
  }

};

gallery.addGalleryFile = function(url) {

  if (gallery.galleryFiles.indexOf(url) === -1) {
    gallery.galleryFiles.push(url);
  }

};

if (!api.mobile) {
  gallery.init();
}


code:
var globalManagement = {};

globalManagement.roles = [ 'Admin', 'Global volunteer', 'Global janitor',
    'User' ];

globalManagement.init = function() {

  api.management = true;

  if (document.getElementById('addStaffForm')) {

    api
        .convertButton('addFormButton', globalManagement.addUser,
            'addUserField');
    api.convertButton('massBanFormButton', globalManagement.massBan,
        'massBanField');

  }

  globalManagement.divStaff = document.getElementById('divStaff');

  api.convertButton('closeReportsFormButton', reports.closeReports,
      'closeReportsField');

  var staffCells = document.getElementsByClassName('staffCell');

  for (var i = 0; i < staffCells.length; i++) {
    globalManagement.processCell(staffCells[i]);
  }

};

globalManagement.processCell = function(cell) {

  var button = cell.getElementsByClassName('saveFormButton')[0];

  var comboBox = cell.getElementsByClassName('roleCombo')[0];
  var user = cell.getElementsByClassName('userIdentifier')[0].value;

  api.convertButton(button, function() {
    globalManagement.setUser(user,
        comboBox.options[comboBox.selectedIndex].value, cell);
  });

};

globalManagement.addUser = function() {

  var combo = document.getElementById('newStaffCombo');

  globalManagement.setUser(document.getElementById('fieldLogin').value.trim(),
      combo.options[combo.selectedIndex].value);

};

globalManagement.showNewUser = function(login, role) {

  var form = document.createElement('form');
  form.method = 'post';
  form.enctype = 'multipart/form-data';
  form.action = '/setGlobalRole.js';
  form.className = 'staffCell';

  var nameLabel = document.createElement('span');
  nameLabel.innerHTML = login;
  nameLabel.className = 'userLabel';
  form.appendChild(nameLabel);

  form.appendChild(document.createTextNode(' '));

  var combo = document.createElement('select');
  combo.name = 'role';
  combo.className = 'roleCombo';
  form.appendChild(combo);

  for (var i = document.getElementById('globalSettingsLink') ? 0 : 1; i < globalManagement.roles.length; i++) {

    var option = document.createElement('option');
    option.innerHTML = globalManagement.roles[i];
    option.value = (i + 1).toString();

    if (i === role - 1) {
      option.setAttribute('selected', 'selected');
    }

    combo.appendChild(option);

  }

  var identifier = document.createElement('input');
  identifier.className = 'userIdentifier';
  identifier.type = 'hidden';
  identifier.value = login;
  form.appendChild(identifier);

  var wrapper = document.createElement('label');
  form.appendChild(wrapper);

  var button = document.createElement('button');
  button.type = 'submit';
  button.className = 'saveFormButton';
  button.innerHTML = 'Save role';
  wrapper.appendChild(button);

  globalManagement.divStaff.appendChild(form);

  globalManagement.processCell(form);

};

globalManagement.setUser = function(login, role, cell) {

  role = +role;

  api.formApiRequest('setGlobalRole', {
    login : login,
    role : role
  }, function requestComplete(status, data) {

    if (status === 'ok') {

      if (role <= 3 && cell) {
        alert('Role changed.');
      } else if (cell) {
        cell.remove();
      } else {
        globalManagement.showNewUser(login, role);
      }

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

globalManagement.massBan = function() {

  var ipField = document.getElementById('fieldIps');
  var reasonField = document.getElementById('fieldReason');
  var durationField = document.getElementById('fieldDuration');

  var typedIps = ipField.value.trim();

  var ipArray = typedIps.split(',');

  var finalIpArray = [];

  for (var i = 0; i < ipArray.length; i++) {

    var ip = ipArray[i].trim();

    if (ip.length) {
      finalIpArray.push(ip);
    }

  }

  if (!finalIpArray.length) {
    alert('No ips informed');
    return;
  }

  var typedReason = reasonField.value;
  var typedDuration = durationField.value;

  api.formApiRequest('massBan', {
    ips : finalIpArray,
    reason : typedReason,
    duration : typedDuration
  }, function requestCompleted(status, data) {

    if (status === 'ok') {

      ipField.value = '';
      reasonField.value = '';
      durationField.value = '';

      alert('Mass ban applied.');

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

globalManagement.init();


code:
var globalSettings = {};

globalSettings.init = function() {

  api.convertButton('saveFormButton', globalSettings.save,
      'globalSettingsField');

  globalSettings.siteSettingsRelation = {

    fieldSlaves : {
      setting : 'slaves',
      type : 'string'
    },
    checkboxSendmail : {
      type : 'boolean',
      setting : 'useSendmail',
    },
    checkboxRedactModNames : {
      type : 'boolean',
      setting : 'redactModNames',
    },
    checkboxUnboundBoardLimits : {
      type : 'boolean',
      setting : 'unboundBoardLimits',
    },
    checkboxGlobalBanners : {
      type : 'boolean',
      setting : 'useGlobalBanners',
    },
    checkboxStripExif : {
      type : 'boolean',
      setting : 'stripExif',
    },
    checkboxValidateMimes : {
      type : 'boolean',
      setting : 'validateMimes',
    },
    checkboxDisableLatestPostings : {
      type : 'boolean',
      setting : 'disableLatestPostings',
    },
    checkboxVerboseCache : {
      type : 'boolean',
      setting : 'verboseCache',
    },
    checkboxVolunteerSettings : {
      type : 'boolean',
      setting : 'allowVolunteerSettings',
    },
    checkboxVerboseGenerator : {
      type : 'boolean',
      setting : 'verboseGenerator',
    },
    checkboxDontProcessLinks : {
      type : 'boolean',
      setting : 'dontProcessLinks',
    },
    checkboxHttp2 : {
      type : 'boolean',
      setting : 'useHttp2',
    },
    checkboxBoardStaffArchiving : {
      type : 'boolean',
      setting : 'allowBoardStaffArchiving',
    },
    checkboxVerboseQueue : {
      type : 'boolean',
      setting : 'verboseQueue',
    },
    checkboxOmitUnindexedContent : {
      type : 'boolean',
      setting : 'omitUnindexedContent',
    },
    fieldMaxBoardHashBans : {
      type : 'string',
      setting : 'maxBoardHashBans',
    },
    fieldMaxBoardGeneralBans : {
      type : 'string',
      setting : 'maxBoardGeneralBans',
    },
    fieldLatestPostsAmount : {
      type : 'string',
      setting : 'latestPostsAmount',
    },
    fieldFileProcessingLimit : {
      type : 'string',
      setting : 'fileProcessingLimit',
    },
    fieldImageFont : {
      type : 'string',
      setting : 'imageFont',
    },
    checkboxVerboseGridfs : {
      type : 'boolean',
      setting : 'verboseGridfs',
    },
    checkboxBlockedReport : {
      type : 'boolean',
      setting : 'allowBlockedToReport',
    },
    checkboxVerboseMisc : {
      type : 'boolean',
      setting : 'verboseMisc',
    },
    checkboxVerboseApis : {
      type : 'boolean',
      setting : 'verboseApis',
    },
    checkboxDisableCatalogPosting : {
      type : 'boolean',
      setting : 'disableCatalogPosting',
    },
    checkboxDisableCatalogPosting : {
      type : 'boolean',
      setting : 'disableCatalogPosting',
    },
    checkboxAllowTorFiles : {
      type : 'boolean',
      setting : 'allowTorFiles',
    },
    checkboxUseAlternativeLanguages : {
      type : 'boolean',
      setting : 'useAlternativeLanguages',
    },
    fieldIpExpiration : {
      type : 'string',
      setting : 'ipExpirationDays'
    },
    fieldAuthenticationLimit : {
      type : 'string',
      setting : 'authenticationLimit'
    },
    fieldClusterPort : {
      type : 'string',
      setting : 'clusterPort'
    },
    fieldIncrementalSpamIpsSource : {
      type : 'string',
      setting : 'incSpamIpsSource'
    },
    fieldMaxBoardBanners : {
      type : 'string',
      setting : 'maxBoardBanners'
    },
    fieldMaster : {
      setting : 'master',
      type : 'string'
    },
    fieldFileLimit : {
      setting : 'fileLimit',
      type : 'string'
    },
    fieldTorDNSL : {
      setting : 'torDNSBL',
      type : 'string'
    },
    fieldTrustedProxies : {
      setting : 'trustedProxies',
      type : 'string'
    },
    fieldMessageLength : {
      setting : 'messageLength',
      type : 'string'
    },
    fieldTorPort : {
      setting : 'torPort',
      type : 'string'
    },
    fieldBoardMessageLength : {
      setting : 'boardMessageLength',
      type : 'string'
    },
    fieldSpamIpsSource : {
      setting : 'spamIpsSource',
      type : 'string'
    },
    fieldCaptchaLimit : {
      setting : 'captchaLimit',
      type : 'string'
    },
    fieldDnsbl : {
      setting : 'dnsbl',
      type : 'string'
    },
    fieldAddress : {
      setting : 'address',
      type : 'string'
    },
    fieldMediaPageSize : {
      setting : 'mediaPageSize',
      type : 'string'
    },
    fieldBypassHours : {
      type : 'string',
      setting : 'bypassDurationHours',
    },
    fieldRssDomain : {
      setting : 'rssDomain',
      type : 'string'
    },
    fieldInactivityThreshold : {
      setting : 'inactivityThreshold',
      type : 'string'
    },
    fieldCSP : {
      setting : 'CSP',
      type : 'string'
    },
    fieldPort : {
      setting : 'port',
      type : 'string'
    },
    fieldSfwOverboard : {
      setting : 'sfwOverboard',
      type : 'string'
    },
    fieldMultiBoardThreadCount : {
      setting : 'multiboardThreadCount',
      type : 'string'
    },
    fieldSslPass : {
      setting : 'sslPass',
      type : 'string'
    },
    fieldGlobalLatestPosts : {
      setting : 'globalLatestPosts',
      type : 'string'
    },
    fieldOverBoardThreads : {
      setting : 'overBoardThreadCount',
      type : 'string'
    },
    fieldFePath : {
      setting : 'fePath',
      type : 'string'
    },
    fieldBypassPosts : {
      setting : 'bypassMaxPosts',
      type : 'string'
    },
    fieldOverboard : {
      setting : 'overboard',
      type : 'string'
    },
    fieldPageSize : {
      setting : 'pageSize',
      type : 'string'
    },
    fieldMaxTags : {
      setting : 'maxBoardTags',
      type : 'string'
    },
    fieldArchiveThreshold : {
      setting : 'archiveThreshold',
      type : 'string'
    },
    fieldLatestPostsCount : {
      setting : 'latestPostCount',
      type : 'string'
    },
    fieldAutoSageLimit : {
      setting : 'autoSageLimit',
      type : 'string'
    },
    fieldThreadLimit : {
      setting : 'maxThreadCount',
      type : 'string'
    },
    fieldSiteTitle : {
      setting : 'siteTitle',
      type : 'string'
    },
    fieldTempDir : {
      setting : 'tempDirectory',
      type : 'string'
    },
    fieldSenderEmail : {
      setting : 'emailSender',
      type : 'string'
    },
    fieldCaptchaExpiration : {
      setting : 'captchaExpiration',
      type : 'string'
    },
    fieldMaxRequestSize : {
      setting : 'maxRequestSizeMB',
      type : 'string'
    },
    fieldMaxFileSize : {
      setting : 'maxFileSizeMB',
      type : 'string'
    },
    fieldMaxFiles : {
      setting : 'maxFiles',
      type : 'string'
    },
    fieldBanMessage : {
      setting : 'defaultBanMessage',
      type : 'string'
    },
    fieldAnonymousName : {
      setting : 'defaultAnonymousName',
      type : 'string'
    },
    fieldTopBoardsCount : {
      setting : 'topBoardsCount',
      type : 'string'
    },
    fieldFlagNameLength : {
      setting : 'flagNameLength',
      type : 'string'
    },
    fieldStaticExpiration : {
      setting : 'staticExpiration',
      type : 'string'
    },
    fieldBoardsPerPage : {
      setting : 'boardsPerPage',
      type : 'string'
    },
    fieldTorSource : {
      setting : 'torSource',
      type : 'string'
    },
    fieldLanguagePack : {
      setting : 'languagePackPath',
      type : 'string'
    },
    fieldMaxRules : {
      setting : 'maxBoardRules',
      type : 'string'
    },
    fieldThumbSize : {
      setting : 'thumbSize',
      type : 'string'
    },
    fieldMaxFilters : {
      setting : 'maxFilters',
      type : 'string'
    },
    fieldMaxVolunteers : {
      setting : 'maxBoardVolunteers',
      type : 'string'
    },
    fieldGlobalLatestImages : {
      setting : 'globalLatestImages',
      type : 'string'
    },
    fieldMaxBannerSize : {
      setting : 'maxBannerSizeKB',
      type : 'string'
    },
    fieldMaxFlagSize : {
      setting : 'maxFlagSizeKB',
      type : 'string'
    },
    fieldThumbExtension : {
      setting : 'thumbExtension',
      type : 'string'
    },
    fieldFloodInterval : {
      setting : 'floodTimerSec',
      type : 'string'
    },
    checkboxVerbose : {
      setting : 'verbose',
      type : 'boolean'
    },
    checkboxFfmpegGifs : {
      setting : 'ffmpegGifs',
      type : 'boolean'
    },
    checkboxDisable304 : {
      setting : 'disable304',
      type : 'boolean'
    },
    checkboxAllowCustomJs : {
      setting : 'allowBoardCustomJs',
      type : 'boolean'
    },
    checkboxDisableSpamCheck : {
      setting : 'disableSpamCheck',
      type : 'boolean'
    },
    comboPruningMode : {
      setting : 'pruningMode',
      type : 'combo'
    },
    checkboxFrontPageStats : {
      setting : 'frontPageStats',
      type : 'boolean'
    },
    comboSsl : {
      setting : 'ssl',
      type : 'combo'
    },
    checkboxGlobalBoardModeration : {
      setting : 'allowGlobalBoardModeration',
      type : 'boolean'
    },
    checkboxVersatileBlockBypass : {
      setting : 'allowVersatileBlockBypass',
      type : 'boolean'
    },
    checkboxMediaThumb : {
      setting : 'mediaThumb',
      type : 'boolean'
    },
    checkboxGlobalCaptcha : {
      setting : 'forceCaptcha',
      type : 'boolean'
    },
    checkboxMaintenance : {
      setting : 'maintenance',
      type : 'boolean'
    },
    checkboxMultipleReports : {
      setting : 'multipleReports',
      type : 'boolean'
    },
    checkboxSFWLatestImages : {
      setting : 'onlySfwLatestImages',
      type : 'boolean'
    },
    checkboxDisableFloodCheck : {
      setting : 'disableFloodCheck',
      type : 'boolean'
    },
    checkboxDisableAccountCreation : {
      setting : 'disableAccountCreation',
      type : 'boolean'
    },
    fieldAcceptedMimes : {
      setting : 'acceptedMimes',
      type : 'string'
    },
    fieldAddons : {
      setting : 'addons',
      type : 'string'
    },
    comboBoardCreationRequirement : {
      setting : 'boardCreationRequirement',
      type : 'combo'
    },
    comboBypassMode : {
      setting : 'bypassMode',
      type : 'combo'
    },
    comboTorPostingLevel : {
      type : 'combo',
      setting : 'torPostingLevel',
    },
    comboMinClearIpRole : {
      setting : 'clearIpMinRole',
      type : 'combo'
    }
  };

};

globalSettings.save = function() {

  var parameters = {};

  for ( var key in globalSettings.siteSettingsRelation) {

    var item = globalSettings.siteSettingsRelation[key];

    switch (item.type) {
    case 'string':
      parameters[item.setting] = document.getElementById(key).value.trim();
      break;
    case 'boolean':
      if (document.getElementById(key).checked) {
        parameters[item.setting] = true;
      }
      break;
    case 'combo':
      var combo = document.getElementById(key);
      parameters[item.setting] = combo.options[combo.selectedIndex].value;
      break;

    }

  }

  api.formApiRequest('saveGlobalSettings', parameters,
      function requestComplete(status, data) {

        if (status === 'ok') {
          alert('New settings saved.');
        } else {
          alert(status + ': ' + JSON.stringify(data));
        }

      });

};

globalSettings.init();


code:
var hashBans = {};

hashBans.init = function() {

  var boardIdentifier = document.getElementById('boardIdentifier');

  if (boardIdentifier) {
    api.boardUri = boardIdentifier.value;
  }

  api.convertButton('createFormButton', hashBans.placeHashBan,
      'addHashBanField');

  var hashBansDiv = document.getElementById('hashBansDiv');

  for (var j = 0; j < hashBansDiv.childNodes.length; j++) {
    hashBans.processHashBanCell(hashBansDiv.childNodes[j]);
  }

  hashBans.div = hashBansDiv;

};

hashBans.processHashBanCell = function(cell) {

  var button = cell.getElementsByClassName('liftFormButton')[0];

  api.convertButton(button, function() {
    hashBans.liftHashBan(cell);
  });

};

hashBans.liftHashBan = function(cell) {

  api.formApiRequest('liftHashBan', {
    hashBanId : cell.getElementsByClassName('idIdentifier')[0].value
  }, function requestComplete(status, data) {

    if (status === 'ok') {
      cell.remove();
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }

  });

};

hashBans.showNewHashBan = function(typedHash, typedReason, id) {

  var form = document.createElement('form');
  form.method = 'post';
  form.enctype = 'multipart/form-data';
  form.action = '/liftHashBan.js';
  form.className = 'hashBanCell';

  form.appendChild(document.createElement('hr'));

  var hashPara = document.createElement('p');
  hashPara.innerHTML = 'MD5: ';
  form.appendChild(hashPara);

  var hashLabel = document.createElement('span');
  hashLabel.className = 'hashLabel';
  hashLabel.innerHTML = typedHash;
  hashPara.appendChild(hashLabel);

  var reasonPara = document.createElement('p');
  reasonPara.innerHTML = 'Reason: ';
  form.appendChild(reasonPara);

  var reasonLabel = document.createElement('span');
  reasonLabel.className = 'reasonLabel';
  reasonLabel.innerHTML = typedReason;
  reasonPara.appendChild(reasonLabel);

  var userPara = document.createElement('p');
  userPara.innerHTML = 'User: ';
  form.appendChild(userPara);

  var userLabel = document.createElement('span');
  userLabel.className = 'userLabel';
  userLabel.innerHTML = api.getCookies().login;
  userPara.appendChild(userLabel);

  var datePara = document.createElement('p');
  datePara.innerHTML = 'Date: ';
  form.appendChild(datePara);

  var dateLabel = document.createElement('span');
  dateLabel.className = 'dateLabel';
  dateLabel.innerHTML = api.formatDateToDisplay(new Date());
  datePara.appendChild(dateLabel);

  var identifier = document.createElement('input');
  identifier.type = 'hidden';
  identifier.value = id;
  identifier.name = 'hashBanId';
  identifier.className = 'idIdentifier';
  form.appendChild(identifier);

  var submit = document.createElement('button');
  submit.type = 'submit';
  submit.innerHTML = 'Lift hash ban';
  submit.className = 'liftFormButton';
  form.appendChild(submit);

  hashBans.div.appendChild(form);

  hashBans.processHashBanCell(form);

};

hashBans.placeHashBan = function() {

  var typedHash = document.getElementById('hashField').value.trim();
  var typedReason = document.getElementById('reasonField').value.trim();

  api.formApiRequest('placeHashBan', {
    hash : typedHash,
    reason : typedReason,
    boardUri : api.boardUri
  }, function requestComplete(status, data) {

    if (status === 'ok') {
      document.getElementById('hashField').value = '';
      document.getElementById('reasonField').value = '';
      hashBans.showNewHashBan(typedHash, typedReason, data);
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }

  });

};

hashBans.init();


code:
var hiding = {};

hiding.init = function() {

  hiding.updateHidingData();

  hiding.filtered = [];

  document.body.addEventListener('click', function clicked() {

    if (hiding.shownMenu) {
      hiding.shownMenu.remove();
      delete hiding.shownMenu;
    }

  }, true);

  var links = document.getElementsByClassName('linkSelf');

  for (var i = 0; i < links.length; i++) {
    hiding.setHideMenu(links[i]);
  }

  hiding.checkFilters();

};

hiding.updateHidingData = function() {

  var storedHidingData = localStorage.hidingData;

  if (!storedHidingData) {
    hiding.storedHidingData = {};
    return;
  }

  hiding.storedHidingData = JSON.parse(storedHidingData);

};

hiding.filterMatches = function(string, filter) {

  var toRet;

  if (!filter.regex) {
    toRet = string.indexOf(filter.filter) >= 0;
  } else {
    toRet = string.match(new RegExp(filter.filter)) ? true : false;
  }

  return toRet;

};

hiding.hideForFilter = function(linkSelf) {

  var toHide = linkSelf.parentNode.parentNode.parentNode;

  toHide.style.display = 'none';
  hiding.filtered.push(toHide);

  return true;

};

hiding.checkFilters = function() {

  for (var i = 0; i < hiding.filtered.length; i++) {
    hiding.filtered[i].style.display = 'block';
  }

  hiding.filtered = [];

  var links = document.getElementsByClassName('linkSelf');

  for (var i = 0; i < links.length; i++) {
    hiding.checkFilterHiding(links[i]);
  }

};

hiding.checkFilterHiding = function(linkSelf) {

  for (var i = 0; i < settingsMenu.loadedFilters.length; i++) {

    var filter = settingsMenu.loadedFilters[i];

    if (filter.type < 2) {
      var name = linkSelf.parentNode.getElementsByClassName('linkName')[0].innerHTML;

      if (name.indexOf('#') >= 0) {

        var trip = name.substring(name.lastIndexOf('#') + 1);

        name = name.substring(0, name.indexOf('#'));

      }

    }

    switch (filter.type) {

    case 0: {
      if (hiding.filterMatches(name, filter)) {
        return hiding.hideForFilter(linkSelf);
      }
      break;
    }

    case 1: {
      if (trip && hiding.filterMatches(trip, filter)) {
        return hiding.hideForFilter(linkSelf);
      }
      break;
    }

    case 2: {
      var subjectLabel = linkSelf.parentNode
          .getElementsByClassName('labelSubject')[0];

      if (subjectLabel && hiding.filterMatches(subjectLabel.innerHTML, filter)) {
        return hiding.hideForFilter(linkSelf);
      }
      break;
    }

    case 3: {
      if (hiding.filterMatches(linkSelf.parentNode.parentNode
          .getElementsByClassName('divMessage')[0].innerHTML, filter)) {
        return hiding.hideForFilter(linkSelf);
      }
      break;
    }

    case 4: {
      var labelId = linkSelf.parentNode.getElementsByClassName('labelId')[0];

      if (labelId) {
        if (hiding.buildPostFilterId(linkSelf, labelId.innerHTML) === filter.filter) {
          return hiding.hideForFilter(linkSelf);
        }
      }
      break;
    }

    }

  }

};

hiding.registerHiding = function(board, thread, post, unhiding) {

  var storedData = localStorage.hidingData;

  var hidingData = storedData ? JSON.parse(storedData) : {};

  var boardData = hidingData[board] || {
    threads : [],
    posts : []
  };

  var listToUse = post ? boardData.posts : boardData.threads;

  if (!unhiding) {
    if (listToUse.indexOf(post || thread) < 0) {
      listToUse.push(post || thread);
    }
  } else {
    listToUse.splice(listToUse.indexOf(post || thread), 1);
  }

  hidingData[board] = boardData;

  localStorage.hidingData = JSON.stringify(hidingData);

  hiding.storedHidingData = hidingData;

};

hiding.hidePost = function(linkSelf, board, thread, post) {

  hiding.toggleHidden(linkSelf.parentNode.parentNode, true);

  hiding.registerHiding(board, thread, post);

  var unhidePostButton = document.createElement('span');

  var unhideHTML = '[Unhide ' + (post ? 'post' : 'OP') + ' ' + board + '/'
      + post + ']';

  unhidePostButton.innerHTML = unhideHTML;
  unhidePostButton.className = 'unhideButton glowOnHover';

  linkSelf.parentNode.parentNode.parentNode.insertBefore(unhidePostButton,
      linkSelf.parentNode.parentNode);

  unhidePostButton.onclick = function() {

    hiding.registerHiding(board, thread, post, true);
    unhidePostButton.remove();

    hiding.toggleHidden(linkSelf.parentNode.parentNode, false);

  };

};

hiding.hideThread = function(linkSelf, board, thread) {

  hiding.toggleHidden(linkSelf.parentNode.parentNode.parentNode, true);
  var unhideThreadButton = document.createElement('span');

  unhideThreadButton.innerHTML = '[Unhide thread ' + board + '/' + thread + ']';
  unhideThreadButton.className = 'unhideButton glowOnHover';
  linkSelf.parentNode.parentNode.parentNode.parentNode.insertBefore(
      unhideThreadButton, linkSelf.parentNode.parentNode.parentNode);

  hiding.registerHiding(board, thread);

  unhideThreadButton.onclick = function() {
    hiding.toggleHidden(linkSelf.parentNode.parentNode.parentNode, false);
    unhideThreadButton.remove();
    hiding.registerHiding(board, thread, null, true);
  }

};

hiding.buildPostFilterId = function(linkSelf, id) {

  var checkbox = linkSelf.parentNode.getElementsByClassName('deletionCheckBox')[0];
  var postData = checkbox.name.split('-');
  var board = postData[0];
  var threadId = postData[1];

  return board + '-' + threadId + '-' + id;

};

hiding.buildHideMenu = function(board, thread, post, linkSelf, hideMenu) {

  var postHideButton;
  postHideButton = document.createElement('div');

  if (post) {

    postHideButton.innerHTML = 'Hide post';
    hideMenu.appendChild(postHideButton);

  } else {

    postHideButton.innerHTML = 'Hide OP';
    hideMenu.appendChild(postHideButton);

    hideMenu.appendChild(document.createElement('hr'));

    var threadHideButton = document.createElement('div');
    threadHideButton.innerHTML = 'Hide thread';
    hideMenu.appendChild(threadHideButton);

  }

  hideMenu.appendChild(document.createElement('hr'));

  var name = linkSelf.parentNode.getElementsByClassName('linkName')[0].innerHTML;

  var trip;

  if (name.indexOf('#') >= 0) {
    trip = name.substring(name.lastIndexOf('#') + 1);
    name = name.substring(0, name.indexOf('#'));
  }

  var filterNameButton = document.createElement('div');
  filterNameButton.innerHTML = 'Filter name';
  filterNameButton.onclick = function() {
    settingsMenu.createFilter(name, false, 0);
  };
  hideMenu.appendChild(filterNameButton);

  hideMenu.appendChild(document.createElement('hr'));

  if (trip) {

    var filterTripButton = document.createElement('div');
    filterTripButton.innerHTML = 'Filter tripcode';
    filterTripButton.onclick = function() {
      settingsMenu.createFilter(trip, false, 1);
    };
    hideMenu.appendChild(filterTripButton);

    hideMenu.appendChild(document.createElement('hr'));
  }

  var labelId = linkSelf.parentNode.getElementsByClassName('labelId')[0];

  if (labelId) {
    var filterIdButton = document.createElement('div');
    filterIdButton.innerHTML = 'Filter id';
    filterIdButton.onclick = function() {
      settingsMenu.createFilter(hiding.buildPostFilterId(linkSelf,
          labelId.innerHTML), false, 4);
    };
    hideMenu.appendChild(filterIdButton);

    hideMenu.appendChild(document.createElement('hr'));
  }

  postHideButton.onclick = function() {
    hiding.hidePost(linkSelf, board, thread, post || thread);
  };

  if (!post) {

    threadHideButton.onclick = function() {
      hiding.hideThread(linkSelf, board, thread);
    }

  }

};

hiding.toggleHidden = function(element, hide) {

  var className = element.className;

  if (hide) {
    element.className += ' hidden';
  } else {
    element.className = className.replace(' hidden', '');
  }

};

hiding.setHideMenu = function(linkSelf) {

  var hideButton = document.createElement('span');
  hideButton.className = 'hideButton glowOnHover coloredIcon';
  hideButton.title = "Hide";

  var parentNode = linkSelf.parentNode;

  var checkbox = parentNode.getElementsByClassName('deletionCheckBox')[0];

  if (!checkbox) {

    var href = linkSelf.href;

    var parts = href.split('/');

    var board = parts[3];

    var finalParts = parts[5].split('.');

    var thread = finalParts[0];

    var post = finalParts[1].split('#')[1];

    if (post === thread) {
      post = undefined;
    }

  } else {

    parts = checkbox.name.split('-');

    board = parts[0];
    thread = parts[1];
    post = parts[2];
  }

  parentNode.insertBefore(hideButton, checkbox ? checkbox.nextSibling
      : parentNode.childNodes[0]);

  hideButton.onclick = function() {

    var rect = hideButton.getBoundingClientRect();

    var hideMenu = document.createElement('div');
    hideMenu.className = 'floatingMenu hideMenu';

    hideButton.appendChild(hideMenu);

    hiding.shownMenu = hideMenu;

    hiding.buildHideMenu(board, thread, post, linkSelf, hideMenu);

  };

  var boardData = hiding.storedHidingData[board];

  if (!boardData) {
    return;
  }

  if (boardData.posts.indexOf(post || thread) > -1) {
    hiding.hidePost(linkSelf, board, thread, post || thread);
  }

  if (!post && boardData.threads.indexOf(thread) > -1) {
    hiding.hideThread(linkSelf, board, thread);
  }

  hiding.checkFilterHiding(linkSelf);

};

hiding.init();


code:
var languages = {};

languages.init = function() {

  api.convertButton('addFormButton', languages.addLanguage, 'newLanguageField');

  languages.div = document.getElementById('languagesDiv');

  var cells = document.getElementsByClassName('languageCell');

  for (var i = 0; i < cells.length; i++) {
    languages.setLanguageCell(cells[i]);
  }

};

languages.setLanguageCell = function(cell) {

  var button = cell.getElementsByClassName('deleteFormButton')[0];

  api.convertButton(button, function() {

    api.formApiRequest('deleteLanguage', {
      languageId : cell.getElementsByClassName('languageIdentifier')[0].value
    }, function requestComplete(status, data) {

      if (status === 'ok') {
        cell.remove();
      } else {
        alert(status + ': ' + JSON.stringify(data));
      }
    });

  });

};

languages.showNewLanguage = function(data, id) {

  var form = document.createElement('form');
  form.method = 'post';
  form.enctype = 'multipart/form-data';
  form.action = '/deleteLanguage.js';
  form.className = 'languageCell';
  form.innerHTML = 'Header values: ';

  var headersLabel = document.createElement('span');
  headersLabel.className = 'headerValuesLabel';
  headersLabel.innerHTML = data.headerValues.join(', ');
  form.appendChild(headersLabel);

  form.appendChild(document.createElement('br'));

  form.appendChild(document.createTextNode('Front-end: '));

  var feLabel = document.createElement('span');
  feLabel.innerHTML = data.frontEnd;
  feLabel.className = 'frontEndLabel';
  form.appendChild(feLabel);

  form.appendChild(document.createElement('br'));

  form.appendChild(document.createTextNode('Language pack: '));

  var packLabel = document.createElement('span');
  packLabel.innerHTML = data.languagePack;
  packLabel.className = 'languagePackLabel';
  form.appendChild(packLabel);

  form.appendChild(document.createElement('br'));

  var identifier = document.createElement('input');
  identifier.type = 'hidden';
  identifier.name = 'languageId';
  identifier.value = id;
  identifier.className = 'languageIdentifier';
  form.appendChild(identifier);

  var button = document.createElement('button');
  button.type = 'submit';
  button.innerHTML = 'Delete language';
  button.className = 'deleteFormButton';
  form.appendChild(button);

  form.appendChild(document.createElement('hr'));

  languages.div.appendChild(form);

  languages.setLanguageCell(form);

};

languages.addLanguage = function() {

  var typedHeaderValues = document.getElementById('fieldHeaderValues').value
      .trim();

  var parsedHeaderValues = typedHeaderValues.split(',').map(function(value) {
    return value.trim()
  });

  var typedFrontEnd = document.getElementById('fieldFrontEnd').value.trim();

  var typedLanguagePack = document.getElementById('fieldLanguagePack').value
      .trim();

  var payload = {
    frontEnd : typedFrontEnd,
    languagePack : typedLanguagePack,
    headerValues : parsedHeaderValues
  };

  api.formApiRequest('addLanguage', {
    frontEnd : typedFrontEnd,
    languagePack : typedLanguagePack,
    headerValues : parsedHeaderValues
  }, function requestComplete(status, data) {

    if (status === 'ok') {

      document.getElementById('fieldFrontEnd').value = '';
      document.getElementById('fieldLanguagePack').value = '';
      document.getElementById('fieldHeaderValues').value = '';

      languages.showNewLanguage(payload, data);
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

languages.init();


code:
var latestPostings = {};

latestPostings.init = function() {

  latestPostings.postsDiv = document.getElementById('divPostings');

  var moreButton = document.getElementById('buttonLoadMore');
  moreButton.className = '';
  moreButton.onclick = latestPostings.loadMore;

  var parts = document.getElementById('linkNext').href.split('?')[1].split('&');

  var args = {};

  for (var i = 0; i < parts.length; i++) {
    var subParts = parts[i].split('=');

    args[subParts[0]] = subParts[1];
  }

  latestPostings.latestCheck = new Date(+args.date);

};

latestPostings.loadMore = function(event) {

  event.preventDefault();

  api.formApiRequest('latestPostings', {}, function gotData(status, data) {

    if (status !== 'ok') {
      return;
    }

    if (data.length) {
      latestPostings.latestCheck = new Date(data[0].creation);
    }

    for (var i = data.length - 1; i >= 0; i--) {

      var post = data[i];

      var cell = posting.addPost(post, post.boardUri, post.threadId);

      cell.getElementsByClassName('deletionCheckBox')[0].remove();

      latestPostings.postsDiv.insertBefore(cell,
          latestPostings.postsDiv.childNodes[0]);

    }

  }, true, {
    date : latestPostings.latestCheck.getTime(),
    boards : document.getElementById('fieldBoards').value
  });

};

latestPostings.init();


code:
var loginObj = {};
// I wish I could go back in time and kill whoever implemented the exposed
// element bullshit on IE before he was born

loginObj.init = function() {

  if (document.getElementById('divCreation')) {
    api.convertButton('registerFormButton', loginObj.registerAccount,
        'registerField');
  }

  api.convertButton('recoverFormButton', loginObj.recoverAccount,
      'recoverField');
  api.convertButton('loginFormButton', loginObj.loginUser, 'loginField');

};

loginObj.recoverAccount = function() {

  var typedLogin = document.getElementById('recoverFieldLogin').value.trim();
  var typedCaptcha = document.getElementById('fieldCaptchaRecover').value
      .trim();

  if (typedCaptcha.length !== 6 && typedCaptcha.length !== 24) {
    alert('Captchas are exactly 6 (24 if no cookies) characters long.');

  } else if (/\W/.test(typedCaptcha)) {
    alert('Invalid captcha.');

  } else if (typedLogin.length) {

    api.formApiRequest('requestAccountRecovery', {
      login : typedLogin,
      captcha : typedCaptcha
    }, function requestComplete(status, data) {

      if (status === 'ok') {

        alert('Password request created. Check your e-mail.');

      } else {
        alert(status + ': ' + JSON.stringify(data));
      }
    });

  }

};

loginObj.loginUser = function() {

  var typedLogin = document.getElementById('loginFieldLogin').value.trim();
  var typedPassword = document.getElementById('loginFieldPassword').value;

  if (!typedLogin.length || !typedPassword.length) {
    alert('Both login and password are mandatory.');
  } else {

    var redirect = api.getCookies().loginredirect || '/account.js';

    api.formApiRequest('login', {
      login : typedLogin,
      password : typedPassword,
      remember : document.getElementById('checkboxRemember').checked
    }, function requestComplete(status, data) {

      if (status === 'ok') {
        window.location.href = redirect;
      } else {
        alert(status + ': ' + JSON.stringify(data));
      }
    });
  }

};

loginObj.registerAccount = function() {

  var typedLogin = document.getElementById('registerFieldLogin').value.trim();
  var typedEmail = document.getElementById('registerFieldEmail').value.trim();
  var typedPassword = document.getElementById('registerFieldPassword').value;
  var typedCaptcha = document.getElementById('fieldCaptcha').value.trim();

  if (!typedLogin.length || !typedPassword.length) {
    alert('Both login and password are mandatory.');
  } else if (typedLogin.length > 16) {
    alert('Login too long, keep it under 16 characters.');
  } else if (typedEmail.length > 64) {
    alert('E-mail too long, keep it under 64 characters.');
  } else if (typedCaptcha.length !== 6 && typedCaptcha.length !== 24) {
    alert('Captchas are exactly 6 (24 if no cookies) characters long.');
    return;
  } else if (/\W/.test(typedCaptcha)) {
    alert('Invalid captcha.');
    return;
  } else if (/\W/.test(typedLogin)) {
    alert('Invalid login.');
  } else {

    api.formApiRequest('registerAccount', {
      login : typedLogin,
      captcha : typedCaptcha,
      password : typedPassword,
      email : typedEmail
    }, function requestComplete(status, data) {

      if (status === 'ok') {
        window.location.pathname = '/account.js';
      } else {
        alert(status + ': ' + JSON.stringify(data));
      }
    });

  }

};

loginObj.init();


code:
var mediaHiding = {};

mediaHiding.init = function() {

  mediaHiding.hiddenMediaRelation = {};

  var shownFiles = document.getElementsByClassName('uploadCell');

  for (var i = 0; i < shownFiles.length; i++) {
    mediaHiding.processFileForHiding(shownFiles[i]);
  }

  var hiddenMedia = mediaHiding.getHiddenMedia();

  for (i = 0; i < hiddenMedia.length; i++) {
    mediaHiding.updateHiddenFiles(hiddenMedia[i], true);
  }

};

mediaHiding.getHiddenMedia = function() {

  var hiddenMedia = localStorage.hiddenMedia;

  if (hiddenMedia) {
    hiddenMedia = JSON.parse(hiddenMedia);
  } else {
    hiddenMedia = [];
  }

  return hiddenMedia;

};

mediaHiding.updateHiddenFiles = function(file, hiding) {

  var mediaObject = mediaHiding.hiddenMediaRelation[file] || [];

  for (var i = 0; i < mediaObject.length; i++) {

    var element = mediaObject[i];

    element.button.classList.toggle('hiddenFile', hiding);

    if (element.element.style.display === 'none' && hiding) {

      var hideLinkList = element.element.parentNode
          .getElementsByClassName('hideLink');

      if (hideLinkList.length) {
        hideLinkList[0].onclick();
      }
    }

    element.element.style.display = hiding ? 'none' : 'inline';
  }

};

mediaHiding.processFileForHiding = function(file) {

  var nameLink = file.getElementsByClassName('nameLink')[0];

  var hidingButton = document.createElement('a');
  hidingButton.className = 'hideFileButton glowOnHover coloredIcon';

  var fileName = nameLink.href.split('/');
  fileName = fileName[fileName.length - 1];

  var mediaObject = mediaHiding.hiddenMediaRelation[fileName] || [];

  mediaObject.push({
    button : hidingButton,
    element : file.getElementsByClassName('imgLink')[0]
  });

  mediaHiding.hiddenMediaRelation[fileName] = mediaObject;

  hidingButton.onclick = function() {

    var hiddenMedia = mediaHiding.getHiddenMedia();

    var alreadyHidden = hiddenMedia.indexOf(fileName) > -1;

    if (alreadyHidden) {
      hiddenMedia.splice(hiddenMedia.indexOf(fileName), 1);
    } else {
      hiddenMedia.push(fileName);
    }

    localStorage.hiddenMedia = JSON.stringify(hiddenMedia);

    mediaHiding.updateHiddenFiles(fileName, !alreadyHidden);

  };

  nameLink.parentNode.insertBefore(hidingButton, nameLink.nextSibling);

};

mediaHiding.init();


code:
var mediaManagement = {};

mediaManagement.init = function() {

  api.convertButton('deleteFormButton', mediaManagement.deleteMedia);

  document.getElementById('selectAllButton').className = '';

};

mediaManagement.selectAll = function() {

  var checkBoxes = document.getElementsByClassName('identifierCheckbox');

  for (var i = 0; i < checkBoxes.length; i++) {
    checkBoxes[i].checked = true;
  }

}

mediaManagement.deleteMedia = function() {

  var checkBoxes = document.getElementsByClassName('identifierCheckbox');

  var identifiers = {
    identifiers : identifiers
  };

  for (var i = 0; i < checkBoxes.length; i++) {
    if (checkBoxes[i].checked) {
      identifiers[checkBoxes[i].name] = true;
    }
  }

  api.formApiRequest('deleteMedia', identifiers, function deletedMedia(status,
      data) {

    if (status === 'ok') {

      for (var i = checkBoxes.length - 1; i > -1; i--) {
        if (checkBoxes[i].checked) {
          checkBoxes[i].parentNode.parentNode.remove();
        }
      }

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }

  });

};

mediaManagement.init();


code:
var postCommon = {};

postCommon.init = function() {

  if (!document.getElementById('fieldPostingPassword')) {
    return;
  }

  var charLimitLabel = document.getElementById('labelMessageLength');

  document.getElementById('fieldMessage').addEventListener('input',
      postCommon.updateCurrentChar);

  postCommon.currentCharLabel = document.createElement('span');

  charLimitLabel.parentNode.insertBefore(postCommon.currentCharLabel,
      charLimitLabel);

  charLimitLabel.parentNode.insertBefore(document.createTextNode('/'),
      charLimitLabel);

  postCommon.updateCurrentChar();

  postCommon.selectedCell = '
✖
'
      + '
'
      + '<input type="checkbox" class="spoilerCheckBox">Spoiler
';

  postCommon.selectedFiles = [];

  if (document.getElementById('divUpload')) {
    postCommon.setDragAndDrop();
  }

  var savedPassword = localStorage.deletionPassword;

  if (savedPassword) {

    document.getElementById('fieldPostingPassword').value = savedPassword;

    if (document.getElementById('deletionFieldPassword')) {
      document.getElementById('deletionFieldPassword').value = savedPassword;
    }

  }

  var nameField = document.getElementById('fieldName');

  if (nameField) {
    nameField.value = localStorage.name || '';
  }

  document.getElementById('alwaysUseBypassDiv').classList.toggle('hidden');

  var bypassCheckBox = document.getElementById('alwaysUseBypassCheckBox');

  if (localStorage.ensureBypass && JSON.parse(localStorage.ensureBypass)) {
    bypassCheckBox.checked = true;
  }

  bypassCheckBox.addEventListener('change', function() {
    localStorage.setItem('ensureBypass', bypassCheckBox.checked);
  });

  var flagCombo = document.getElementById('flagCombobox');

  if (flagCombo && localStorage.savedFlags) {

    var flagInfo = JSON.parse(localStorage.savedFlags);

    if (flagInfo[api.boardUri]) {

      for (var i = 0; i < flagCombo.options.length; i++) {

        if (flagCombo.options[i].value === flagInfo[api.boardUri]) {
          flagCombo.selectedIndex = i;

          postCommon.showFlagPreview(flagCombo);

          break;
        }

      }

    }

  }

  if (flagCombo) {
    postCommon.setFlagPreviews(flagCombo);
  }

  var formMore = document.getElementById('formMore');
  formMore.classList.toggle('hidden');

  var toggled = false;

  var extra = document.getElementById('extra');
  extra.classList.toggle('hidden');

  formMore.children[0].onclick = function() {

    extra.classList.toggle('hidden');
    formMore.children[0].innerHTML = toggled ? 'More' : 'Less';

    toggled = !toggled;

    localStorage.setItem('showExtra', toggled);

  };

  if (localStorage.showExtra && JSON.parse(localStorage.showExtra)) {
    formMore.children[0].onclick();
  }

};

postCommon.updateCurrentChar = function() {
  postCommon.currentCharLabel.innerHTML = document
      .getElementById('fieldMessage').value.trim().length;
};

postCommon.showFlagPreview = function(combo) {

  var index = combo.selectedIndex;

  var src;

  if (!index) {
    src = '';
  } else {
    src = '/' + api.boardUri + '/flags/' + combo.options[index].value;
  }

  var previews = document.getElementsByClassName('flagPreview');

  for (var i = 0; i < previews.length; i++) {
    previews[i].src = src;
  }

};

postCommon.setFlagPreviews = function(combo) {

  combo.addEventListener('change', function() {
    postCommon.showFlagPreview(combo);
  });

};

postCommon.savedSelectedFlag = function(selectedFlag) {

  var savedFlagData = localStorage.savedFlags ? JSON
      .parse(localStorage.savedFlags) : {};

  savedFlagData[api.boardUri] = selectedFlag;

  localStorage.setItem('savedFlags', JSON.stringify(savedFlagData));

};

postCommon.addDndCell = function(cell, removeButton) {

  if (postCommon.selectedDivQr) {
    var clonedCell = cell.cloneNode(true);
    clonedCell.getElementsByClassName('removeButton')[0].onclick = removeButton.onclick;
    postCommon.selectedDivQr.appendChild(clonedCell);

    var sourceSpoiler = cell.getElementsByClassName('spoilerCheckBox')[0];
    var destinationSpoiler = clonedCell
        .getElementsByClassName('spoilerCheckBox')[0];

    sourceSpoiler.addEventListener('change', function() {
      if (destinationSpoiler) {
        destinationSpoiler.checked = sourceSpoiler.checked;
      }
    });

    destinationSpoiler.addEventListener('change', function() {
      sourceSpoiler.checked = destinationSpoiler.checked;
    });

  }

  postCommon.selectedDiv.appendChild(cell);

};

postCommon.addSelectedFile = function(file) {

  var cell = document.createElement('div');
  cell.className = 'selectedCell';

  cell.innerHTML = postCommon.selectedCell;

  var nameLabel = cell.getElementsByClassName('nameLabel')[0];
  nameLabel.innerHTML = file.name;

  var removeButton = cell.getElementsByClassName('removeButton')[0];

  removeButton.onclick = function() {
    var index = postCommon.selectedFiles.indexOf(file);

    if (postCommon.selectedDivQr) {

      for (var i = 0; i < postCommon.selectedDiv.childNodes.length; i++) {
        if (postCommon.selectedDiv.childNodes[i] === cell) {
          postCommon.selectedDivQr
              .removeChild(postCommon.selectedDivQr.childNodes[i]);
        }
      }

    }

    postCommon.selectedDiv.removeChild(cell);

    postCommon.selectedFiles.splice(postCommon.selectedFiles.indexOf(file), 1);
  };

  postCommon.selectedFiles.push(file);

  if (!file.type.indexOf('image/')) {

    var fileReader = new FileReader();

    fileReader.onloadend = function() {

      var dndThumb = document.createElement('img');
      dndThumb.src = fileReader.result;
      dndThumb.className = 'dragAndDropThumb';
      cell.appendChild(dndThumb);

      postCommon.addDndCell(cell, removeButton);

    };

    fileReader.readAsDataURL(file);

  } else {
    postCommon.addDndCell(cell, removeButton);
  }

};

postCommon.clearSelectedFiles = function() {

  if (!document.getElementById('divUpload')) {
    return;
  }

  postCommon.selectedFiles = [];

  while (postCommon.selectedDiv.firstChild) {
    postCommon.selectedDiv.removeChild(postCommon.selectedDiv.firstChild);
  }

  if (postCommon.selectedDivQr) {
    while (postCommon.selectedDivQr.firstChild) {
      postCommon.selectedDivQr.removeChild(postCommon.selectedDivQr.firstChild);
    }
  }

};

postCommon.setDragAndDrop = function(qr) {

  var fileInput = document.getElementById('inputFiles');

  if (!qr) {
    fileInput.style.display = 'none';
    document.getElementById('dragAndDropDiv').style.display = 'block';

    fileInput.onchange = function() {

      for (var i = 0; i < fileInput.files.length; i++) {
        postCommon.addSelectedFile(fileInput.files[i]);
      }

      fileInput.type = "text";
      fileInput.type = "file";
    };
  }

  var drop = document.getElementById(qr ? 'dropzoneQr' : 'dropzone');
  drop.onclick = function() {
    fileInput.click();
  };

  if (!qr) {
    postCommon.selectedDiv = document.getElementById('selectedDiv');
  } else {
    postCommon.selectedDivQr = document.getElementById('selectedDivQr');
  }

  drop.addEventListener('dragover', function handleDragOver(event) {

    event.stopPropagation();
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';

  }, false);

  drop.addEventListener('drop', function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    for (var i = 0; i < evt.dataTransfer.files.length; i++) {
      postCommon.addSelectedFile(evt.dataTransfer.files[i])
    }

  }, false);

};

postCommon.newCheckExistance = function(file, callback) {

  var reader = new FileReader();

  reader.onloadend = function() {

    var mime = file.type;
    var md5 = SparkMD5.ArrayBuffer.hash(reader.result);

    var identifier = md5 + '-' + mime.replace('/', '');

    api.formApiRequest('checkFileIdentifier', {}, function requested(status,
        data) {

      if (status !== 'ok') {
        console.log(data);
        callback();
      } else {
        callback(md5, mime, data);
      }

    }, false, {
      identifier : identifier
    });

  };

  reader.readAsArrayBuffer(file);

};

postCommon.newGetFilesToUpload = function(callback, index, files) {

  index = index || 0;
  files = files || [];

  if (!document.getElementById('divUpload')
      || index >= postCommon.selectedFiles.length) {
    callback(files);
    return;
  }

  var spoiled = postCommon.selectedDiv
      .getElementsByClassName('spoilerCheckBox')[index].checked;

  var file = postCommon.selectedFiles[index];

  postCommon.newCheckExistance(file, function checked(md5, mime, found) {

    var toPush = {
      name : postCommon.selectedFiles[index].name,
      spoiler : spoiled,
      md5 : md5,
      mime : mime
    };

    if (!found) {
      toPush.content = file;
    }

    files.push(toPush);

    postCommon.newGetFilesToUpload(callback, ++index, files);

  });

};

postCommon.displayBlockBypassPrompt = function(callback) {

  var outerPanel = captchaModal
      .getCaptchaModal('You need a block bypass to post');

  var okButton = outerPanel.getElementsByClassName('modalOkButton')[0];

  okButton.onclick = function() {

    var typedCaptcha = outerPanel.getElementsByClassName('modalAnswer')[0].value
        .trim();

    if (typedCaptcha.length !== 6 && typedCaptcha.length !== 24) {
      alert('Captchas are exactly 6 (24 if no cookies) characters long.');
      return;
    } else if (/\W/.test(typedCaptcha)) {
      alert('Invalid captcha.');
      return;
    }

    api.formApiRequest('renewBypass', {
      captcha : typedCaptcha
    }, function requestComplete(status, data) {

      if (status === 'ok') {

        if (callback) {
          callback();
        }

        outerPanel.remove();

      } else {
        alert(status + ': ' + JSON.stringify(data));
      }
    });

  };

};

postCommon.storeUsedPostingPassword = function(boardUri, threadId, postId) {

  var storedData = JSON.parse(localStorage.postingPasswords || '{}');

  var key = boardUri + '/' + threadId

  if (postId) {
    key += '/' + postId;
  }

  storedData[key] = localStorage.deletionPassword;

  localStorage.setItem('postingPasswords', JSON.stringify(storedData));

};

postCommon.init();


code:
var posting = {};

posting.init = function() {

  posting.idsRelation = {};
  posting.highLightedIds = [];

  posting.postCellTemplate = '

'
      + '<input type="checkbox" class="deletionCheckBox"> '
      + '   '
      + '   Id: No.  [Edit] '
      + '[History] [File history]'
      + '
'
      + '
ASN:
'
      + '
'
      + ' Broad'
      + 'range(1/2 octets):
'
      + 'Narrow range(3/4 octets):
'
      + ' Ip: '
      + '
'
      + '

'
      + '

';

  posting.uploadCell = '
'
      + ' ( '
      + ' )

MD5:
';

  posting.sizeOrders = [ 'B', 'KB', 'MB', 'GB', 'TB' ];

  posting.guiEditInfo = 'Edited last time by {$login} on {$date}.';

  posting.reverseHTMLReplaceTable = {};

  for ( var key in api.htmlReplaceTable) {
    posting.reverseHTMLReplaceTable[api.htmlReplaceTable[key]] = key;
  }

  if (document.getElementById('deleteFormButton')) {

    api.convertButton('reportFormButton', posting.reportPosts, 'reportField');
    api.convertButton('deleteFormButton', posting.deletePosts, 'deletionField');

  }

  if (localStorage.localTime && JSON.parse(localStorage.localTime)) {

    var times = document.getElementsByClassName('labelCreated');

    for (var i = 0; i < times.length; i++) {
      posting.setLocalTime(times[i]);
    }

    posting.localTimes = true;
  }

  if (localStorage.relativeTime && JSON.parse(localStorage.relativeTime)) {
    posting.updateAllRelativeTimes();
    setInterval(posting.updateAllRelativeTimes, 1000 * 60 * 5);
  }

  if (typeof (thread) !== 'undefined') {
    return;
  }

  var ids = document.getElementsByClassName('labelId');

  for (i = 0; i < ids.length; i++) {
    posting.processIdLabel(ids[i]);
  }

};

posting.setLocalTime = function(time) {

  time.innerHTML = api.formatDateToDisplay(new Date(time.innerHTML + ' UTC'),
      true);

};

posting.applyBans = function(captcha) {

  var typedReason = document.getElementById('reportFieldReason').value.trim();
  var typedDuration = document.getElementById('fieldDuration').value.trim();
  var typedMessage = document.getElementById('fieldbanMessage').value.trim();
  var banType = document.getElementById('comboBoxBanTypes').selectedIndex;

  var params = {
    action : 'ban',
    reason : typedReason,
    captcha : captcha,
    banType : banType,
    duration : typedDuration,
    banMessage : typedMessage,
    global : document.getElementById('checkboxGlobal').checked
  };

  posting.newGetSelectedContent(params);

  api.formApiRequest('contentActions', params, function requestComplete(status,
      data) {

    if (status === 'ok') {
      alert('Bans applied');
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }

  });
};

posting.banPosts = function() {

  if (!document.getElementsByClassName('panelRange').length) {
    posting.applyBans();
    return;
  }

  var typedCaptcha = document.getElementById('fieldCaptchaReport').value.trim();

  if (typedCaptcha && /\W/.test(typedCaptcha)) {
    alert('Invalid captcha.');
    return;
  }

  if (typedCaptcha.length == 24 || !typedCaptcha) {
    thread.applyBans(typedCaptcha);
  } else {
    var parsedCookies = api.getCookies();

    api.formaApiRequest('solveCaptcha', {
      captchaId : parsedCookies.captchaid,
      answer : typedCaptcha
    }, function solvedCaptcha(status, data) {

      if (status !== 'ok') {
        alert(status);
        return;
      }

      posting.applyBans(parsedCookies.captchaid);
    });
  }

};

posting.deleteFromIpOnBoard = function() {

  var checkBoxes = document.getElementsByClassName('deletionCheckBox');

  for (var i = 0; i < checkBoxes.length; i++) {
    var checkBox = checkBoxes[i];

    if (checkBox.checked) {
      var splitName = checkBox.name.split('-')[0];
      break;
    }

  }

  if (!splitName) {
    return;
  }

  var redirect = '/' + splitName + '/';

  var confirmationBox = document
      .getElementById('ipDeletionConfirmationCheckbox');

  var param = {
    action : 'ip-deletion',
    confirmation : confirmationBox.checked
  };

  posting.newGetSelectedContent(param);

  api.formApiRequest('contentActions', param, function requestComplete(status,
      data) {

    if (status === 'ok') {
      window.location.pathname = redirect;
    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

posting.processIdLabel = function(label) {

  var id = label.innerHTML;

  var array = posting.idsRelation[id] || [];
  posting.idsRelation[id] = array;

  var cell = label.parentNode.parentNode.parentNode;

  array.push(cell);

  label.onmouseover = function() {
    label.innerHTML = id + ' (' + array.length + ')';
  }

  label.onmouseout = function() {
    label.innerHTML = id;
  }

  label.onclick = function() {

    var index = posting.highLightedIds.indexOf(id);

    if (index > -1) {
      posting.highLightedIds.splice(index, 1);
    } else {
      posting.highLightedIds.push(id);
    }

    for (var i = 0; i < array.length; i++) {
      var cellToChange = array[i];

      if (cellToChange.className === 'innerOP') {
        continue;
      }

      cellToChange.className = index > -1 ? 'innerPost' : 'markedPost';
    }

  };

};

posting.updateAllRelativeTimes = function() {

  var times = document.getElementsByClassName('labelCreated');

  for (var i = 0; i < times.length; i++) {
    posting.addRelativeTime(times[i]);
  }

};

posting.addRelativeTime = function(time) {

  var timeObject = new Date(time.innerHTML + (posting.localTimes ? '' : ' UTC'));

  if (time.nextSibling.nextSibling.className !== 'relativeTime') {

    var newRelativeLabel = document.createElement('span');

    newRelativeLabel.className = 'relativeTime';

    time.parentNode.insertBefore(newRelativeLabel, time.nextSibling);
    time.parentNode
        .insertBefore(document.createTextNode(' '), time.nextSibling);

  }

  var now = new Date();

  var content;

  var delta = now - timeObject;

  var second = 1000;
  var minute = second * 60;
  var hour = minute * 60;
  var day = hour * 24;
  var month = day * 30.5;
  var year = day * 365.25;

  if (delta > 2 * year) {
    content = Math.ceil(delta / year) + ' years ago';
  } else if (delta > 2 * month) {
    content = Math.ceil(delta / month) + ' months ago';
  } else if (delta > 2 * day) {
    content = Math.ceil(delta / day) + ' days ago';
  } else if (delta > 2 * hour) {
    content = Math.ceil(delta / hour) + ' hours ago';
  } else if (delta > 2 * minute) {
    content = Math.ceil(delta / minute) + ' minutes ago';
  } else {
    content = 'Just now'
  }

  time.nextSibling.nextSibling.innerHTML = '(' + content + ')';

};

posting.spoilFiles = function() {

  var posts = {
    action : 'spoil'
  };

  posting.newGetSelectedContent(posts);

  api.formApiRequest('contentActions', posts, function requestComplete(status,
      data) {

    if (status === 'ok') {

      alert('Files spoiled');

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

posting.newGetSelectedContent = function(object) {

  var checkBoxes = document.getElementsByClassName('deletionCheckBox');

  for (var i = 0; i < checkBoxes.length; i++) {
    var checkBox = checkBoxes[i];

    if (checkBox.checked) {
      object[checkBox.name] = true;
    }
  }

};

posting.reportPosts = function() {

  var typedReason = document.getElementById('reportFieldReason').value.trim();
  var typedCaptcha = document.getElementById('fieldCaptchaReport').value.trim();

  if (typedCaptcha.length !== 6 && typedCaptcha.length !== 24) {
    alert('Captchas are exactly 6 (24 if no cookies) characters long.');
    return;
  } else if (/\W/.test(typedCaptcha)) {
    alert('Invalid captcha.');
    return;
  }

  var params = {
    action : 'report',
    reason : typedReason,
    captcha : typedCaptcha,
    global : document.getElementById('checkboxGlobal').checked,
  };

  posting.newGetSelectedContent(params);

  api.formApiRequest('contentActions', params, function reported(status, data) {

    if (status === 'ok') {

      alert('Content reported');

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }

  });

};

posting.deletePosts = function() {

  var typedPassword = document.getElementById('deletionFieldPassword').value
      .trim();

  var params = {
    password : typedPassword,
    deleteMedia : document.getElementById('checkboxMediaDeletion').checked,
    deleteUploads : document.getElementById('checkboxOnlyFiles').checked,
    action : 'delete'
  };

  posting.newGetSelectedContent(params);

  api.formApiRequest('contentActions', params, function requestComplete(status,
      data) {

    if (status === 'ok') {

      alert(data.removedThreads + ' threads and ' + data.removedPosts
          + ' posts were successfully deleted.');

      if (typeof latestPostings !== 'undefined') {

        var checkBoxes = document.getElementsByClassName('deletionCheckBox');

        for (var i = checkBoxes.length - 1; i >= 0; i--) {
          var checkBox = checkBoxes[i];

          if (checkBox.checked) {
            checkBox.parentNode.parentNode.parentNode.remove();
          }

        }

      } else if (!api.isBoard && !data.removedThreads && data.removedPosts) {
        thread.refreshPosts(true, true);
      } else if (data.removedThreads || data.removedPosts) {
        window.location.pathname = '/';
      }

    } else {
      alert(status + ': ' + JSON.stringify(data));
    }
  });

};

posting.formatFileSize = function(size) {

  var orderIndex = 0;

  while (orderIndex < posting.sizeOrders.length - 1 && size > 1024) {

    orderIndex++;
    size /= 1024;

  }

  return size.toFixed(2) + ' ' + posting.sizeOrders[orderIndex];

};

posting.setLastEditedLabel = function(post, cell) {

  var editedLabel = cell.getElementsByClassName('labelLastEdit')[0];

  if (post.lastEditTime) {

    var formatedDate = api.formatDateToDisplay(new Date(post.lastEditTime));

    editedLabel.innerHTML = posting.guiEditInfo
        .replace('{$date}', formatedDate).replace('{$login}',
            post.lastEditLogin);

  } else {
    editedLabel.remove();
  }

};

posting.setUploadLinks = function(cell, file, noExtras) {

  var thumbLink = cell.getElementsByClassName('imgLink')[0];
  thumbLink.href = file.path;

  thumbLink.setAttribute('data-filemime', file.mime);

  if (file.mime.indexOf('image/') > -1 && !noExtras
      && (typeof gallery !== 'undefined') && !api.mobile) {
    gallery.addGalleryFile(file.path);
  }

  var img = document.createElement('img');
  img.src = file.thumb;

  thumbLink.appendChild(img);

  var nameLink = cell.getElementsByClassName('nameLink')[0];
  nameLink.href = file.path;

  var originalLink = cell.getElementsByClassName('originalNameLink')[0];
  originalLink.innerHTML = file.originalName;
  originalLink.href = file.path;
  originalLink.setAttribute('download', file.originalName);

};

posting.getUploadCellBase = function() {

  var cell = document.createElement('figure');
  cell.innerHTML = posting.uploadCell;
  cell.className = 'uploadCell';

  return cell;

}

posting.setUploadCell = function(node, files, noExtras) {

  if (!files) {
    return;
  }

  for (var i = 0; i < files.length; i++) {
    var file = files[i];

    var cell = posting.getUploadCellBase();

    posting.setUploadLinks(cell, file, noExtras);

    var sizeString = posting.formatFileSize(file.size);
    cell.getElementsByClassName('sizeLabel')[0].innerHTML = sizeString;

    var dimensionLabel = cell.getElementsByClassName('dimensionLabel')[0];

    if (file.width) {
      dimensionLabel.innerHTML = file.width + 'x' + file.height;
    } else {
      dimensionLabel.remove();
    }

    if (file.md5) {
      cell.getElementsByClassName('labelHash')[0].innerHTML = file.md5;
    } else {
      cell.getElementsByClassName('divHash')[0].remove();
    }

    node.appendChild(cell);
  }

};

posting.setPostHideableElements = function(postCell, post, noExtras) {

  var subjectLabel = postCell.getElementsByClassName('labelSubject')[0];

  if (post.subject) {
    subjectLabel.innerHTML = post.subject;
  } else {
    subjectLabel.remove();
  }

  if (post.id) {
    var labelId = postCell.getElementsByClassName('labelId')[0];
    labelId.setAttribute('style', 'background-color: #' + post.id);
    labelId.innerHTML = post.id;

    if (!noExtras) {
      posting.processIdLabel(labelId);
    }

  } else {
    var spanId = postCell.getElementsByClassName('spanId')[0];
    spanId.remove();
  }

  var banMessageLabel = postCell.getElementsByClassName('divBanMessage')[0];

  if (!post.banMessage) {
    banMessageLabel.parentNode.removeChild(banMessageLabel);
  } else {
    banMessageLabel.innerHTML = post.banMessage;
  }

  posting.setLastEditedLabel(post, postCell);

  var imgFlag = postCell.getElementsByClassName('imgFlag')[0];

  if (post.flag) {
    imgFlag.src = post.flag;
    imgFlag.title = post.flagName.replace(/&(l|g)t;/g, function replace(match) {
      return posting.reverseHTMLReplaceTable[match];
    });

    if (post.flagCode) {
      imgFlag.className += ' flag' + post.flagCode;
    }
  } else {
    imgFlag.remove();
  }

  if (!post.asn) {
    postCell.getElementsByClassName('panelASN')[0].remove();
  } else {
    postCell.getElementsByClassName('labelASN')[0].innerHTML = post.asn;
  }

  if (!post.ip) {
    postCell.getElementsByClassName('panelIp')[0].remove();
  } else {

    postCell.getElementsByClassName('labelIp')[0].innerHTML = post.ip;

    if (!post.broadRange) {
      postCell.getElementsByClassName('panelRange')[0].remove();
    } else {

      postCell.getElementsByClassName('labelBroadRange')[0].innerHTML = post.broadRange;
      postCell.getElementsByClassName('labelNarrowRange')[0].innerHTML = post.narrowRange;

    }

  }

};

posting.setPostLinks = function(postCell, post, boardUri, link, threadId,
    linkQuote, deletionCheckbox) {

  var postingId = post.postId || threadId;

  var linkStart = '#';

  linkQuote.href = linkStart;
  link.href = linkStart;

  link.href += postingId;
  linkQuote.href += 'q' + postingId;

  var linkEdit = postCell.getElementsByClassName('linkEdit')[0];
  var linkHistory = postCell.getElementsByClassName('linkHistory')[0];
  var linkFileHistory = postCell.getElementsByClassName('linkFileHistory')[0];

  var complement = (post.postId ? 'postId' : 'threadId') + '=' + postingId;

  if (api.mod) {
    linkEdit.href = '/edit.js?boardUri=' + boardUri + '&';
    linkEdit.href += complement;
  } else if (linkEdit) {
    linkEdit.remove();
  }

  if (api.mod && post.ip) {
    linkFileHistory.href = '/mediaManagement.js?boardUri=' + boardUri + '&';
    linkFileHistory.href += complement;

    linkHistory.href = '/latestPostings.js?boardUri=' + boardUri + '&';
    linkHistory.href += complement;
  } else if (linkHistory) {
    linkHistory.remove();
    linkFileHistory.remove();
  }

  var checkboxName = boardUri + '-' + threadId;

  if (post.postId) {
    checkboxName += '-' + post.postId;
  }

  deletionCheckbox.setAttribute('name', checkboxName);

};

posting.setRoleSignature = function(postingCell, posting) {

  var labelRole = postingCell.getElementsByClassName('labelRole')[0];

  if (posting.signedRole) {
    labelRole.innerHTML = posting.signedRole;
  } else {
    labelRole.parentNode.removeChild(labelRole);
  }

};

posting.setPostComplexElements = function(postCell, post, boardUri, threadId,
    noExtras) {

  posting.setRoleSignature(postCell, post);

  var link = postCell.getElementsByClassName('linkSelf')[0];

  var linkQuote = postCell.getElementsByClassName('linkQuote')[0];
  linkQuote.innerHTML = post.postId || threadId;

  var deletionCheckbox = postCell.getElementsByClassName('deletionCheckBox')[0];

  posting.setPostLinks(postCell, post, boardUri, link, threadId, linkQuote,
      deletionCheckbox);

  var panelUploads = postCell.getElementsByClassName('panelUploads')[0];

  if (!post.files || !post.files.length) {
    panelUploads.remove();
  } else {

    if (post.files.length > 1) {
      panelUploads.className += ' multipleUploads';
    }

    posting.setUploadCell(panelUploads, post.files, noExtras);
  }

};

posting.setPostInnerElements = function(boardUri, threadId, post, postCell,
    noExtras) {

  var linkName = postCell.getElementsByClassName('linkName')[0];

  linkName.innerHTML = post.name;

  if (post.email) {
    linkName.href = 'mailto:' + post.email;
  } else {
    linkName.className += ' noEmailName';
  }

  var labelCreated = postCell.getElementsByClassName('labelCreated')[0];

  labelCreated.innerHTML = api.formatDateToDisplay(new Date(post.creation));

  if (posting.localTimes) {
    posting.setLocalTime(labelCreated);
  }

  if (localStorage.relativeTime && JSON.parse(localStorage.relativeTime)) {
    posting.addRelativeTime(labelCreated);
  }

  postCell.getElementsByClassName('divMessage')[0].innerHTML = post.markdown;

  posting.setPostHideableElements(postCell, post, noExtras);

  posting.setPostComplexElements(postCell, post, boardUri, threadId, noExtras);

  var messageLinks = postCell.getElementsByClassName('divMessage')[0]
      .getElementsByTagName('a');

  for (var i = 0; i < messageLinks.length; i++) {
    embed.processLinkForEmbed(messageLinks[i]);
  }

  var links = postCell.getElementsByClassName('imgLink');

  var temporaryImageLinks = [];

  for (i = 0; i < links.length; i++) {
    temporaryImageLinks.push(links[i]);
  }

  for (i = 0; i < temporaryImageLinks.length; i++) {
    thumbs.processImageLink(temporaryImageLinks[i]);
  }

  var shownFiles = postCell.getElementsByClassName('uploadCell');

  for (var i = 0; i < shownFiles.length; i++) {
    mediaHiding.processFileForHiding(shownFiles[i]);
  }

  var hiddenMedia = mediaHiding.getHiddenMedia();

  for (i = 0; i < hiddenMedia.length; i++) {
    mediaHiding.updateHiddenFiles(hiddenMedia[i], true);
  }

  postCell.setAttribute('data-boarduri', boardUri);

  if (noExtras) {
    return;
  }

  tooltips.addToKnownPostsForBackLinks(postCell);

  var quotes = postCell.getElementsByClassName('quoteLink');

  for (i = 0; i < quotes.length; i++) {
    tooltips.processQuote(quotes[i]);
  }

  var linkSelf = postCell.getElementsByClassName('linkSelf')[0];
  hiding.setHideMenu(linkSelf);
  postingMenu.setExtraMenu(linkSelf)

  if (api.threadId) {
    thread.processPostingQuote(postCell.getElementsByClassName('linkQuote')[0]);
  }

};

posting.addPost = function(post, boardUri, threadId, noExtra) {

  var postCell = document.createElement('div');
  postCell.innerHTML = posting.postCellTemplate;

  postCell.id = post.postId;
  postCell.setAttribute('class', 'postCell');

  postCell.setAttribute('data-boarduri', boardUri);

  posting.setPostInnerElements(boardUri, threadId, post, postCell, noExtra);

  return postCell;

};

posting.init();