(function() { var $, $$, AEOS, DAY, a, addTo, arr, as, autoWatch, autohide, b, board, callback, clearHidden, closeQR, config, cooldown, cutoff, d, delform, down, editSauce, el, expand, expandComment, expandThread, formSubmit, g, getConfig, getThread, getTime, hide, hideReply, hideThread, href, html, i, id, iframe, iframeLoad, imageClick, imageExpandClick, imageFull, imageThumb, imageToggle, img, inAfter, inBefore, input, inputs, keyModeInsert, keyModeNormal, keydown, keypress, l1, lastChecked, m, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, options, optionsClose, parseResponse, pathname, qrListener, qrText, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, remove, replace, replyNav, report, scroll, show, showReply, showThread, slice, span, src, start, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, tzOffset, up, watch, watchX, watcher, watcherUpdate, x, zeroPad, _, _base, _fn, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _m, _ref, _ref2, _ref3, _ref4; var __slice = Array.prototype.slice, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (this[i] === item) return i; } return -1; }; config = { '404 Redirect': [true, 'Redirect dead threads'], 'Anonymize': [false, 'Make everybody anonymous'], 'Auto Watch': [true, 'Automatically watch threads that you start (Firefox only)'], 'Comment Expansion': [true, 'Expand too long comments'], 'Image Expansion': [true, 'Expand images'], 'Keybinds': [false, 'Binds actions to keys'], 'Localize Time': [true, 'Show times based on your timezone'], 'Persistent QR': [false, 'Quick reply won\'t disappear after posting. Only in replies.'], 'Post in Title': [true, 'Show the op\'s post in the tab title'], 'Quick Reply': [true, 'Reply without leaving the page'], 'Quick Report': [true, 'Add quick report buttons'], 'Reply Hiding': [true, 'Hide single replies'], 'Reply Navigation': [true, 'Navigate to the beginning / end of a thread'], 'Sauce': [true, 'Add sauce to images'], 'Show Stubs': [true, 'Of hidden threads / replies'], 'Thread Expansion': [true, 'View all replies'], 'Thread Hiding': [true, 'Hide entire threads'], 'Thread Navigation': [true, 'Navigate to previous / next thread'], 'Thread Watcher': [true, 'Bookmark threads'] }; AEOS = { init: function() { if (typeof GM_deleteValue === 'undefined') { window.GM_setValue = function(name, value) { value = (typeof value)[0] + value; return localStorage.setItem(name, value); }; window.GM_getValue = function(name, defaultValue) { var type, value; if (!(value = localStorage.getItem(name))) { return defaultValue; } type = value[0]; value = value.slice(1); switch (type) { case 'b': return value === 'true'; case 'n': return Number(value); default: return value; } }; window.GM_addStyle = function(css) { var style; style = document.createElement('style'); style.type = 'text/css'; style.textContent = css; return document.getElementsByTagName('head')[0].appendChild(style); }; window.GM_openInTab = function(url) { return window.open(url, "_blank"); }; } return GM_addStyle('\ div.dialog {\ border: 1px solid;\ }\ div.dialog > div.move {\ cursor: move;\ }\ label, a {\ cursor: pointer;\ }\ '); }, makeDialog: function(id, position) { var dialog, left, top; dialog = document.createElement('div'); dialog.className = 'reply dialog'; dialog.id = id; switch (position) { case 'topleft': left = '0px'; top = '0px'; break; case 'topright': left = null; top = '0px'; break; case 'bottomleft': left = '0px'; top = null; break; case 'bottomright': left = null; top = null; } left = GM_getValue("" + id + "Left", left); top = GM_getValue("" + id + "Top", top); if (left) { dialog.style.left = left; } else { dialog.style.right = '0px'; } if (top) { dialog.style.top = top; } else { dialog.style.bottom = '0px'; } return dialog; }, move: function(e) { var div; div = this.parentNode; AEOS.div = div; AEOS.dx = e.clientX - div.offsetLeft; AEOS.dy = e.clientY - div.offsetTop; AEOS.width = document.body.clientWidth - div.offsetWidth; AEOS.height = document.body.clientHeight - div.offsetHeight; document.addEventListener('mousemove', AEOS.moveMove, true); return document.addEventListener('mouseup', AEOS.moveEnd, true); }, moveMove: function(e) { var bottom, div, left, right, top; div = AEOS.div; left = e.clientX - AEOS.dx; if (left < 20) { left = '0px'; } else if (AEOS.width - left < 20) { left = ''; } right = left ? '' : '0px'; div.style.left = left; div.style.right = right; top = e.clientY - AEOS.dy; if (top < 20) { top = '0px'; } else if (AEOS.height - top < 20) { top = ''; } bottom = top ? '' : '0px'; div.style.top = top; return div.style.bottom = bottom; }, moveEnd: function() { var div, id; document.removeEventListener('mousemove', AEOS.moveMove, true); document.removeEventListener('mouseup', AEOS.moveEnd, true); div = AEOS.div; id = div.id; GM_setValue("" + id + "Left", div.style.left); return GM_setValue("" + id + "Top", div.style.top); } }; d = document; g = null; $ = function(selector, root) { root || (root = d.body); return root.querySelector(selector); }; $$ = function(selector, root) { var node, result, _i, _len, _results; root || (root = d.body); result = root.querySelectorAll(selector); _results = []; for (_i = 0, _len = result.length; _i < _len; _i++) { node = result[_i]; _results.push(node); } return _results; }; addTo = function() { var child, children, parent, _i, _len, _results; parent = arguments[0], children = 2 <= arguments.length ? __slice.call(arguments, 1) : []; _results = []; for (_i = 0, _len = children.length; _i < _len; _i++) { child = children[_i]; _results.push(parent.appendChild(child)); } return _results; }; getConfig = function(name) { return GM_getValue(name, config[name][0]); }; getTime = function() { return Math.floor(new Date().getTime() / 1000); }; hide = function(el) { return el.style.display = 'none'; }; inAfter = function(root, el) { return root.parentNode.insertBefore(el, root.nextSibling); }; inBefore = function(root, el) { return root.parentNode.insertBefore(el, root); }; m = function(el, props) { var event, funk, key, l, val; if (l = props.listener) { delete props.listener; event = l[0], funk = l[1]; el.addEventListener(event, funk, true); } for (key in props) { val = props[key]; el[key] = val; } return el; }; n = function(tag, props) { var el; el = d.createElement(tag); if (props) { m(el, props); } return el; }; remove = function(el) { return el.parentNode.removeChild(el); }; replace = function(root, el) { return root.parentNode.replaceChild(el, root); }; show = function(el) { return el.style.display = ''; }; slice = function(arr, id) { var i, l, _results; i = 0; l = arr.length; _results = []; while (i < l) { if (id === arr[i].id) { arr.splice(i, 1); return arr; } _results.push(i++); } return _results; }; tn = function(s) { return d.createTextNode(s); }; x = function(path, root) { root || (root = d.body); return d.evaluate(path, root, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; }; zeroPad = function(n) { if (n < 10) { return '0' + n; } else { return n; } }; autohide = function() { var klass, qr; qr = $('#qr'); klass = qr.className; if (klass.indexOf('auto') === -1) { klass += ' auto'; } else { klass = klass.replace(' auto', ''); } return qr.className = klass; }; autoWatch = function() { var autoText; autoText = $('textarea', this).value.slice(0, 25); return GM_setValue('autoText', "/" + g.BOARD + "/ - " + autoText); }; closeQR = function() { var div; div = this.parentNode.parentNode; return remove(div); }; clearHidden = function() { GM_deleteValue("hiddenReplies/" + g.BOARD + "/"); GM_deleteValue("hiddenThreads/" + g.BOARD + "/"); this.value = "hidden: 0"; g.hiddenReplies = []; return g.hiddenThreads = []; }; cooldown = function() { var auto, seconds, submit; submit = $('#qr input[type=submit]'); seconds = parseInt(submit.value); if (seconds === 0) { submit.disabled = false; submit.value = 'Submit'; auto = submit.previousSibling.lastChild; if (auto.checked) { return $('#qr form').submit(); } } else { submit.value = seconds - 1; return window.setTimeout(cooldown, 1000); } }; editSauce = function() { var ta; ta = $('#options textarea'); if (ta.style.display) { return show(ta); } else { return hide(ta); } }; expandComment = function(e) { var a, href, r; e.preventDefault(); a = this; href = a.getAttribute('href'); r = new XMLHttpRequest(); r.onload = function() { return onloadComment(this.responseText, a, href); }; r.open('GET', href, true); r.send(); return g.xhrs.push({ r: r, id: href.match(/\d+/)[0] }); }; expandThread = function() { var id, num, prev, r, span, table, xhr, _i, _len, _ref; id = x('preceding-sibling::input[1]', this).name; span = this; if (span.textContent[0] === '-') { num = board === 'b' ? 3 : 5; table = x("following::br[@clear][1]/preceding::table[" + num + "]", span); while ((prev = table.previousSibling) && (prev.nodeName === 'TABLE')) { remove(prev); } span.textContent = span.textContent.replace('-', '+'); return; } span.textContent = span.textContent.replace('+', 'X Loading...'); _ref = g.xhrs; for (_i = 0, _len = _ref.length; _i < _len; _i++) { xhr = _ref[_i]; if (xhr.id === id) { onloadThread(xhr.r.responseText, span); return; } } r = new XMLHttpRequest(); r.onload = function() { return onloadThread(this.responseText, span); }; r.open('GET', "res/" + id, true); r.send(); return g.xhrs.push({ r: r, id: id }); }; getThread = function() { var bottom, i, thread, threads, _len; threads = $$('div.thread'); for (i = 0, _len = threads.length; i < _len; i++) { thread = threads[i]; bottom = thread.getBoundingClientRect().bottom; if (bottom > 0) { return [thread, i]; } } }; formSubmit = function(e) { var recaptcha, span, _ref; if (span = this.nextSibling) { remove(span); } recaptcha = $('input[name=recaptcha_response_field]', this); if (recaptcha.value) { return (_ref = $('#qr input[title=autohide]:not(:checked)')) != null ? _ref.click() : void 0; } else { e.preventDefault(); span = n('span', { className: 'error', textContent: 'You forgot to type in the verification.' }); addTo(this.parentNode, span); alert('You forgot to type in the verification.'); return recaptcha.focus(); } }; hideReply = function(reply) { var a, div, name, p, table, trip, _ref; if (p = this.parentNode) { reply = p.nextSibling; g.hiddenReplies.push({ id: reply.id, timestamp: getTime() }); GM_setValue("hiddenReplies/" + g.BOARD + "/", JSON.stringify(g.hiddenReplies)); } name = $('span.commentpostername', reply).textContent; trip = ((_ref = $('span.postertrip', reply)) != null ? _ref.textContent : void 0) || ''; table = x('ancestor::table', reply); hide(table); if (getConfig('Show Stubs')) { a = n('a', { textContent: "[ + ] " + name + " " + trip, className: 'pointer', listener: ['click', showReply] }); div = n('div'); addTo(div, a); return inBefore(table, div); } }; hideThread = function(div) { var a, name, num, p, span, text, trip, _ref; if (p = this.parentNode) { div = p; g.hiddenThreads.push({ id: div.id, timestamp: getTime() }); GM_setValue("hiddenThreads/" + g.BOARD + "/", JSON.stringify(g.hiddenThreads)); } hide(div); if (getConfig('Show Stubs')) { if (span = $('.omittedposts', div)) { num = Number(span.textContent.match(/\d+/)[0]); } else { num = 0; } num += $$('table', div).length; text = num === 1 ? "1 reply" : "" + num + " replies"; name = $('span.postername', div).textContent; trip = ((_ref = $('span.postername + span.postertrip', div)) != null ? _ref.textContent : void 0) || ''; a = n('a', { textContent: "[ + ] " + name + trip + " (" + text + ")", className: 'pointer', listener: ['click', showThread] }); return inBefore(div, a); } }; iframeLoad = function() { var auto, error, qr, span, submit, _ref, _ref2; if (g.iframe = !g.iframe) { return; } $('iframe').src = 'about:blank'; qr = $('#qr'); if (error = GM_getValue('error')) { span = n('span', { textContent: error, className: 'error' }); addTo(qr, span); if ((_ref = $('input[title=autohide]:checked', qr)) != null) { _ref.click(); } } else if (g.REPLY && getConfig('Persistent QR')) { $('textarea', qr).value = ''; $('input[name=recaptcha_response_field]', qr).value = ''; submit = $('input[type=submit]', qr); submit.value = 30; submit.disabled = true; window.setTimeout(cooldown, 1000); auto = submit.previousSibling.lastChild; if (auto.checked) { if ((_ref2 = $('input[title=autohide]:checked', qr)) != null) { _ref2.click(); } } } else { remove(qr); } return recaptchaReload(); }; imageClick = function(e) { if (e.shiftKey || e.altKey || e.ctrlKey) { return; } e.preventDefault(); return imageToggle(this); }; imageToggle = function(image) { var thumb; thumb = image.firstChild; if (thumb.className === 'hide') { return imageThumb(thumb); } else { return imageFull(thumb); } }; imageExpandClick = function() { var thumb, thumbs, _i, _j, _len, _len2, _results, _results2; thumbs = $$('img[md5]'); g.expand = this.checked; if (this.checked) { _results = []; for (_i = 0, _len = thumbs.length; _i < _len; _i++) { thumb = thumbs[_i]; _results.push(thumb.className !== 'hide' ? imageFull(thumb) : void 0); } return _results; } else { _results2 = []; for (_j = 0, _len2 = thumbs.length; _j < _len2; _j++) { thumb = thumbs[_j]; _results2.push(thumb.className === 'hide' ? imageThumb(thumb) : void 0); } return _results2; } }; imageFull = function(thumb) { var img, link; thumb.className = 'hide'; link = thumb.parentNode; img = n('img', { src: link.href }); return link.appendChild(img); }; imageThumb = function(thumb) { thumb.className = ''; return remove(thumb.nextSibling); }; keydown = function(e) { var kc; kc = e.keyCode; g.keyCode = kc; return g.char = String.fromCharCode(kc); }; keypress = function(e) { var _ref; if ((_ref = document.activeElement.nodeName) === 'TEXTAREA' || _ref === 'INPUT') { return keyModeInsert(e); } else { return keyModeNormal(e); } }; keyModeInsert = function(e) { var char, kc, range, selEnd, selStart, ta, valEnd, valMid, valStart, value; kc = g.keyCode; char = g.char; if (kc === 27) { remove($('#qr')); return e.preventDefault(); } else if (e.ctrlKey && char === "S") { ta = document.activeElement; if (ta.nodeName !== 'TEXTAREA') { return; } value = ta.value; selStart = ta.selectionStart; selEnd = ta.selectionEnd; valStart = value.slice(0, selStart) + '[spoiler]'; valMid = value.slice(selStart, selEnd); valEnd = '[/spoiler]' + value.slice(selEnd); ta.value = valStart + valMid + valEnd; range = valStart.length + valMid.length; ta.setSelectionRange(range, range); return e.preventDefault(); } }; keyModeNormal = function(e) { var bot, char, count, hash, height, href, image, next, prev, qrLink, rect, replies, reply, root, sign, td, temp, thread, top, watchButton, _i, _j, _len, _len2; if (e.ctrlKey || e.altKey) { return; } char = g.char; hash = location.hash; count = g.count; if (__indexOf.call('1234567890', char) >= 0) { temp = Number(char); if (temp === 0 && count === 0) { location.pathname = "/" + g.BOARD; } else { g.count = (count * 10) + temp; } return; } g.count = 0; if (char === "G") { if (count) { temp = count > 15 ? 15 : count; location.pathname = "/" + g.BOARD + "/" + temp + "#1"; } else { if (e.shiftKey) { window.scrollTo(0, 99999); } else { window.scrollTo(0, 0); location.hash = ''; } } } count || (count = 1); switch (char) { case "H": if (e.shiftKey) { if (!g.REPLY) { temp = g.PAGENUM - count; if (temp < 0) { temp = 0; } return location.pathname = "/" + g.BOARD + "/" + temp + "#1"; } } else { return window.scrollBy(-20 * count, 0); } break; case "I": if (g.reply) { if (!(qrLink = $('td.replyhl span[id] a:not(:first-child)'))) { qrLink = $("span[id^=nothread] a:not(:first-child)"); } } else { thread = getThread()[0]; if (!(qrLink = $('td.replyhl span[id] a:not(:first-child)', thread))) { qrLink = $("span#nothread" + thread.id + " a:not(:first-child)", thread); } } if (e.shiftKey) { return quickReply(qrLink); } else { return quickReply(qrLink, qrText(qrLink)); } break; case "J": if (e.shiftKey) { if (!g.REPLY) { root = getThread()[0]; } if (td = $('td.replyhl', root)) { td.className = 'reply'; rect = td.getBoundingClientRect(); if (rect.top > 0 && rect.bottom < d.body.clientHeight) { next = x('following::td[@class="reply"]', td); rect = next.getBoundingClientRect(); if (rect.top > 0 && rect.bottom < d.body.clientHeight) { next.className = 'replyhl'; } return; } } replies = $$('td.reply', root); for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; top = reply.getBoundingClientRect().top; if (top > 0) { reply.className = 'replyhl'; break; } } } else { return window.scrollBy(0, 20 * count); } break; case "K": if (e.shiftKey) { if (!g.REPLY) { root = getThread()[0]; } if (td = $('td.replyhl', root)) { td.className = 'reply'; rect = td.getBoundingClientRect(); if (rect.top > 0 && rect.bottom < d.body.clientHeight) { prev = x('preceding::td[@class="reply"][1]', td); rect = prev.getBoundingClientRect(); if (rect.top > 0 && rect.bottom < d.body.clientHeight) { prev.className = 'replyhl'; } return; } } replies = $$('td.reply', root); replies.reverse(); height = d.body.clientHeight; for (_j = 0, _len2 = replies.length; _j < _len2; _j++) { reply = replies[_j]; bot = reply.getBoundingClientRect().bottom; if (bot < height) { reply.className = 'replyhl'; break; } } } else { return window.scrollBy(0, -20 * count); } break; case "L": if (e.shiftKey) { if (!g.REPLY) { temp = g.PAGENUM + count; if (temp > 15) { temp = 15; } return location.pathname = "/" + g.BOARD + "/" + temp + "#0"; } } else { return window.scrollBy(20 * count, 0); } break; case "M": if (e.shiftKey) { return $("#imageExpand").click(); } else { if (!g.REPLY) { root = getThread()[0]; } if (!(image = $('td.replyhl span.filesize ~ a[target]', root))) { image = $('span.filesize ~ a[target]', root); } return imageToggle(image); } break; case "N": sign = e.shiftKey ? -1 : 1; return scroll(sign * count); break; case "O": href = $("" + hash + " ~ span[id] a:last-of-type").href; if (e.shiftKey) { return location.href = href; } else { return GM_openInTab(href); } break; case "W": watchButton = $("" + hash + " ~ img"); return watch.call(watchButton); } }; nodeInserted = function(e) { var callback, qr, target, _i, _len, _ref, _results; target = e.target; if (target.nodeName === 'TABLE') { _ref = g.callbacks; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { callback = _ref[_i]; _results.push(callback(target)); } return _results; } else if (target.id === 'recaptcha_challenge_field' && (qr = $('#qr'))) { $('#recaptcha_image img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + target.value; return $('#recaptcha_challenge_field', qr).value = target.value; } }; onloadComment = function(responseText, a, href) { var bq, html, id, op, opbq, replies, reply, _, _i, _len, _ref, _ref2; _ref = href.match(/(\d+)#(\d+)/), _ = _ref[0], op = _ref[1], id = _ref[2]; _ref2 = parseResponse(responseText), replies = _ref2[0], opbq = _ref2[1]; if (id === op) { html = opbq.innerHTML; } else { for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; if (reply.id === id) { html = $('blockquote', reply).innerHTML; } } } bq = x('ancestor::blockquote', a); return bq.innerHTML = html; }; onloadThread = function(responseText, span) { var div, next, opbq, replies, reply, _i, _j, _len, _len2, _ref, _results, _results2; _ref = parseResponse(responseText), replies = _ref[0], opbq = _ref[1]; span.textContent = span.textContent.replace('X Loading...', '- '); span.previousSibling.innerHTML = opbq.innerHTML; while ((next = span.nextSibling) && !next.clear) { remove(next); } if (next) { _results = []; for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; _results.push(inBefore(next, x('ancestor::table', reply))); } return _results; } else { div = span.parentNode; _results2 = []; for (_j = 0, _len2 = replies.length; _j < _len2; _j++) { reply = replies[_j]; _results2.push(addTo(div, x('ancestor::table', reply))); } return _results2; } }; options = function() { var checked, description, div, hiddenNum, html, option, value; if (div = $('#options')) { return remove(div); } else { div = AEOS.makeDialog('options', 'center'); hiddenNum = g.hiddenReplies.length + g.hiddenThreads.length; html = '