From 0ee7960a1e0ad2ec90f0fe7a5129a4b4a89b09ab Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 24 Aug 2013 14:07:00 -0700 Subject: [PATCH] Build --- builds/4chan-X.meta.js | 21 - builds/4chan-X.user.js | 11742 ------------------------------------- builds/appchan-x.user.js | 2 +- 3 files changed, 1 insertion(+), 11764 deletions(-) delete mode 100755 builds/4chan-X.meta.js delete mode 100644 builds/4chan-X.user.js diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js deleted file mode 100755 index a16133455..000000000 --- a/builds/4chan-X.meta.js +++ /dev/null @@ -1,21 +0,0 @@ -// ==UserScript== -// @name 4chan X -// @version 1.2.35 -// @minGMVer 1.13 -// @minFFVer 22 -// @namespace 4chan-X -// @description Cross-browser userscript for maximum lurking on 4chan. -// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE -// @match *://api.4chan.org/* -// @match *://boards.4chan.org/* -// @match *://images.4chan.org/* -// @match *://sys.4chan.org/* -// @grant GM_getValue -// @grant GM_setValue -// @grant GM_deleteValue -// @grant GM_openInTab -// @run-at document-start -// @updateURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.meta.js -// @downloadURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.user.js -// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC -// ==/UserScript== diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js deleted file mode 100644 index 8f3d0882e..000000000 --- a/builds/4chan-X.user.js +++ /dev/null @@ -1,11742 +0,0 @@ -// Generated by CoffeeScript -// ==UserScript== -// @name 4chan X -// @version 1.2.35 -// @minGMVer 1.13 -// @minFFVer 22 -// @namespace 4chan-X -// @description Cross-browser userscript for maximum lurking on 4chan. -// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE -// @match *://api.4chan.org/* -// @match *://boards.4chan.org/* -// @match *://images.4chan.org/* -// @match *://sys.4chan.org/* -// @grant GM_getValue -// @grant GM_setValue -// @grant GM_deleteValue -// @grant GM_openInTab -// @run-at document-start -// @updateURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.meta.js -// @downloadURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.user.js -// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC -// ==/UserScript== - -/* -* 4chan X - Version 1.2.35 - 2013-08-24 -* -* Licensed under the MIT license. -* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE -* -* Appchan X Copyright © 2013-2013 Zixaphir -* http://zixaphir.github.io/appchan-x/ -* 4chan x Copyright © 2009-2011 James Campos -* https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2013 Nicolas Stepien -* https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2013 Jordan Bates -* http://seaweedchan.github.io/4chan-x/ -* 4chan x Copyright © 2012-2013 ihavenoface -* http://ihavenoface.github.io/4chan-x/ -* 4chan SS Copyright © 2011-2013 Ahodesuka -* https://github.com/ahodesuka/4chan-Style-Script/ -* -* Permission is hereby granted, free of charge, to any person -* obtaining a copy of this software and associated documentation -* files (the "Software"), to deal in the Software without -* restriction, including without limitation the rights to use, -* copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following -* conditions: -* -* The above copyright notice and this permission notice shall be -* included in all copies or substantial portions of the Software. -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -* -* Contributors: -* aeosynth -* mayhemydg -* noface -* !K.WeEabo0o -* blaise -* that4chanwolf -* desuwa -* seaweed -* e000 -* ahodesuka -* Shou -* ferongr -* xat -* Ongpot -* thisisanon -* Anonymous -* Seiba -* herpaderpderp -* WakiMiko -* btmcsweeney -* AppleBloom -* detharonil -* -* All the people who've taken the time to write bug reports. -* -* Thank you. -*/ - -/* -* Contains data from external sources: -* -* audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/ -* cc-by-nc-3.0 -* -* 4chan/4chan-JS (https://github.com/4chan/4chan-JS) -* Copyright (c) 2012-2013, 4chan LLC -* All rights reserved. -* -* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE -*/ -'use strict'; - -(function() { - var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g, - __slice = [].slice, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Config = { - main: { - 'Miscellaneous': { - 'Catalog Links': [true, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'], - 'External Catalog': [false, 'Link to external catalog instead of the internal one.'], - 'QR Shortcut': [false, 'Adds a small [QR] link in the header.'], - 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'], - 'Desktop Notifications': [false, 'Enables desktop notifications across various 4chan X features.'], - '404 Redirect': [true, 'Redirect dead threads and images.'], - 'Keybinds': [true, 'Bind actions to keyboard shortcuts.'], - 'Time Formatting': [true, 'Localize and format timestamps.'], - 'Relative Post Dates': [true, 'Display dates like "3 minutes ago". Tooltip shows the timestamp.'], - 'File Info Formatting': [true, 'Reformat the file information.'], - 'Comment Expansion': [true, 'Add buttons to expand long comments.'], - 'Thread Expansion': [true, 'Add buttons to expand threads.'], - 'Index Navigation': [false, 'Add buttons to navigate between threads.'], - 'Reply Navigation': [false, 'Add buttons to navigate to top / bottom of thread.'], - 'Show Dice Roll': [true, 'Show dice that were entered into the email field.'], - 'Custom Board Titles': [true, 'Allow editing of the board title and subtitle by ctrl+clicking them'], - 'Persistent Custom Board Titles': [false, 'Force custom board titles to be persistent, even if moot updates the board titles.'], - 'Show Updated Notifications': [true, 'Show notifications when 4chan X is successfully updated.'], - 'Emoji': [false, 'Adds icons next to names for different emails'], - 'Color User IDs': [false, 'Assign unique colors to user IDs on boards that use them'], - 'Remove Spoilers': [false, 'Remove all spoilers in text.'], - 'Reveal Spoilers': [false, 'Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled.'] - }, - 'Linkification': { - 'Linkify': [true, 'Convert text into links where applicable.'], - 'Embedding': [true, 'Embed supported services.'], - 'Auto-embed': [false, 'Auto-embed Linkify Embeds.'], - 'Link Title': [true, 'Replace the link of a supported site with its actual title. Currently Supported: YouTube, Vimeo, SoundCloud, and Github gists'] - }, - 'Filtering': { - 'Anonymize': [false, 'Make everyone Anonymous.'], - 'Filter': [true, 'Self-moderation placebo.'], - 'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'], - 'Thread Hiding Buttons': [false, 'Add buttons to hide entire threads.'], - 'Reply Hiding Buttons': [false, 'Add buttons to hide single replies.'], - 'Filtered Backlinks': [true, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.'], - 'Stubs': [true, 'Show stubs of hidden threads / replies.'] - }, - 'Images': { - 'Image Expansion': [true, 'Expand images.'], - 'Image Hover': [true, 'Show full image on mouseover.'], - 'Gallery': [true, 'Adds a simple and cute image gallery.'], - 'Sauce': [true, 'Add sauce links to images.'], - 'Reveal Spoiler Thumbnails': [false, 'Replace spoiler thumbnails with the original image.'], - 'Replace GIF': [false, 'Replace thumbnail of gifs with its actual image.'], - 'Replace PNG': [false, 'Replace pngs.'], - 'Replace JPG': [false, 'Replace jpgs.'], - 'Image Prefetching': [false, 'Preload images'], - 'Fappe Tyme': [false, 'Hide posts without images. *hint* *hint*'], - 'Werk Tyme': [false, 'Hide all post images.'] - }, - 'Menu': { - 'Menu': [true, 'Add a drop-down menu to posts.'], - 'Report Link': [true, 'Add a report link to the menu.'], - 'Thread Hiding Link': [true, 'Add a link to hide entire threads.'], - 'Reply Hiding Link': [true, 'Add a link to hide single replies.'], - 'Delete Link': [true, 'Add post and image deletion links to the menu.'], - 'Archive Link': [true, 'Add an archive link to the menu.'] - }, - 'Monitoring': { - 'Thread Updater': [true, 'Fetch and insert new replies. Has more options in its own dialog.'], - 'Unread Count': [true, 'Show the unread posts count in the tab title.'], - 'Hide Unread Count at (0)': [false, 'Hide the unread posts count in the tab title when it reaches 0.'], - 'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'], - 'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'], - 'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.'], - 'Thread Excerpt': [true, 'Show an excerpt of the thread in the tab title.'], - 'Thread Stats': [true, 'Display reply and image count.'], - 'Page Count in Stats': [false, 'Display the page count in the thread stats as well.'], - 'Updater and Stats in Header': [true, 'Places the thread updater and thread stats in the header instead of floating them.'], - 'Thread Watcher': [true, 'Bookmark threads.'], - 'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher, hides the watcher by default, and makes it scroll with the page.'] - }, - 'Posting': { - 'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'], - 'Persistent QR': [true, 'The Quick reply won\'t disappear after posting.'], - 'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.'], - 'Open Post in New Tab': [true, 'Open new threads or replies to a thread from the index in a new tab.'], - 'Remember Subject': [false, 'Remember the subject field, instead of resetting after posting.'], - 'Remember QR Size': [false, 'Remember the size of the Quick reply.'], - 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting.'], - 'Hide Original Post Form': [true, 'Hide the normal post form.'], - 'Cooldown': [true, 'Indicate the remaining time before posting again.'], - 'Cooldown Prediction': [true, 'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'], - 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.'], - 'Captcha Warning Notifications': [true, 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'] - }, - 'Quote Links': { - 'Quote Backlinks': [true, 'Add quote backlinks.'], - 'OP Backlinks': [true, 'Add backlinks to the OP.'], - 'Quote Inlining': [true, 'Inline quoted post on click.'], - 'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.'], - 'Forward Hiding': [true, 'Hide original posts of inlined backlinks.'], - 'Quote Previewing': [true, 'Show quoted post on hover.'], - 'Quote Highlighting': [true, 'Highlight the previewed post.'], - 'Resurrect Quotes': [true, 'Link dead quotes to the archives.'], - 'Mark Quotes of You': [true, 'Add \'(You)\' to quotes linking to your posts.'], - 'Quoted Title': [false, 'Change the page title to reflect you\'ve been quoted.'], - 'Highlight Posts Quoting You': [false, 'Highlights any posts that contain a quote to your post.'], - 'Highlight Own Posts': [false, 'Highlights own posts if Mark Quotes of You is enabled.'], - 'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'], - 'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'], - 'Quote Threading': [true, 'Thread conversations'] - } - }, - imageExpansion: { - 'Fit width': [false, ''], - 'Fit height': [false, ''], - 'Expand spoilers': [true, 'Expand all images along with spoilers.'], - 'Expand from here': [false, 'Expand all images only from current position to thread end.'], - 'Advance on contract': [false, 'Advance to next post when contracting an expanded image.'] - }, - gallery: { - 'Hide thumbnails': [false] - }, - threadWatcher: { - 'Current Board': [false, 'Only show watched threads from the current board.'], - 'Auto Watch': [true, 'Automatically watch threads you start.'], - 'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'], - 'Auto Prune': [false, 'Automatically prune 404\'d threads.'] - }, - filter: { - name: "# Filter any namefags:\n#/^(?!Anonymous$)/", - uniqueID: "# Filter a specific ID:\n#/Txhvk1Tl/", - tripcode: "# Filter any tripfag\n#/^!/", - capcode: "# Set a custom class for mods:\n#/Mod$/;highlight:mod;op:yes\n# Set a custom class for moot:\n#/Admin$/;highlight:moot;op:yes", - email: "# Filter any e-mails that are not `sage` on /a/ and /jp/:\n#/^(?!sage$)/;boards:a,jp", - subject: "# Filter Generals on /v/:\n#/general/i;boards:v;op:only", - comment: "# Filter Stallman copypasta on /g/:\n#/what you\'re refer+ing to as linux/i;boards:g", - flag: '', - filename: '', - dimensions: "# Highlight potential wallpapers:\n#/1920x1080/;op:yes;highlight;top:no;boards:w,wg", - filesize: '', - MD5: '' - }, - sauces: "https://www.google.com/searchbyimage?image_url=%TURL\nhttp://iqdb.org/?url=%TURL\n#//tineye.com/search?url=%TURL\n#http://saucenao.com/search.php?url=%TURL\n#http://3d.iqdb.org/?url=%TURL\n#http://regex.info/exif.cgi?imgurl=%URL\n# uploaders:\n#http://imgur.com/upload?url=%URL;text:Upload to imgur\n#http://ompldr.org/upload?url1=%URL;text:Upload to ompldr\n# \"View Same\" in archives:\n#//archive.foolz.us/_/search/image/%MD5/;text:View same on foolz\n#//archive.foolz.us/%board/search/image/%MD5/;text:View same on foolz /%board/\n#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/", - 'sageEmoji': '4chan SS', - 'emojiPos': 'before', - 'Custom CSS': false, - Header: { - 'Fixed Header': true, - 'Header auto-hide': false, - 'Bottom Header': false, - 'Centered links': false, - 'Header catalog links': false, - 'Bottom Board List': true, - 'Shortcut Icons': false, - 'Custom Board Navigation': true - }, - boardnav: "[ toggle-all ]\na-replace\nc-replace\ng-replace\nk-replace\nv-replace\nvg-replace\nvr-replace\nck-replace\nco-replace\nfit-replace\njp-replace\nmu-replace\nsp-replace\ntv-replace\nvp-replace\nq-replace\n[external-text:\"FAQ\",\"https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions\"]", - QR: { - 'QR.personas': "#email:\"sage\";boards:jp;always" - }, - time: '%m/%d/%y(%a)%H:%M:%S', - backlink: '>>%id', - fileInfo: '%L (%p%s, %r)', - favicon: 'ferongr', - usercss: '', - hotkeys: { - 'Toggle board list': ['Ctrl+b', 'Toggle the full board list.'], - 'Toggle header': ['Shift+h', 'Toggle the auto-hide option of the header.'], - 'Open empty QR': ['i', 'Open QR without post number inserted.'], - 'Open QR': ['Shift+i', 'Open QR with post number inserted.'], - 'Open settings': ['Alt+o', 'Open Settings.'], - 'Close': ['Esc', 'Close Settings, Notifications or QR.'], - 'Spoiler tags': ['Ctrl+s', 'Insert spoiler tags.'], - 'Code tags': ['Alt+c', 'Insert code tags.'], - 'Eqn tags': ['Alt+e', 'Insert eqn tags.'], - 'Math tags': ['Alt+m', 'Insert math tags.'], - 'Toggle sage': ['Alt+s', 'Toggle sage in email field'], - 'Submit QR': ['Ctrl+Enter', 'Submit post.'], - 'Watch': ['w', 'Watch thread.'], - 'Update': ['r', 'Update the thread now.'], - 'Expand image': ['Shift+e', 'Expand selected image.'], - 'Expand images': ['e', 'Expand all images.'], - 'Open Gallery': ['g', 'Opens the gallery.'], - 'fappeTyme': ['f', 'Fappe Tyme.'], - 'werkTyme': ['Shift+w', 'Werk Tyme'], - 'Front page': ['0', 'Jump to page 0.'], - 'Open front page': ['Shift+0', 'Open page 0 in a new tab.'], - 'Next page': ['Shift+Right', 'Jump to the next page.'], - 'Previous page': ['Shift+Left', 'Jump to the previous page.'], - 'Open catalog': ['Shift+c', 'Open the catalog of the current board'], - 'Next thread': ['Shift+Down', 'See next thread.'], - 'Previous thread': ['Shift+Up', 'See previous thread.'], - 'Expand thread': ['Ctrl+e', 'Expand thread.'], - 'Open thread': ['o', 'Open thread in current tab.'], - 'Open thread tab': ['Shift+o', 'Open thread in new tab.'], - 'Next reply': ['j', 'Select next reply.'], - 'Previous reply': ['k', 'Select previous reply.'], - 'Deselect reply': ['Shift+d', 'Deselect reply.'], - 'Hide': ['x', 'Hide thread.'], - 'Previous Post Quoting You': ['Alt+Up', 'Scroll to the previous post that quotes you.'], - 'Next Post Quoting You': ['Alt+Down', 'Scroll to the next post that quotes you.'] - }, - updater: { - checkbox: { - 'Beep': [false, 'Beep on new post to completely read thread.'], - 'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.'], - 'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'], - 'Scroll BG': [false, 'Auto-scroll background tabs.'], - 'Auto Update': [true, 'Automatically fetch new posts.'], - 'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.'] - }, - 'Interval': 30 - } - }; - - Conf = {}; - - c = console; - - d = document; - - doc = d.documentElement; - - g = { - VERSION: '1.2.35', - NAMESPACE: '4chan X.', - boards: {}, - threads: {}, - posts: {} - }; - - String.prototype.capitalize = function() { - return this.charAt(0).toUpperCase() + this.slice(1); - }; - - String.prototype.contains = function(string) { - return this.indexOf(string) > -1; - }; - - Array.prototype.contains = function(object) { - return this.indexOf(object) > -1; - }; - - Array.prototype.indexOf = function(object) { - var i; - - i = this.length; - while (i--) { - if (this[i] === object) { - return i; - } - } - return i; - }; - - $ = function(selector, root) { - if (root == null) { - root = d.body; - } - return root.querySelector(selector); - }; - - $.extend = function(object, properties) { - var key, val; - - for (key in properties) { - val = properties[key]; - if (!properties.hasOwnProperty(key)) { - continue; - } - object[key] = val; - } - }; - - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); - - $.id = function(id) { - return d.getElementById(id); - }; - - $.ready = function(fc) { - var cb; - - if (d.readyState !== 'loading') { - $.queueTask(fc); - return; - } - cb = function() { - $.off(d, 'DOMContentLoaded', cb); - return fc(); - }; - return $.on(d, 'DOMContentLoaded', cb); - }; - - $.formData = function(form) { - var fd, key, val; - - if (form instanceof HTMLFormElement) { - return new FormData(form); - } - fd = new FormData(); - for (key in form) { - val = form[key]; - if (val) { - if (typeof val === 'object' && 'newName' in val) { - fd.append(key, val, val.newName); - } else { - fd.append(key, val); - } - } - } - return fd; - }; - - $.extend = function(object, properties) { - var key, val; - - for (key in properties) { - val = properties[key]; - object[key] = val; - } - }; - - $.ajax = (function() { - var lastModified; - - lastModified = {}; - return function(url, options, extra) { - var form, r, sync, type, upCallbacks, whenModified; - - if (extra == null) { - extra = {}; - } - type = extra.type, whenModified = extra.whenModified, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync; - r = new XMLHttpRequest(); - type || (type = form && 'post' || 'get'); - r.open(type, url, !sync); - if (whenModified) { - r.setRequestHeader('If-Modified-Since', lastModified[url] || '0'); - $.on(r, 'load', function() { - return lastModified[url] = r.getResponseHeader('Last-Modified'); - }); - } - $.extend(r, options); - $.extend(r.upload, upCallbacks); - r.send(form); - return r; - }; - })(); - - $.cache = (function() { - var reqs; - - reqs = {}; - return function(url, cb, options) { - var err, req, rm; - - if (req = reqs[url]) { - if (req.readyState === 4) { - cb.call(req, req.evt); - } else { - req.callbacks.push(cb); - } - return; - } - rm = function() { - return delete reqs[url]; - }; - try { - req = $.ajax(url, options); - } catch (_error) { - err = _error; - return; - } - $.on(req, 'load', function(e) { - var _i, _len, _ref; - - _ref = this.callbacks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cb = _ref[_i]; - cb.call(this, e); - } - this.evt = e; - return delete this.callbacks; - }); - $.on(req, 'abort error', rm); - req.callbacks = [cb]; - return reqs[url] = req; - }; - })(); - - $.cb = { - checked: function() { - $.set(this.name, this.checked); - return Conf[this.name] = this.checked; - }, - value: function() { - $.set(this.name, this.value.trim()); - return Conf[this.name] = this.value; - } - }; - - $.asap = function(test, cb) { - if (test()) { - return cb(); - } else { - return setTimeout($.asap, 25, test, cb); - } - }; - - $.addStyle = function(css, id) { - var style; - - style = $.el('style', { - id: id, - textContent: css - }); - $.asap((function() { - return d.head; - }), function() { - return $.add(d.head, style); - }); - return style; - }; - - $.x = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 8, null).singleNodeValue; - }; - - $.X = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 7, null); - }; - - $.addClass = function(el, className) { - return el.classList.add(className); - }; - - $.rmClass = function(el, className) { - return el.classList.remove(className); - }; - - $.toggleClass = function(el, className) { - return el.classList.toggle(className); - }; - - $.hasClass = function(el, className) { - return el.classList.contains(className); - }; - - $.rm = (function() { - if ('remove' in Element.prototype) { - return function(el) { - return el.remove(); - }; - } else { - return function(el) { - var _ref; - - return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0; - }; - } - })(); - - $.rmAll = function(root) { - var node; - - while (node = root.firstChild) { - root.removeChild(node); - } - }; - - $.tn = function(s) { - return d.createTextNode(s); - }; - - $.frag = function() { - return d.createDocumentFragment(); - }; - - $.nodes = function(nodes) { - var frag, node, _i, _len; - - if (!(nodes instanceof Array)) { - return nodes; - } - frag = $.frag(); - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i]; - frag.appendChild(node); - } - return frag; - }; - - $.add = function(parent, el) { - return parent.appendChild($.nodes(el)); - }; - - $.prepend = function(parent, el) { - return parent.insertBefore($.nodes(el), parent.firstChild); - }; - - $.after = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root.nextSibling); - }; - - $.before = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root); - }; - - $.replace = function(root, el) { - return root.parentNode.replaceChild($.nodes(el), root); - }; - - $.el = function(tag, properties) { - var el; - - el = d.createElement(tag); - if (properties) { - $.extend(el, properties); - } - return el; - }; - - $.on = function(el, events, handler) { - var event, _i, _len, _ref; - - _ref = events.split(' '); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - event = _ref[_i]; - el.addEventListener(event, handler, false); - } - }; - - $.off = function(el, events, handler) { - var event, _i, _len, _ref; - - _ref = events.split(' '); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - event = _ref[_i]; - el.removeEventListener(event, handler, false); - } - }; - - $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - detail: detail - })); - }; - - $.open = GM_openInTab; - - $.debounce = function(wait, fn) { - var args, exec, lastCall, that, timeout; - - lastCall = 0; - timeout = null; - that = null; - args = null; - exec = function() { - lastCall = Date.now(); - return fn.apply(that, args); - }; - return function() { - args = arguments; - that = this; - if (lastCall < Date.now() - wait) { - return exec(); - } - clearTimeout(timeout); - return timeout = setTimeout(exec, wait); - }; - }; - - $.queueTask = (function() { - var execTask, taskChannel, taskQueue; - - taskQueue = []; - execTask = function() { - var args, func, task; - - task = taskQueue.shift(); - func = task[0]; - args = Array.prototype.slice.call(task, 1); - return func.apply(func, args); - }; - if (window.MessageChannel) { - taskChannel = new MessageChannel(); - taskChannel.port1.onmessage = execTask; - return function() { - taskQueue.push(arguments); - return taskChannel.port2.postMessage(null); - }; - } else { - return function() { - taskQueue.push(arguments); - return setTimeout(execTask, 0); - }; - } - })(); - - $.globalEval = function(code) { - var script; - - script = $.el('script', { - textContent: code - }); - $.add(d.head || doc, script); - return $.rm(script); - }; - - $.bytesToString = function(size) { - var unit; - - unit = 0; - while (size >= 1024) { - size /= 1024; - unit++; - } - size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size); - return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit]; - }; - - $.minmax = function(value, min, max) { - return (value < min ? min : value > max ? max : value); - }; - - $.item = function(key, val) { - var item; - - item = {}; - item[key] = val; - return item; - }; - - $.syncing = {}; - - $.sync = (function() { - $.on(window, 'storage', function(e) { - var cb; - - if (cb = $.syncing[e.key]) { - return cb(JSON.parse(e.newValue)); - } - }); - return function(key, cb) { - return $.syncing[g.NAMESPACE + key] = cb; - }; - })(); - - $["delete"] = function(keys) { - var key, _i, _len; - - if (!(keys instanceof Array)) { - keys = [keys]; - } - for (_i = 0, _len = keys.length; _i < _len; _i++) { - key = keys[_i]; - key = g.NAMESPACE + key; - localStorage.removeItem(key); - GM_deleteValue(key); - } - }; - - $.get = function(key, val, cb) { - var items; - - if (typeof cb === 'function') { - items = $.item(key, val); - } else { - items = key; - cb = val; - } - return $.queueTask(function() { - for (key in items) { - if (val = GM_getValue(g.NAMESPACE + key)) { - items[key] = JSON.parse(val); - } - } - return cb(items); - }); - }; - - $.set = (function() { - var set; - - set = function(key, val) { - key = g.NAMESPACE + key; - val = JSON.stringify(val); - if (key in $.syncing) { - localStorage.setItem(key, val); - } - return GM_setValue(key, val); - }; - return function(keys, val) { - var key; - - if (typeof keys === 'string') { - set(keys, val); - return; - } - for (key in keys) { - val = keys[key]; - set(key, val); - } - }; - })(); - - $$ = function(selector, root) { - if (root == null) { - root = d.body; - } - return __slice.call(root.querySelectorAll(selector)); - }; - - Board = (function() { - Board.prototype.toString = function() { - return this.ID; - }; - - function Board(ID) { - this.ID = ID; - this.threads = {}; - this.posts = {}; - g.boards[this] = this; - } - - return Board; - - })(); - - Thread = (function() { - Thread.prototype.callbacks = []; - - Thread.prototype.toString = function() { - return this.ID; - }; - - function Thread(ID, board) { - this.ID = ID; - this.board = board; - this.fullID = "" + this.board + "." + this.ID; - this.posts = {}; - g.threads[this.fullID] = board.threads[this] = this; - } - - Thread.prototype.kill = function() { - this.isDead = true; - return this.timeOfDeath = Date.now(); - }; - - return Thread; - - })(); - - Post = (function() { - Post.prototype.callbacks = []; - - Post.prototype.toString = function() { - return this.ID; - }; - - function Post(root, thread, board, that) { - var capcode, date, email, flag, info, name, post, subject, tripcode, uniqueID; - - this.thread = thread; - this.board = board; - if (that == null) { - that = {}; - } - this.ID = +root.id.slice(2); - this.fullID = "" + this.board + "." + this.ID; - post = $('.post', root); - info = $('.postInfo', post); - this.nodes = { - root: root, - post: post, - info: info, - comment: $('.postMessage', post), - links: [], - quotelinks: [], - backlinks: info.getElementsByClassName('backlink') - }; - if (!(this.isReply = $.hasClass(post, 'reply'))) { - this.thread.OP = this; - this.thread.isSticky = !!$('.stickyIcon', info); - this.thread.isClosed = !!$('.closedIcon', info); - } - this.info = {}; - if (subject = $('.subject', info)) { - this.nodes.subject = subject; - this.info.subject = subject.textContent; - } - if (name = $('.name', info)) { - this.nodes.name = name; - this.info.name = name.textContent; - } - if (email = $('.useremail', info)) { - this.nodes.email = email; - this.info.email = decodeURIComponent(email.href.slice(7)); - } - if (tripcode = $('.postertrip', info)) { - this.nodes.tripcode = tripcode; - this.info.tripcode = tripcode.textContent; - } - if (uniqueID = $('.posteruid', info)) { - this.nodes.uniqueID = uniqueID; - this.info.uniqueID = uniqueID.firstElementChild.textContent; - } - if (capcode = $('.capcode.hand', info)) { - this.nodes.capcode = capcode; - this.info.capcode = capcode.textContent.replace('## ', ''); - } - if (flag = $('.flag, .countryFlag', info)) { - this.nodes.flag = flag; - this.info.flag = flag.title; - } - if (date = $('.dateTime', info)) { - this.nodes.date = date; - this.info.date = new Date(date.dataset.utc * 1000); - } - if (Conf['Quick Reply']) { - this.info.yours = QR.db.get({ - boardID: this.board, - threadID: this.thread, - postID: this.ID - }); - } - this.parseComment(); - this.parseQuotes(); - this.parseFile(that); - this.clones = []; - g.posts[this.fullID] = thread.posts[this] = board.posts[this] = this; - if (that.isArchived) { - this.kill(); - } - } - - Post.prototype.parseComment = function() { - var bq, i, node, nodes, text; - - this.nodes.comment.normalize(); - bq = this.nodes.comment.cloneNode(true); - nodes = $$('.abbr, .capcodeReplies, .exif, b', bq); - i = 0; - while (node = nodes[i++]) { - $.rm(node); - } - text = ""; - nodes = $.X('.//br|.//text()', bq); - i = 0; - while (node = nodes.snapshotItem(i++)) { - text += node.data || '\n'; - } - return this.info.comment = text.trim().replace(/\s+$/gm, ''); - }; - - Post.prototype.parseQuotes = function() { - var quotelink, _i, _len, _ref; - - this.quotes = []; - _ref = $$('.quotelink', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quotelink = _ref[_i]; - this.parseQuote(quotelink); - } - }; - - Post.prototype.parseQuote = function(quotelink) { - var fullID, match; - - if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/res\/\d+#p(\d+)$/))) { - return; - } - this.nodes.quotelinks.push(quotelink); - if (this.isClone || !this.isReply && $.hasClass(quotelink.parentNode.parentNode, 'capcodeReplies')) { - return; - } - fullID = "" + match[1] + "." + match[2]; - if (!this.quotes.contains(fullID)) { - return this.quotes.push(fullID); - } - }; - - Post.prototype.parseFile = function(that) { - var alt, anchor, fileEl, fileInfo, size, thumb, unit; - - if (!((fileEl = $('.file', this.nodes.post)) && (thumb = $('img[data-md5]', fileEl)))) { - return; - } - alt = thumb.alt; - anchor = thumb.parentNode; - fileInfo = fileEl.firstElementChild; - this.file = { - info: fileInfo, - text: fileInfo.firstElementChild, - thumb: thumb, - URL: anchor.href, - size: alt.match(/[\d.]+\s\w+/)[0], - MD5: thumb.dataset.md5, - isSpoiler: $.hasClass(anchor, 'imgspoiler') - }; - size = +this.file.size.match(/[\d.]+/)[0]; - unit = ['B', 'KB', 'MB', 'GB'].indexOf(this.file.size.match(/\w+$/)[0]); - while (unit-- > 0) { - size *= 1024; - } - this.file.sizeInBytes = size; - this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//thumbs.4chan.org/" + this.board + "/thumb/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg"; - this.file.name = $('span[title]', fileInfo).title; - if (this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name)) { - return this.file.dimensions = this.file.text.textContent.match(/\d+x\d+/)[0]; - } - }; - - Post.prototype.kill = function(file, now) { - var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; - - now || (now = new Date()); - if (file) { - if (this.file.isDead) { - return; - } - this.file.isDead = true; - this.file.timeOfDeath = now; - $.addClass(this.nodes.root, 'deleted-file'); - } else { - if (this.isDead) { - return; - } - this.isDead = true; - this.timeOfDeath = now; - $.addClass(this.nodes.root, 'deleted-post'); - } - if (!(strong = $('strong.warning', this.nodes.info))) { - strong = $.el('strong', { - className: 'warning', - textContent: this.isReply ? '[Deleted]' : '[Dead]' - }); - $.after($('input', this.nodes.info), strong); - } - strong.textContent = file ? '[File deleted]' : '[Deleted]'; - if (this.isClone) { - return; - } - _ref = this.clones; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - clone = _ref[_i]; - clone.kill(file, now); - } - if (file) { - return; - } - _ref1 = Get.allQuotelinksLinkingTo(this); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - quotelink = _ref1[_j]; - if (!(!$.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.add(quotelink, $.tn('\u00A0(Dead)')); - $.addClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.resurrect = function() { - var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; - - delete this.isDead; - delete this.timeOfDeath; - $.rmClass(this.nodes.root, 'deleted-post'); - strong = $('strong.warning', this.nodes.info); - if (this.file && this.file.isDead) { - strong.textContent = '[File deleted]'; - } else { - $.rm(strong); - } - if (this.isClone) { - return; - } - _ref = this.clones; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - clone = _ref[_i]; - clone.resurrect(); - } - _ref1 = Get.allQuotelinksLinkingTo(this); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - quotelink = _ref1[_j]; - if ($.hasClass(quotelink, 'deadlink')) { - quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', ''); - $.rmClass(quotelink, 'deadlink'); - } - } - }; - - Post.prototype.addClone = function(context) { - return new Clone(this, context); - }; - - Post.prototype.rmClone = function(index) { - var clone, _i, _len, _ref; - - this.clones.splice(index, 1); - _ref = this.clones.slice(index); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - clone = _ref[_i]; - clone.nodes.root.dataset.clone = index++; - } - }; - - return Post; - - })(); - - Clone = (function(_super) { - __extends(Clone, _super); - - function Clone(origin, context) { - var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; - - this.origin = origin; - this.context = context; - _ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - this[key] = origin[key]; - } - nodes = origin.nodes; - root = nodes.root.cloneNode(true); - post = $('.post', root); - info = $('.postInfo', post); - this.nodes = { - root: root, - post: post, - info: info, - comment: $('.postMessage', post), - quotelinks: [], - backlinks: info.getElementsByClassName('backlink') - }; - _ref1 = $$('.inline', post); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - inline = _ref1[_j]; - $.rm(inline); - } - _ref2 = $$('.inlined', post); - for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { - inlined = _ref2[_k]; - $.rmClass(inlined, 'inlined'); - } - root.hidden = false; - $.rmClass(root, 'forwarded'); - $.rmClass(post, 'highlight'); - if (nodes.subject) { - this.nodes.subject = $('.subject', info); - } - if (nodes.name) { - this.nodes.name = $('.name', info); - } - if (nodes.email) { - this.nodes.email = $('.useremail', info); - } - if (nodes.tripcode) { - this.nodes.tripcode = $('.postertrip', info); - } - if (nodes.uniqueID) { - this.nodes.uniqueID = $('.posteruid', info); - } - if (nodes.capcode) { - this.nodes.capcode = $('.capcode', info); - } - if (nodes.flag) { - this.nodes.flag = $('.countryFlag', info); - } - if (nodes.date) { - this.nodes.date = $('.dateTime', info); - } - this.parseQuotes(); - if (origin.file) { - this.file = {}; - _ref3 = origin.file; - for (key in _ref3) { - val = _ref3[key]; - this.file[key] = val; - } - file = $('.file', post); - this.file.info = file.firstElementChild; - this.file.text = this.file.info.firstElementChild; - this.file.thumb = $('img[data-md5]', file); - this.file.fullImage = $('.full-image', file); - } - if (origin.isDead) { - this.isDead = true; - } - this.isClone = true; - root.dataset.clone = origin.clones.push(this) - 1; - } - - return Clone; - - })(Post); - - DataBoard = (function() { - DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads']; - - function DataBoard(key, sync, dontClean) { - var init, - _this = this; - - this.key = key; - this.onSync = __bind(this.onSync, this); - this.data = Conf[key]; - $.sync(key, this.onSync); - if (!dontClean) { - this.clean(); - } - if (!sync) { - return; - } - init = function() { - $.off(d, '4chanXInitFinished', init); - return _this.sync = sync; - }; - $.on(d, '4chanXInitFinished', init); - } - - DataBoard.prototype.save = function() { - return $.set(this.key, this.data); - }; - - DataBoard.prototype["delete"] = function(_arg) { - var boardID, postID, threadID; - - boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; - if (postID) { - delete this.data.boards[boardID][threadID][postID]; - this.deleteIfEmpty({ - boardID: boardID, - threadID: threadID - }); - } else if (threadID) { - delete this.data.boards[boardID][threadID]; - this.deleteIfEmpty({ - boardID: boardID - }); - } else { - delete this.data.boards[boardID]; - } - return this.save(); - }; - - DataBoard.prototype.deleteIfEmpty = function(_arg) { - var boardID, threadID; - - boardID = _arg.boardID, threadID = _arg.threadID; - if (threadID) { - if (!Object.keys(this.data.boards[boardID][threadID]).length) { - delete this.data.boards[boardID][threadID]; - return this.deleteIfEmpty({ - boardID: boardID - }); - } - } else if (!Object.keys(this.data.boards[boardID]).length) { - return delete this.data.boards[boardID]; - } - }; - - DataBoard.prototype.set = function(_arg) { - var boardID, postID, threadID, val, _base, _base1, _base2; - - boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val; - if (postID !== void 0) { - ((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val; - } else if (threadID !== void 0) { - ((_base2 = this.data.boards)[boardID] || (_base2[boardID] = {}))[threadID] = val; - } else { - this.data.boards[boardID] = val; - } - return this.save(); - }; - - DataBoard.prototype.get = function(_arg) { - var ID, board, boardID, defaultValue, postID, thread, threadID, val, _i, _len; - - boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, defaultValue = _arg.defaultValue; - if (board = this.data.boards[boardID]) { - if (!threadID) { - if (postID) { - for (thread = _i = 0, _len = board.length; _i < _len; thread = ++_i) { - ID = board[thread]; - if (postID in thread) { - val = thread[postID]; - break; - } - } - } else { - val = board; - } - } else if (thread = board[threadID]) { - val = postID ? thread[postID] : thread; - } - } - return val || defaultValue; - }; - - DataBoard.prototype.clean = function() { - var boardID, now, val, _ref; - - _ref = this.data.boards; - for (boardID in _ref) { - val = _ref[boardID]; - this.deleteIfEmpty({ - boardID: boardID - }); - } - now = Date.now(); - if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) { - this.data.lastChecked = now; - for (boardID in this.data.boards) { - this.ajaxClean(boardID); - } - } - return this.save(); - }; - - DataBoard.prototype.ajaxClean = function(boardID) { - var _this = this; - - return $.cache("//api.4chan.org/" + boardID + "/threads.json", function(e) { - var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1; - - if (e.target.status !== 200) { - return; - } - board = _this.data.boards[boardID]; - threads = {}; - _ref = JSON.parse(e.target.response); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - page = _ref[_i]; - _ref1 = page.threads; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - thread = _ref1[_j]; - if (thread.no in board) { - threads[thread.no] = board[thread.no]; - } - } - } - _this.data.boards[boardID] = threads; - _this.deleteIfEmpty({ - boardID: boardID - }); - return _this.save(); - }); - }; - - DataBoard.prototype.onSync = function(data) { - this.data = data || { - boards: {} - }; - return typeof this.sync === "function" ? this.sync() : void 0; - }; - - return DataBoard; - - })(); - - Notice = (function() { - function Notice(type, content, timeout) { - this.timeout = timeout; - this.close = __bind(this.close, this); - this.add = __bind(this.add, this); - this.el = $.el('div', { - innerHTML: '×
' - }); - this.el.style.opacity = 0; - this.setType(type); - $.on(this.el.firstElementChild, 'click', this.close); - if (typeof content === 'string') { - content = $.tn(content); - } - $.add(this.el.lastElementChild, content); - $.ready(this.add); - } - - Notice.prototype.setType = function(type) { - return this.el.className = "notification " + type; - }; - - Notice.prototype.add = function() { - if (d.hidden) { - $.on(d, 'visibilitychange', this.add); - return; - } - $.off(d, 'visibilitychange', this.add); - $.add($.id('notifications'), this.el); - this.el.clientHeight; - this.el.style.opacity = 1; - if (this.timeout) { - return setTimeout(this.close, this.timeout * $.SECOND); - } - }; - - Notice.prototype.close = function() { - $.off(d, 'visibilitychange', this.add); - return $.rm(this.el); - }; - - return Notice; - - })(); - - Polyfill = { - init: function() {}, - notificationPermission: function() { - if (!window.Notification || 'permission' in Notification) { - return; - } - return Object.defineProperty(Notification, 'permission', { - get: function() { - switch (webkitNotifications.checkPermission()) { - case 0: - return 'granted'; - case 1: - return 'default'; - case 2: - return 'denied'; - } - } - }); - }, - toBlob: function() { - var _base; - - return (_base = HTMLCanvasElement.prototype).toBlob || (_base.toBlob = function(cb) { - var data, i, l, ui8a, _i; - - data = atob(this.toDataURL().slice(22)); - l = data.length; - ui8a = new Uint8Array(l); - for (i = _i = 0; _i < l; i = _i += 1) { - ui8a[i] = data.charCodeAt(i); - } - return cb(new Blob([ui8a], { - type: 'image/png' - })); - }); - }, - visibility: function() { - if (!('webkitHidden' in document)) { - return; - } - Object.defineProperties(HTMLDocument.prototype, { - visibilityState: { - get: function() { - return this.webkitVisibilityState; - } - }, - hidden: { - get: function() { - return this.webkitHidden; - } - } - }); - return $.on(d, 'webkitvisibilitychange', function() { - return $.event('visibilitychange'); - }); - } - }; - - Header = { - init: function() { - var barFixedToggler, barPositionToggler, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, shortcutToggler, - _this = this; - - this.menu = new UI.Menu('header'); - menuButton = $.el('span', { - className: 'menu-button', - innerHTML: '' - }); - barFixedToggler = $.el('label', { - innerHTML: ' Fixed Header' - }); - headerToggler = $.el('label', { - innerHTML: ' Auto-hide header' - }); - barPositionToggler = $.el('label', { - innerHTML: ' Bottom header' - }); - linkJustifyToggler = $.el('label', { - innerHTML: " Centered links" - }); - customNavToggler = $.el('label', { - innerHTML: ' Custom board navigation' - }); - footerToggler = $.el('label', { - innerHTML: " Hide bottom board list" - }); - shortcutToggler = $.el('label', { - innerHTML: " Shortcut Icons" - }); - editCustomNav = $.el('a', { - textContent: 'Edit custom board navigation', - href: 'javascript:;' - }); - this.barFixedToggler = barFixedToggler.firstElementChild; - this.barPositionToggler = barPositionToggler.firstElementChild; - this.linkJustifyToggler = linkJustifyToggler.firstElementChild; - this.headerToggler = headerToggler.firstElementChild; - this.footerToggler = footerToggler.firstElementChild; - this.shortcutToggler = shortcutToggler.firstElementChild; - this.customNavToggler = customNavToggler.firstElementChild; - $.on(menuButton, 'click', this.menuToggle); - $.on(this.barFixedToggler, 'change', this.toggleBarFixed); - $.on(this.barPositionToggler, 'change', this.toggleBarPosition); - $.on(this.linkJustifyToggler, 'change', this.toggleLinkJustify); - $.on(this.headerToggler, 'change', this.toggleBarVisibility); - $.on(this.footerToggler, 'change', this.toggleFooterVisibility); - $.on(this.shortcutToggler, 'change', this.toggleShortcutIcons); - $.on(this.customNavToggler, 'change', this.toggleCustomNav); - $.on(editCustomNav, 'click', this.editCustomNav); - this.setBarFixed(Conf['Fixed Header']); - this.setBarVisibility(Conf['Header auto-hide']); - this.setLinkJustify(Conf['Centered links']); - this.setShortcutIcons(Conf['Shortcut Icons']); - $.sync('Fixed Header', Header.setBarFixed); - $.sync('Bottom Header', Header.setBarPosition); - $.sync('Shortcut Icons', Header.setShortcutIcons); - $.sync('Header auto-hide', Header.setBarVisibility); - $.sync('Centered links', Header.setLinkJustify); - this.addShortcut(menuButton); - $.event('AddMenuEntry', { - type: 'header', - el: $.el('span', { - textContent: 'Header' - }), - order: 107, - subEntries: [ - { - el: barFixedToggler - }, { - el: headerToggler - }, { - el: barPositionToggler - }, { - el: linkJustifyToggler - }, { - el: footerToggler - }, { - el: shortcutToggler - }, { - el: customNavToggler - }, { - el: editCustomNav - } - ] - }); - $.on(window, 'load hashchange', Header.hashScroll); - $.on(d, 'CreateNotification', this.createNotification); - $.asap((function() { - return d.body; - }), function() { - if (!Main.isThisPageLegit()) { - return; - } - $.asap((function() { - return $.id('boardNavMobile') || d.readyState !== 'loading'; - }), Header.setBoardList); - $.prepend(d.body, _this.bar); - $.add(d.body, Header.hover); - _this.setBarPosition(Conf['Bottom Header']); - return _this; - }); - $.ready(function() { - var a, cs; - - _this.footer = $.id('boardNavDesktopFoot'); - if (a = $("a[href*='/" + g.BOARD + "/']", $.id('boardNavDesktopFoot'))) { - a.className = 'current'; - } - cs = $.el('a', { - id: 'settingsWindowLink', - href: 'javascript:;', - textContent: 'Catalog Settings' - }); - if (g.VIEW === 'catalog') { - _this.addShortcut(cs); - } - Header.setFooterVisibility(Conf['Bottom Board List']); - return $.sync('Bottom Board List', Header.setFooterVisibility); - }); - return this.enableDesktopNotifications(); - }, - bar: $.el('div', { - id: 'header-bar' - }), - notify: $.el('div', { - id: 'notifications' - }), - shortcuts: $.el('span', { - id: 'shortcuts' - }), - hover: $.el('div', { - id: 'hoverUI' - }), - toggle: $.el('div', { - id: 'scroll-marker' - }), - setBoardList: function() { - var a, boardList, btn, fourchannav, fullBoardList; - - fourchannav = $.id('boardNavDesktop'); - if (a = $("a[href*='/" + g.BOARD + "/']", fourchannav)) { - a.className = 'current'; - } - boardList = $.el('span', { - id: 'board-list', - innerHTML: "" - }); - fullBoardList = $('#full-board-list', boardList); - btn = $('.hide-board-list-button', fullBoardList); - $.on(btn, 'click', Header.toggleBoardList); - $.rm($('#navtopright', fullBoardList)); - $.add(boardList, fullBoardList); - $.add(Header.bar, [boardList, Header.shortcuts, Header.notify, Header.toggle]); - Header.setCustomNav(Conf['Custom Board Navigation']); - Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' ')); - $.sync('Custom Board Navigation', Header.setCustomNav); - return $.sync('boardnav', Header.generateBoardList); - }, - generateBoardList: function(text) { - var as, list, nodes; - - list = $('#custom-board-list', Header.bar); - $.rmAll(list); - if (!text) { - return; - } - as = $$('#full-board-list a[title]', Header.bar); - nodes = text.match(/[\w@]+((-(all|title|replace|full|index|catalog|url:"[^"]+[^"]"|text:"[^"]+")|\,"[^"]+[^"]"))*|[^\w@]+/g).map(function(t) { - var a, board, m, _i, _len; - - if (/^[^\w@]/.test(t)) { - return $.tn(t); - } - if (/^toggle-all/.test(t)) { - a = $.el('a', { - className: 'show-board-list-button', - textContent: (t.match(/-text:"(.+)"/) || [null, '+'])[1], - href: 'javascript:;' - }); - $.on(a, 'click', Header.toggleBoardList); - return a; - } - if (/^external/.test(t)) { - a = $.el('a', { - href: (t.match(/\,"(.+)"/) || [null, '+'])[1], - textContent: (t.match(/-text:"(.+)"\,/) || [null, '+'])[1], - className: 'external' - }); - return a; - } - board = /^current/.test(t) ? g.BOARD.ID : t.match(/^[^-]+/)[0]; - for (_i = 0, _len = as.length; _i < _len; _i++) { - a = as[_i]; - if (a.textContent === board) { - a = a.cloneNode(true); - a.textContent = /-title/.test(t) || /-replace/.test(t) && $.hasClass(a, 'current') ? a.title : /-full/.test(t) ? "/" + board + "/ - " + a.title : (m = t.match(/-text:"(.+)"/)) ? m[1] : a.textContent; - if (m = t.match(/-(index|catalog)/)) { - a.dataset.only = m[1]; - a.href = "//boards.4chan.org/" + board + "/"; - if (m[1] === 'catalog') { - if (Conf['External Catalog']) { - a.href = CatalogLinks.external(board); - } else { - a.href += 'catalog'; - } - $.addClass(a, 'catalog'); - } - } - if (board === '@') { - $.addClass(a, 'navSmall'); - } - return a; - } - } - return $.tn(t); - }); - return $.add(list, nodes); - }, - toggleBoardList: function() { - var bar, custom, full, showBoardList; - - bar = Header.bar; - custom = $('#custom-board-list', bar); - full = $('#full-board-list', bar); - showBoardList = !full.hidden; - custom.hidden = !showBoardList; - return full.hidden = showBoardList; - }, - setBarPosition: function(bottom) { - Header.barPositionToggler.checked = bottom; - if (bottom) { - $.rmClass(doc, 'top'); - $.addClass(doc, 'bottom'); - return $.after(Header.bar, Header.notify); - } else { - $.rmClass(doc, 'bottom'); - $.addClass(doc, 'top'); - return $.add(Header.bar, Header.notify); - } - }, - setLinkJustify: function(centered) { - Header.linkJustifyToggler.checked = centered; - if (centered) { - return $.addClass(doc, 'centered-links'); - } else { - return $.rmClass(doc, 'centered-links'); - } - }, - toggleBarPosition: function() { - $.event('CloseMenu'); - Header.setBarPosition(this.checked); - Conf['Bottom Header'] = this.checked; - return $.set('Bottom Header', this.checked); - }, - toggleLinkJustify: function() { - var centered; - - $.event('CloseMenu'); - centered = this.nodeName === 'INPUT' ? this.checked : void 0; - Header.setLinkJustify(centered); - return $.set('Centered links', centered); - }, - setBarFixed: function(fixed) { - Header.barFixedToggler.checked = fixed; - if (fixed) { - $.addClass(doc, 'fixed'); - return $.addClass(Header.bar, 'dialog'); - } else { - $.rmClass(doc, 'fixed'); - return $.rmClass(Header.bar, 'dialog'); - } - }, - toggleBarFixed: function() { - $.event('CloseMenu'); - Header.setBarFixed(this.checked); - Conf['Fixed Header'] = this.checked; - return $.set('Fixed Header', this.checked); - }, - setShortcutIcons: function(show) { - Header.shortcutToggler.checked = show; - if (show) { - return $.addClass(doc, 'shortcut-icons'); - } else { - return $.rmClass(doc, 'shortcut-icons'); - } - }, - toggleShortcutIcons: function() { - $.event('CloseMenu'); - Header.setShortcutIcons(this.checked); - Conf['Shortcut Icons'] = this.checked; - return $.set('Shortcut Icons', this.checked); - }, - setBarVisibility: function(hide) { - Header.headerToggler.checked = hide; - $.event('CloseMenu'); - (hide ? $.addClass : $.rmClass)(Header.bar, 'autohide'); - return (hide ? $.addClass : $.rmClass)(doc, 'autohide'); - }, - toggleBarVisibility: function() { - var hide, message; - - hide = this.nodeName === 'INPUT' ? this.checked : !$.hasClass(Header.bar, 'autohide'); - this.checked = hide; - $.set('Header auto-hide', Conf['Header auto-hide'] = hide); - Header.setBarVisibility(hide); - message = "The header bar will " + (hide ? 'automatically hide itself.' : 'remain visible.'); - return new Notice('info', message, 2); - }, - setFooterVisibility: function(hide) { - Header.footerToggler.checked = hide; - return Header.footer.hidden = hide; - }, - toggleFooterVisibility: function() { - var hide, message; - - $.event('CloseMenu'); - hide = this.nodeName === 'INPUT' ? this.checked : !!Header.footer.hidden; - Header.setFooterVisibility(hide); - $.set('Bottom Board List', hide); - message = hide ? 'The bottom navigation will now be hidden.' : 'The bottom navigation will remain visible.'; - return new Notice('info', message, 2); - }, - setCustomNav: function(show) { - var btn, cust, full, _ref; - - Header.customNavToggler.checked = show; - cust = $('#custom-board-list', Header.bar); - full = $('#full-board-list', Header.bar); - btn = $('.hide-board-list-button', full); - return _ref = show ? [false, true] : [true, false], cust.hidden = _ref[0], full.hidden = _ref[1], _ref; - }, - toggleCustomNav: function() { - $.cb.checked.call(this); - return Header.setCustomNav(this.checked); - }, - editCustomNav: function() { - var settings; - - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('input[name=boardnav]', settings).focus(); - }, - hashScroll: function() { - var hash, post; - - if (!((hash = this.location.hash.slice(1)) && (post = $.id(hash)))) { - return; - } - if ((Get.postFromRoot(post)).isHidden) { - return; - } - return Header.scrollToPost(post); - }, - scrollToPost: function(post) { - var headRect, top; - - top = post.getBoundingClientRect().top; - if (Conf['Fixed Header'] && !Conf['Bottom Header']) { - headRect = Header.bar.getBoundingClientRect(); - top -= headRect.top + headRect.height; - } - return window.scrollBy(0, top); - }, - addShortcut: function(el) { - var shortcut; - - shortcut = $.el('span', { - className: 'shortcut brackets-wrap' - }); - $.add(shortcut, el); - return $.prepend(Header.shortcuts, shortcut); - }, - menuToggle: function(e) { - return Header.menu.toggle(e, this, g); - }, - createNotification: function(e) { - var cb, content, lifetime, notif, type, _ref; - - _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb; - notif = new Notice(type, content, lifetime); - if (cb) { - return cb(notif); - } - }, - areNotificationsEnabled: false, - enableDesktopNotifications: function() { - var authorize, disable, el, notice, _ref; - - if (!(window.Notification && Conf['Desktop Notifications'])) { - return; - } - switch (Notification.permission) { - case 'granted': - Header.areNotificationsEnabled = true; - return; - case 'denied': - return; - } - el = $.el('span', { - innerHTML: "Desktop notification permissions are not granted.\n[FAQ]
\n or " - }); - _ref = $$('button', el), authorize = _ref[0], disable = _ref[1]; - $.on(authorize, 'click', function() { - return Notification.requestPermission(function(status) { - Header.areNotificationsEnabled = status === 'granted'; - if (status === 'default') { - return; - } - return notice.close(); - }); - }); - $.on(disable, 'click', function() { - $.set('Desktop Notifications', false); - return notice.close(); - }); - return notice = new Notice('info', el); - } - }; - - Build = { - spoilerRange: {}, - shortFilename: function(filename, isReply) { - var threshold; - - threshold = isReply ? 30 : 40; - if (filename.length - 4 > threshold) { - return "" + filename.slice(0, threshold - 5) + "(...)." + filename.slice(-3); - } else { - return filename; - } - }, - postFromObject: function(data, boardID) { - var o; - - o = { - postID: data.no, - threadID: data.resto || data.no, - boardID: boardID, - name: data.name, - capcode: data.capcode, - tripcode: data.trip, - uniqueID: data.id, - email: data.email ? encodeURI(data.email.replace(/"/g, '"')) : '', - subject: data.sub, - flagCode: data.country, - flagName: data.country_name, - date: data.now, - dateUTC: data.time, - comment: data.com, - capcodeReplies: data.capcode_replies, - isSticky: !!data.sticky, - isClosed: !!data.closed - }; - if (data.ext || data.filedeleted) { - o.file = { - name: data.filename + data.ext, - timestamp: "" + data.tim + data.ext, - url: boardID === 'f' ? "//images.4channel.org/" + boardID + "/src/" + data.filename + data.ext : "//images.4chan.org/" + boardID + "/src/" + data.tim + data.ext, - height: data.h, - width: data.w, - MD5: data.md5, - size: data.fsize, - turl: "//thumbs.4chan.org/" + boardID + "/thumb/" + data.tim + "s.jpg", - theight: data.tn_h, - twidth: data.tn_w, - isSpoiler: !!data.spoiler, - isDeleted: !!data.filedeleted - }; - } - return Build.post(o); - }, - post: function(o, isArchived) { - /* - This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). - @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE - */ - - var a, boardID, capcode, capcodeClass, capcodeReplies, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; - - postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capcodeReplies = o.capcodeReplies, file = o.file; - isOP = postID === threadID; - staticPath = '//static.4chan.org/image/'; - if (email) { - emailStart = ''; - emailEnd = ''; - } else { - emailStart = ''; - emailEnd = ''; - } - subject = "" + (subject || '') + ""; - userID = !capcode && uniqueID ? (" (ID: ") + ("" + uniqueID + ") ") : ''; - switch (capcode) { - case 'admin': - case 'admin_highlight': - capcodeClass = " capcodeAdmin"; - capcodeStart = " ## Admin"; - capcode = (" "; - break; - case 'mod': - capcodeClass = " capcodeMod"; - capcodeStart = " ## Mod"; - capcode = (" "; - break; - case 'developer': - capcodeClass = " capcodeDeveloper"; - capcodeStart = " ## Developer"; - capcode = (" "; - break; - default: - capcodeClass = ''; - capcodeStart = ''; - capcode = ''; - } - flag = !flagCode ? '' : boardID === 'pol' ? "  + flagCode + " : " "; - if (file != null ? file.isDeleted : void 0) { - fileHTML = isOP ? ("
") + ("File deleted.") + "
" : ("
") + ("File deleted.") + "
"; - } else if (file) { - ext = file.name.slice(-3); - if (!file.twidth && !file.theight && ext === 'gif') { - file.twidth = file.width; - file.theight = file.height; - } - fileSize = $.bytesToString(file.size); - fileThumb = file.turl; - if (file.isSpoiler) { - fileSize = "Spoiler Image, " + fileSize; - if (!isArchived) { - fileThumb = "" + staticPath + "spoiler"; - if (spoilerRange = Build.spoilerRange[boardID]) { - fileThumb += ("-" + boardID) + Math.floor(1 + spoilerRange * Math.random()); - } - fileThumb += '.png'; - file.twidth = file.theight = 100; - } - } - imgSrc = boardID === 'f' ? '' : ("") + ("" + fileSize + "") + ""; - a = $.el('a', { - innerHTML: file.name - }); - filename = a.textContent.replace(/%22/g, '"'); - a.textContent = Build.shortFilename(filename); - shortFilename = a.innerHTML; - a.textContent = filename; - filename = a.innerHTML.replace(/'/g, '''); - fileDims = ext === 'pdf' ? 'PDF' : "" + file.width + "x" + file.height; - fileInfo = ("File: " + file.timestamp + "") + ("-(" + fileSize + ", " + fileDims + (file.isSpoiler ? '' : ", " + shortFilename + "")) + ")"; - fileHTML = "
" + fileInfo + "
" + imgSrc + "
"; - } else { - fileHTML = ''; - } - tripcode = tripcode ? " " + tripcode + "" : ''; - sticky = isSticky ? " Sticky" : ''; - closed = isClosed ? " Closed" : ''; - container = $.el('div', { - id: "pc" + postID, - className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", - innerHTML: "" + (isOP ? '' : "
>>
") + "
" + (isOP ? fileHTML : '') + "" + (isOP ? '' : fileHTML) + "
" + (comment || '') + "
" + " " + "
" - }); - _ref = $$('.quotelink', container); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quote = _ref[_i]; - href = quote.getAttribute('href'); - if (href[0] === '/') { - continue; - } - quote.href = "/" + boardID + "/res/" + href; - } - Build.capcodeReplies({ - boardID: boardID, - threadID: threadID, - root: container, - capcodeReplies: capcodeReplies - }); - return container; - }, - capcodeReplies: function(_arg) { - var array, boardID, bq, capcodeReplies, capcodeType, generateCapcodeReplies, html, root, threadID; - - boardID = _arg.boardID, threadID = _arg.threadID, bq = _arg.bq, root = _arg.root, capcodeReplies = _arg.capcodeReplies; - if (!capcodeReplies) { - return; - } - generateCapcodeReplies = function(capcodeType, array) { - return "" + ((function() { - switch (capcodeType) { - case 'admin': - return 'Administrator'; - case 'mod': - return 'Moderator'; - case 'developer': - return 'Developer'; - } - })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) { - return ">>" + ID + ""; - }).join(' ')) + "
"; - }; - html = []; - for (capcodeType in capcodeReplies) { - array = capcodeReplies[capcodeType]; - html.push(generateCapcodeReplies(capcodeType, array)); - } - bq || (bq = $('blockquote', root)); - return $.add(bq, [ - $.el('br'), $.el('br'), $.el('span', { - className: 'capcodeReplies', - innerHTML: html.join('') - }) - ]); - } - }; - - Get = { - threadExcerpt: function(thread) { - var OP, excerpt, _ref; - - OP = thread.OP; - excerpt = ((_ref = OP.info.subject) != null ? _ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || Conf['Anonymize'] && 'Anonymous' || $('.nameBlock', OP.nodes.info).textContent.trim(); - if (excerpt.length > 70) { - excerpt = "" + excerpt.slice(0, 67) + "..."; - } - return "/" + thread.board + "/ - " + excerpt; - }, - threadFromRoot: function(root) { - return g.threads["" + g.BOARD + "." + root.id.slice(1)]; - }, - threadFromNode: function(node) { - return Get.threadFromRoot($.x('ancestor::div[@class="thread"]', node)); - }, - postFromRoot: function(root) { - var boardID, index, link, post, postID; - - link = $('a[title="Highlight this post"]', root); - boardID = link.pathname.split('/')[1]; - postID = link.hash.slice(2); - index = root.dataset.clone; - post = g.posts["" + boardID + "." + postID]; - if (index) { - return post.clones[index]; - } else { - return post; - } - }, - postFromNode: function(root) { - return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")][1]|following::div[contains(@class,"postContainer")][1])', root)); - }, - contextFromNode: function(node) { - return Get.postFromRoot($.x('ancestor::div[parent::div[@class="thread"]][1]', node)); - }, - postDataFromLink: function(link) { - var boardID, path, postID, threadID, _ref; - - if (link.hostname === 'boards.4chan.org') { - path = link.pathname.split('/'); - boardID = path[1]; - threadID = path[3]; - postID = link.hash.slice(2); - } else { - _ref = link.dataset, boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; - threadID || (threadID = 0); - } - return { - boardID: boardID, - threadID: +threadID, - postID: +postID - }; - }, - allQuotelinksLinkingTo: function(post) { - var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; - - quotelinks = []; - _ref = g.posts; - for (ID in _ref) { - quoterPost = _ref[ID]; - if (quoterPost.quotes.contains(post.fullID)) { - _ref1 = [quoterPost].concat(quoterPost.clones); - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - quoterPost = _ref1[_i]; - quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks); - } - } - } - if (Conf['Quote Backlinks']) { - _ref2 = post.quotes; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - quote = _ref2[_j]; - if (!(quotedPost = g.posts[quote])) { - continue; - } - _ref3 = [quotedPost].concat(quotedPost.clones); - for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { - quotedPost = _ref3[_k]; - quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks)); - } - } - } - return quotelinks.filter(function(quotelink) { - var boardID, postID, _ref4; - - _ref4 = Get.postDataFromLink(quotelink), boardID = _ref4.boardID, postID = _ref4.postID; - return boardID === post.board.ID && postID === post.ID; - }); - }, - postClone: function(boardID, threadID, postID, root, context) { - var post, url; - - if (post = g.posts["" + boardID + "." + postID]) { - Get.insert(post, root, context); - return; - } - root.textContent = "Loading post No." + postID + "..."; - if (threadID) { - return $.cache("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", function() { - return Get.fetchedPost(this, boardID, threadID, postID, root, context); - }); - } else if (url = Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - return $.cache(url, function() { - return Get.archivedPost(this, boardID, postID, root, context); - }, { - withCredentials: url.archive.withCredentials - }); - } - }, - insert: function(post, root, context) { - var clone, nodes; - - if (!root.parentNode) { - return; - } - clone = post.addClone(context); - Main.callbackNodes(Clone, [clone]); - nodes = clone.nodes; - $.rmAll(nodes.root); - $.add(nodes.root, nodes.post); - $.rmAll(root); - return $.add(root, nodes.root); - }, - fetchedPost: function(req, boardID, threadID, postID, root, context) { - var board, post, posts, status, thread, url, _i, _len; - - if (post = g.posts["" + boardID + "." + postID]) { - Get.insert(post, root, context); - return; - } - status = req.status; - if (![200, 304].contains(status)) { - if (url = Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - $.cache(url, function() { - return Get.archivedPost(this, boardID, postID, root, context); - }, { - withCredentials: url.archive.withCredentials - }); - } else { - $.addClass(root, 'warning'); - root.textContent = status === 404 ? "Thread No." + threadID + " 404'd." : "Error " + req.statusText + " (" + req.status + ")."; - } - return; - } - posts = JSON.parse(req.response).posts; - Build.spoilerRange[boardID] = posts[0].custom_spoiler; - for (_i = 0, _len = posts.length; _i < _len; _i++) { - post = posts[_i]; - if (post.no === postID) { - break; - } - if (post.no > postID) { - if (url = Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - $.cache(url, function() { - return Get.archivedPost(this, boardID, postID, root, context); - }, { - withCredentials: url.archive.withCredentials - }); - } else { - $.addClass(root, 'warning'); - root.textContent = "Post No." + postID + " was not found."; - } - return; - } - } - board = g.boards[boardID] || new Board(boardID); - thread = g.threads["" + boardID + "." + threadID] || new Thread(threadID, board); - post = new Post(Build.postFromObject(post, boardID), thread, board); - Main.callbackNodes(Post, [post]); - return Get.insert(post, root, context); - }, - archivedPost: function(req, boardID, postID, root, context) { - var board, bq, comment, data, o, post, thread, threadID, _ref; - - if (post = g.posts["" + boardID + "." + postID]) { - Get.insert(post, root, context); - return; - } - data = JSON.parse(req.response); - if (data.error) { - $.addClass(root, 'warning'); - root.textContent = data.error; - return; - } - bq = $.el('blockquote', { - textContent: data.comment - }); - bq.innerHTML = bq.innerHTML.replace(/\n|\[\/?[a-z]+(:lit)?\]/g, Get.parseMarkup); - comment = bq.innerHTML.replace(/(^|>)(>[^<$]*)(<|$)/g, '$1$2$3').replace(/((>){2}(>\/[a-z\d]+\/)?\d+)/g, '$1'); - threadID = +data.thread_num; - o = { - postID: "" + postID, - threadID: "" + threadID, - boardID: boardID, - name: data.name_processed, - capcode: (function() { - switch (data.capcode) { - case 'M': - return 'mod'; - case 'A': - return 'admin'; - case 'D': - return 'developer'; - } - })(), - tripcode: data.trip, - uniqueID: data.poster_hash, - email: data.email ? encodeURI(data.email) : '', - subject: data.title_processed, - flagCode: data.poster_country, - flagName: data.poster_country_name_processed, - date: data.fourchan_date, - dateUTC: data.timestamp, - comment: comment - }; - if ((_ref = data.media) != null ? _ref.media_filename : void 0) { - o.file = { - name: data.media.media_filename_processed, - timestamp: data.media.media_orig, - url: data.media.media_link || data.media.remote_media_link, - height: data.media.media_h, - width: data.media.media_w, - MD5: data.media.media_hash, - size: data.media.media_size, - turl: data.media.thumb_link || ("//thumbs.4chan.org/" + boardID + "/thumb/" + data.media.preview_orig), - theight: data.media.preview_h, - twidth: data.media.preview_w, - isSpoiler: data.media.spoiler === '1' - }; - } - board = g.boards[boardID] || new Board(boardID); - thread = g.threads["" + boardID + "." + threadID] || new Thread(threadID, board); - post = new Post(Build.post(o, true), thread, board, { - isArchived: true - }); - Main.callbackNodes(Post, [post]); - return Get.insert(post, root, context); - }, - parseMarkup: function(text) { - switch (text) { - case '\n': - return '
'; - case '[b]': - return ''; - case '[/b]': - return ''; - case '[spoiler]': - return ''; - case '[/spoiler]': - return ''; - case '[code]': - return '
';
-        case '[/code]':
-          return '
'; - case '[moot]': - return '
'; - case '[/moot]': - return '
'; - case '[banned]': - return ''; - case '[/banned]': - return ''; - default: - return text.replace(':lit', ''); - } - } - }; - - UI = (function() { - var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; - - dialog = function(id, position, html) { - var child, el, move, _i, _len, _ref; - - el = $.el('div', { - className: 'dialog', - innerHTML: html, - id: id - }); - el.style.cssText = position; - $.get("" + id + ".position", position, function(item) { - return el.style.cssText = item["" + id + ".position"]; - }); - move = $('.move', el); - $.on(move, 'touchstart mousedown', dragstart); - _ref = move.children; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - if (!child.tagName) { - continue; - } - $.on(child, 'touchstart mousedown', function(e) { - return e.stopPropagation(); - }); - } - return el; - }; - Menu = (function() { - var currentMenu, lastToggledButton; - - currentMenu = null; - - lastToggledButton = null; - - function Menu(type) { - this.type = type; - this.addEntry = __bind(this.addEntry, this); - this.keybinds = __bind(this.keybinds, this); - this.close = __bind(this.close, this); - $.on(d, 'AddMenuEntry', this.addEntry); - this.entries = []; - } - - Menu.prototype.makeMenu = function() { - var menu; - - menu = $.el('div', { - className: 'dialog', - id: 'menu', - tabIndex: 0 - }); - $.on(menu, 'click', function(e) { - return e.stopPropagation(); - }); - $.on(menu, 'keydown', this.keybinds); - return menu; - }; - - Menu.prototype.toggle = function(e, button, data) { - var previousButton; - - e.preventDefault(); - e.stopPropagation(); - if (currentMenu) { - previousButton = lastToggledButton; - this.close(); - if (previousButton === button) { - return; - } - } - if (!this.entries.length) { - return; - } - return this.open(button, data); - }; - - Menu.prototype.open = function(button, data) { - var bLeft, bRect, bTop, bottom, cHeight, cWidth, entry, left, mRect, menu, right, style, top, _i, _len, _ref, _ref1, _ref2; - - menu = this.makeMenu(); - currentMenu = menu; - lastToggledButton = button; - this.entries.sort(function(first, second) { - return first.order - second.order; - }); - _ref = this.entries; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - entry = _ref[_i]; - this.insertEntry(entry, menu, data); - } - $.addClass(lastToggledButton, 'active'); - $.on(d, 'click', this.close); - $.on(d, 'CloseMenu', this.close); - $.add(Header.hover, menu); - mRect = menu.getBoundingClientRect(); - bRect = button.getBoundingClientRect(); - bTop = window.scrollY + bRect.top; - bLeft = window.scrollX + bRect.left; - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - _ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1]; - _ref2 = bRect.left + mRect.width < cWidth ? [bRect.left, null] : [null, cWidth - bRect.right], left = _ref2[0], right = _ref2[1]; - style = menu.style; - style.top = "" + top + "px"; - style.right = "" + right + "px"; - style.bottom = "" + bottom + "px"; - style.left = "" + left + "px"; - if (right) { - $.addClass(menu, 'left'); - } - entry = $('.entry', menu); - this.focus(entry); - return menu.focus(); - }; - - Menu.prototype.insertEntry = function(entry, parent, data) { - var subEntry, submenu, _i, _len, _ref; - - if (typeof entry.open === 'function') { - if (!entry.open(data)) { - return; - } - } - $.add(parent, entry.el); - if (!entry.subEntries) { - return; - } - if (submenu = $('.submenu', entry.el)) { - $.rm(submenu); - } - submenu = $.el('div', { - className: 'dialog submenu' - }); - _ref = entry.subEntries; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - subEntry = _ref[_i]; - this.insertEntry(subEntry, submenu, data); - } - $.add(entry.el, submenu); - }; - - Menu.prototype.close = function() { - $.rm(currentMenu); - $.rmClass(lastToggledButton, 'active'); - currentMenu = null; - lastToggledButton = null; - return $.off(d, 'click CloseMenu', this.close); - }; - - Menu.prototype.findNextEntry = function(entry, direction) { - var entries; - - entries = __slice.call(entry.parentNode.children); - entries.sort(function(first, second) { - return +(first.style.order || first.style.webkitOrder) - +(second.style.order || second.style.webkitOrder); - }); - return entries[entries.indexOf(entry) + direction]; - }; - - Menu.prototype.keybinds = function(e) { - var entry, next, nextPrev, subEntry, submenu; - - entry = $('.focused', currentMenu); - while (subEntry = $('.focused', entry)) { - entry = subEntry; - } - switch (e.keyCode) { - case 27: - lastToggledButton.focus(); - this.close(); - break; - case 13: - case 32: - entry.click(); - break; - case 38: - if (next = this.findNextEntry(entry, -1)) { - this.focus(next); - } - break; - case 40: - if (next = this.findNextEntry(entry, +1)) { - this.focus(next); - } - break; - case 39: - if ((submenu = $('.submenu', entry)) && (next = submenu.firstElementChild)) { - while (nextPrev = this.findNextEntry(next, -1)) { - next = nextPrev; - } - this.focus(next); - } - break; - case 37: - if (next = $.x('parent::*[contains(@class,"submenu")]/parent::*', entry)) { - this.focus(next); - } - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }; - - Menu.prototype.focus = function(entry) { - var bottom, cHeight, cWidth, eRect, focused, left, right, sRect, style, submenu, top, _i, _len, _ref, _ref1, _ref2; - - while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { - $.rmClass(focused, 'focused'); - } - _ref = $$('.focused', entry); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - focused = _ref[_i]; - $.rmClass(focused, 'focused'); - } - $.addClass(entry, 'focused'); - if (!(submenu = $('.submenu', entry))) { - return; - } - sRect = submenu.getBoundingClientRect(); - eRect = entry.getBoundingClientRect(); - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - _ref1 = eRect.top + sRect.height < cHeight ? ['0px', 'auto'] : ['auto', '0px'], top = _ref1[0], bottom = _ref1[1]; - _ref2 = eRect.right + sRect.width < cWidth ? ['100%', 'auto'] : ['auto', '100%'], left = _ref2[0], right = _ref2[1]; - style = submenu.style; - style.top = top; - style.bottom = bottom; - style.left = left; - return style.right = right; - }; - - Menu.prototype.addEntry = function(e) { - var entry; - - entry = e.detail; - if (entry.type !== this.type) { - return; - } - this.parseEntry(entry); - return this.entries.push(entry); - }; - - Menu.prototype.parseEntry = function(entry) { - var el, style, subEntries, subEntry, _i, _len; - - el = entry.el, subEntries = entry.subEntries; - $.addClass(el, 'entry'); - $.on(el, 'focus mouseover', (function(e) { - e.stopPropagation(); - return this.focus(el); - }).bind(this)); - style = el.style; - style.webkitOrder = style.order = entry.order || 100; - if (!subEntries) { - return; - } - $.addClass(el, 'has-submenu'); - for (_i = 0, _len = subEntries.length; _i < _len; _i++) { - subEntry = subEntries[_i]; - this.parseEntry(subEntry); - } - }; - - return Menu; - - })(); - dragstart = function(e) { - var el, isTouching, o, rect, screenHeight, screenWidth, _ref; - - if (e.type === 'mousedown' && e.button !== 0) { - return; - } - e.preventDefault(); - if (isTouching = e.type === 'touchstart') { - e = e.changedTouches[e.changedTouches.length - 1]; - } - el = $.x('ancestor::div[contains(@class,"dialog")][1]', this); - rect = el.getBoundingClientRect(); - screenHeight = doc.clientHeight; - screenWidth = doc.clientWidth; - o = { - id: el.id, - style: el.style, - dx: e.clientX - rect.left, - dy: e.clientY - rect.top, - height: screenHeight - rect.height, - width: screenWidth - rect.width, - screenHeight: screenHeight, - screenWidth: screenWidth, - isTouching: isTouching - }; - _ref = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = _ref[0], o.bottomBorder = _ref[1]; - if (isTouching) { - o.identifier = e.identifier; - o.move = touchmove.bind(o); - o.up = touchend.bind(o); - $.on(d, 'touchmove', o.move); - return $.on(d, 'touchend touchcancel', o.up); - } else { - o.move = drag.bind(o); - o.up = dragend.bind(o); - $.on(d, 'mousemove', o.move); - return $.on(d, 'mouseup', o.up); - } - }; - touchmove = function(e) { - var touch, _i, _len, _ref; - - _ref = e.changedTouches; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - touch = _ref[_i]; - if (touch.identifier === this.identifier) { - drag.call(this, touch); - return; - } - } - }; - drag = function(e) { - var bottom, clientX, clientY, left, right, style, top; - - clientX = e.clientX, clientY = e.clientY; - left = clientX - this.dx; - left = left < 10 ? 0 : this.width - left < 10 ? null : left / this.screenWidth * 100 + '%'; - top = clientY - this.dy; - top = top < (10 + this.topBorder) ? this.topBorder + 'px' : this.height - top < (10 + this.bottomBorder) ? null : top / this.screenHeight * 100 + '%'; - right = left === null ? 0 : null; - bottom = top === null ? this.bottomBorder + 'px' : null; - style = this.style; - style.left = left; - style.right = right; - style.top = top; - return style.bottom = bottom; - }; - touchend = function(e) { - var touch, _i, _len, _ref; - - _ref = e.changedTouches; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - touch = _ref[_i]; - if (touch.identifier === this.identifier) { - dragend.call(this); - return; - } - } - }; - dragend = function() { - if (this.isTouching) { - $.off(d, 'touchmove', this.move); - $.off(d, 'touchend touchcancel', this.up); - } else { - $.off(d, 'mousemove', this.move); - $.off(d, 'mouseup', this.up); - } - return $.set("" + this.id + ".position", this.style.cssText); - }; - hoverstart = function(_arg) { - var asapTest, cb, el, endEvents, latestEvent, o, root; - - root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb; - o = { - root: root, - el: el, - style: el.style, - cb: cb, - endEvents: endEvents, - latestEvent: latestEvent, - clientHeight: doc.clientHeight, - clientWidth: doc.clientWidth - }; - o.hover = hover.bind(o); - o.hoverend = hoverend.bind(o); - $.asap(function() { - return !el.parentNode || asapTest(); - }, function() { - if (el.parentNode) { - return o.hover(o.latestEvent); - } - }); - $.on(root, endEvents, o.hoverend); - if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) { - $.on(d, 'keydown', o.hoverend); - } - $.on(root, 'mousemove', o.hover); - o.workaround = function(e) { - if (!root.contains(e.target)) { - return o.hoverend(); - } - }; - return $.on(doc, 'mousemove', o.workaround); - }; - hover = function(e) { - var clientX, clientY, height, left, right, style, top, _ref; - - this.latestEvent = e; - height = this.el.offsetHeight; - clientX = e.clientX, clientY = e.clientY; - top = clientY - 120; - top = this.clientHeight <= height || top <= 0 ? 0 : top + height >= this.clientHeight ? this.clientHeight - height : top; - _ref = clientX <= this.clientWidth - 400 ? [clientX + 45 + 'px', null] : [null, this.clientWidth - clientX + 45 + 'px'], left = _ref[0], right = _ref[1]; - style = this.style; - style.top = top + 'px'; - style.left = left; - return style.right = right; - }; - hoverend = function(e) { - if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") { - return; - } - $.rm(this.el); - $.off(this.root, this.endEvents, this.hoverend); - $.off(d, 'keydown', this.hoverend); - $.off(this.root, 'mousemove', this.hover); - $.off(doc, 'mousemove', this.workaround); - if (this.cb) { - return this.cb.call(this); - } - }; - return { - dialog: dialog, - Menu: Menu, - hover: hoverstart - }; - })(); - - Anonymize = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Anonymize']) { - return; - } - return Post.prototype.callbacks.push({ - name: 'Anonymize', - cb: this.node - }); - }, - node: function() { - var email, name, tripcode, _ref; - - if (this.info.capcode || this.isClone) { - return; - } - _ref = this.nodes, name = _ref.name, tripcode = _ref.tripcode, email = _ref.email; - if (this.info.name !== 'Anonymous') { - name.textContent = 'Anonymous'; - } - if (tripcode) { - $.rm(tripcode); - delete this.nodes.tripcode; - } - if (this.info.email) { - if (/sage/i.test(this.info.email)) { - return email.href = 'mailto:sage'; - } else { - $.replace(email, name); - return delete this.nodes.email; - } - } - } - }; - - Filter = { - filters: {}, - init: function() { - var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4; - - if (g.VIEW === 'catalog' || !Conf['Filter']) { - return; - } - if (!Conf['Filtered Backlinks']) { - $.addClass(doc, 'hide-backlinks'); - } - for (key in Config.filter) { - this.filters[key] = []; - _ref = Conf[key].split('\n'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - filter = _ref[_i]; - if (filter[0] === '#') { - continue; - } - if (!(regexp = filter.match(/\/(.+)\/(\w*)/))) { - continue; - } - filter = filter.replace(regexp[0], ''); - boards = ((_ref1 = filter.match(/boards:([^;]+)/)) != null ? _ref1[1].toLowerCase() : void 0) || 'global'; - if (boards !== 'global' && !(boards.split(',')).contains(g.BOARD.ID)) { - continue; - } - if (['uniqueID', 'MD5'].contains(key)) { - regexp = regexp[1]; - } else { - try { - regexp = RegExp(regexp[1], regexp[2]); - } catch (_error) { - err = _error; - new Notice('warning', err.message, 60); - continue; - } - } - op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1] : void 0) || 'yes'; - stub = (function() { - var _ref3; - - switch ((_ref3 = filter.match(/stub:(yes|no)/)) != null ? _ref3[1] : void 0) { - case 'yes': - return true; - case 'no': - return false; - default: - return Conf['Stubs']; - } - })(); - if (hl = /highlight/.test(filter)) { - hl = ((_ref3 = filter.match(/highlight:(\w+)/)) != null ? _ref3[1] : void 0) || 'filter-highlight'; - top = ((_ref4 = filter.match(/top:(yes|no)/)) != null ? _ref4[1] : void 0) || 'yes'; - top = top === 'yes'; - } - this.filters[key].push(this.createFilter(regexp, op, stub, hl, top)); - } - if (!this.filters[key].length) { - delete this.filters[key]; - } - } - if (!Object.keys(this.filters).length) { - return; - } - return Post.prototype.callbacks.push({ - name: 'Filter', - cb: this.node - }); - }, - createFilter: function(regexp, op, stub, hl, top) { - var settings, test; - - test = typeof regexp === 'string' ? function(value) { - return regexp === value; - } : function(value) { - return regexp.test(value); - }; - settings = { - hide: !hl, - stub: stub, - "class": hl, - top: top - }; - return function(value, isReply) { - if (isReply && op === 'only' || !isReply && op === 'no') { - return false; - } - if (!test(value)) { - return false; - } - return settings; - }; - }, - node: function() { - var filter, firstThread, key, result, thisThread, value, _i, _len, _ref; - - if (this.isClone) { - return; - } - for (key in Filter.filters) { - value = Filter[key](this); - if (value === false) { - continue; - } - _ref = Filter.filters[key]; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - filter = _ref[_i]; - if (!(result = filter(value, this.isReply))) { - continue; - } - if (result.hide) { - if (this.isReply) { - PostHiding.hide(this, result.stub); - } else if (g.VIEW === 'index') { - ThreadHiding.hide(this.thread, result.stub); - } else { - continue; - } - return; - } - $.addClass(this.nodes.root, result["class"]); - if (!this.isReply && result.top && g.VIEW === 'index') { - thisThread = this.nodes.root.parentNode; - if (firstThread = $('div[class="postContainer opContainer"]')) { - if (firstThread !== this.nodes.root) { - $.before(firstThread.parentNode, [thisThread, thisThread.nextElementSibling]); - } - } - } - } - } - }, - name: function(post) { - if ('name' in post.info) { - return post.info.name; - } - return false; - }, - uniqueID: function(post) { - if ('uniqueID' in post.info) { - return post.info.uniqueID; - } - return false; - }, - tripcode: function(post) { - if ('tripcode' in post.info) { - return post.info.tripcode; - } - return false; - }, - capcode: function(post) { - if ('capcode' in post.info) { - return post.info.capcode; - } - return false; - }, - email: function(post) { - if ('email' in post.info) { - return post.info.email; - } - return false; - }, - subject: function(post) { - if ('subject' in post.info) { - return post.info.subject || false; - } - return false; - }, - comment: function(post) { - if ('comment' in post.info) { - return post.info.comment; - } - return false; - }, - flag: function(post) { - if ('flag' in post.info) { - return post.info.flag; - } - return false; - }, - filename: function(post) { - if (post.file) { - return post.file.name; - } - return false; - }, - dimensions: function(post) { - if (post.file && post.file.isImage) { - return post.file.dimensions; - } - return false; - }, - filesize: function(post) { - if (post.file) { - return post.file.size; - } - return false; - }, - MD5: function(post) { - if (post.file) { - return post.file.MD5; - } - return false; - }, - menu: { - init: function() { - var div, entry, type, _i, _len, _ref; - - if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Filter']) { - return; - } - div = $.el('div', { - textContent: 'Filter' - }); - entry = { - type: 'post', - el: div, - order: 50, - open: function(post) { - Filter.menu.post = post; - return true; - }, - subEntries: [] - }; - _ref = [['Name', 'name'], ['Unique ID', 'uniqueID'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['E-mail', 'email'], ['Subject', 'subject'], ['Comment', 'comment'], ['Flag', 'flag'], ['Filename', 'filename'], ['Image dimensions', 'dimensions'], ['Filesize', 'filesize'], ['Image MD5', 'MD5']]; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - type = _ref[_i]; - entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); - } - return $.event('AddMenuEntry', entry); - }, - createSubEntry: function(text, type) { - var el; - - el = $.el('a', { - href: 'javascript:;', - textContent: text - }); - el.dataset.type = type; - $.on(el, 'click', Filter.menu.makeFilter); - return { - el: el, - open: function(post) { - var value; - - value = Filter[type](post); - return value !== false; - } - }; - }, - makeFilter: function() { - var re, type, value; - - type = this.dataset.type; - value = Filter[type](Filter.menu.post); - re = ['uniqueID', 'MD5'].contains(type) ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { - if (c === '\n') { - return '\\n'; - } else if (c === '\\') { - return '\\\\'; - } else { - return "\\" + c; - } - }); - re = ['uniqueID', 'MD5'].contains(type) ? "/" + re + "/" : "/^" + re + "$/"; - return $.get(type, Conf[type], function(item) { - var save, section, select, ta, tl; - - save = item[type]; - save = save ? "" + save + "\n" + re : re; - $.set(type, save); - Settings.open('Filter'); - section = $('.section-container'); - select = $('select[name=filter]', section); - select.value = type; - Settings.selectFilter.call(select); - ta = $('textarea', section); - tl = ta.textLength; - ta.setSelectionRange(tl, tl); - return ta.focus(); - }); - } - } - }; - - PostHiding = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link']) { - return; - } - if (Conf['Reply Hiding Buttons']) { - $.addClass(doc, "reply-hide"); - } - this.db = new DataBoard('hiddenPosts'); - return Post.prototype.callbacks.push({ - name: 'Reply Hiding', - cb: this.node - }); - }, - node: function() { - var data; - - if (!this.isReply || this.isClone) { - return; - } - if (data = PostHiding.db.get({ - boardID: this.board.ID, - threadID: this.thread.ID, - postID: this.ID - })) { - if (data.thisPost) { - PostHiding.hide(this, data.makeStub, data.hideRecursively); - } else { - Recursive.apply(PostHiding.hide, this, data.makeStub, true); - Recursive.add(PostHiding.hide, this, data.makeStub, true); - } - } - if (!Conf['Reply Hiding Buttons']) { - return; - } - return $.replace($('.sideArrows', this.nodes.root), PostHiding.makeButton(this, 'hide')); - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub, replies, thisPost; - - if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Reply Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-reply-link', - textContent: 'Hide reply' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.hide); - thisPost = $.el('label', { - innerHTML: ' This post' - }); - replies = $.el('label', { - innerHTML: " Hide replies" - }); - makeStub = $.el('label', { - innerHTML: " Make stub" - }); - $.event('AddMenuEntry', { - type: 'post', - el: div, - order: 20, - open: function(post) { - if (!post.isReply || post.isClone || post.isHidden) { - return false; - } - PostHiding.menu.post = post; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - }, { - el: makeStub - } - ] - }); - div = $.el('div', { - className: 'show-reply-link', - textContent: 'Show reply' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.show); - thisPost = $.el('label', { - innerHTML: ' This post' - }); - replies = $.el('label', { - innerHTML: " Show replies" - }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - $.event('AddMenuEntry', { - type: 'post', - el: div, - order: 20, - open: function(post) { - var data; - - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - PostHiding.menu.post = post; - thisPost.firstChild.checked = post.isHidden; - replies.firstChild.checked = (data != null ? data.hideRecursively : void 0) != null ? data.hideRecursively : Conf['Recursive Hiding']; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - } - ] - }); - return $.event('AddMenuEntry', { - type: 'post', - el: hideStubLink, - order: 15, - open: function(post) { - var data; - - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - return PostHiding.menu.post = post; - } - }); - }, - hide: function() { - var makeStub, parent, post, replies, thisPost; - - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - makeStub = $('input[name=makeStub]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.hide(post, makeStub, replies); - } else if (replies) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } else { - return; - } - PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies); - return $.event('CloseMenu'); - }, - show: function() { - var data, parent, post, replies, thisPost; - - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.show(post, replies); - } else if (replies) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post, true); - } else { - return; - } - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies); - } - return $.event('CloseMenu'); - }, - hideStub: function() { - var post; - - post = PostHiding.menu.post; - post.nodes.root.hidden = true; - $.event('CloseMenu'); - } - }, - makeButton: function(post, type) { - var a; - - a = $.el('a', { - className: "" + type + "-reply-button", - innerHTML: " " + (type === 'hide' ? '-' : '+') + " ", - href: 'javascript:;' - }); - $.on(a, 'click', PostHiding.toggle); - return a; - }, - saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { - var data; - - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (isHiding) { - data.val = { - thisPost: thisPost !== false, - makeStub: makeStub, - hideRecursively: hideRecursively - }; - return PostHiding.db.set(data); - } else { - return PostHiding.db["delete"](data); - } - }, - toggle: function() { - var post; - - post = Get.postFromNode(this); - PostHiding[(post.isHidden ? 'show' : 'hide')](post); - return PostHiding.saveHiddenState(post, post.isHidden); - }, - hide: function(post, makeStub, hideRecursively) { - var a, button, postInfo, quotelink, _i, _len, _ref; - - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (hideRecursively == null) { - hideRecursively = Conf['Recursive Hiding']; - } - if (post.isHidden) { - return; - } - post.isHidden = true; - if (hideRecursively) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } - _ref = Get.allQuotelinksLinkingTo(post); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quotelink = _ref[_i]; - $.addClass(quotelink, 'filtered'); - } - if (!makeStub) { - post.nodes.root.hidden = true; - return; - } - a = PostHiding.makeButton(post, 'show'); - postInfo = Conf['Anonymize'] ? 'Anonymous' : post.info.name; - $.add(a, $.tn(" " + postInfo)); - post.nodes.stub = $.el('div', { - className: 'stub' - }); - $.add(post.nodes.stub, Conf['Menu'] ? [a, $.tn(' '), button = Menu.makeButton(post)] : a); - return $.prepend(post.nodes.root, post.nodes.stub); - }, - show: function(post, showRecursively) { - var quotelink, _i, _len, _ref; - - if (showRecursively == null) { - showRecursively = Conf['Recursive Hiding']; - } - if (post.nodes.stub) { - $.rm(post.nodes.stub); - delete post.nodes.stub; - } else { - post.nodes.root.hidden = false; - } - post.isHidden = false; - if (showRecursively) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post); - } - _ref = Get.allQuotelinksLinkingTo(post); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quotelink = _ref[_i]; - $.rmClass(quotelink, 'filtered'); - } - } - }; - - Recursive = { - recursives: {}, - init: function() { - if (g.VIEW === 'catalog') { - return; - } - return Post.prototype.callbacks.push({ - name: 'Recursive', - cb: this.node - }); - }, - node: function() { - var i, obj, quote, recursive, _i, _j, _len, _len1, _ref, _ref1; - - if (this.isClone) { - return; - } - _ref = this.quotes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quote = _ref[_i]; - if (obj = Recursive.recursives[quote]) { - _ref1 = obj.recursives; - for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) { - recursive = _ref1[i]; - recursive.apply(null, [this].concat(__slice.call(obj.args[i]))); - } - } - } - }, - add: function() { - var args, obj, post, recursive, _base, _name; - - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - obj = (_base = Recursive.recursives)[_name = post.fullID] || (_base[_name] = { - recursives: [], - args: [] - }); - obj.recursives.push(recursive); - return obj.args.push(args); - }, - rm: function(recursive, post) { - var i, obj, rec, _i, _len, _ref; - - if (!(obj = Recursive.recursives[post.fullID])) { - return; - } - _ref = obj.recursives; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - rec = _ref[i]; - if (rec === recursive) { - obj.recursives.splice(i, 1); - obj.args.splice(i, 1); - } - } - }, - apply: function() { - var ID, args, fullID, post, recursive, _ref; - - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; - fullID = post.fullID; - _ref = g.posts; - for (ID in _ref) { - post = _ref[ID]; - if (post.quotes.contains(fullID)) { - recursive.apply(null, [post].concat(__slice.call(args))); - } - } - } - }; - - ThreadHiding = { - init: function() { - if (g.VIEW !== 'index' || !Conf['Thread Hiding Buttons'] && !Conf['Thread Hiding Link']) { - return; - } - this.db = new DataBoard('hiddenThreads'); - this.syncCatalog(); - return Thread.prototype.callbacks.push({ - name: 'Thread Hiding', - cb: this.node - }); - }, - node: function() { - var data; - - if (data = ThreadHiding.db.get({ - boardID: this.board.ID, - threadID: this.ID - })) { - ThreadHiding.hide(this, data.makeStub); - } - if (!Conf['Thread Hiding Buttons']) { - return; - } - return $.prepend(this.OP.nodes.root, ThreadHiding.makeButton(this, 'hide')); - }, - syncCatalog: function() { - var hiddenThreads, hiddenThreadsOnCatalog, threadID; - - hiddenThreads = ThreadHiding.db.get({ - boardID: g.BOARD.ID, - defaultValue: {} - }); - hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - for (threadID in hiddenThreadsOnCatalog) { - if (!(threadID in hiddenThreads)) { - hiddenThreads[threadID] = {}; - } - } - for (threadID in hiddenThreads) { - if (!(threadID in hiddenThreadsOnCatalog)) { - delete hiddenThreads[threadID]; - } - } - if ((ThreadHiding.db.data.lastChecked || 0) > Date.now() - $.MINUTE) { - ThreadHiding.cleanCatalog(hiddenThreadsOnCatalog); - } - return ThreadHiding.db.set({ - boardID: g.BOARD.ID, - val: hiddenThreads - }); - }, - cleanCatalog: function(hiddenThreadsOnCatalog) { - return $.cache("//api.4chan.org/" + g.BOARD + "/threads.json", function() { - var page, thread, threads, _i, _j, _len, _len1, _ref, _ref1; - - if (this.status !== 200) { - return; - } - threads = {}; - _ref = JSON.parse(this.response); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - page = _ref[_i]; - _ref1 = page.threads; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - thread = _ref1[_j]; - if (thread.no in hiddenThreadsOnCatalog) { - threads[thread.no] = hiddenThreadsOnCatalog[thread.no]; - } - } - } - if (Object.keys(threads).length) { - return localStorage.setItem("4chan-hide-t-" + g.BOARD, JSON.stringify(threads)); - } else { - return localStorage.removeItem("4chan-hide-t-" + g.BOARD); - } - }); - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub; - - if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-thread-link', - textContent: 'Hide thread' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', ThreadHiding.menu.hide); - makeStub = $.el('label', { - innerHTML: " Make stub" - }); - $.event('AddMenuEntry', { - type: 'post', - el: div, - order: 20, - open: function(_arg) { - var isReply, thread; - - thread = _arg.thread, isReply = _arg.isReply; - if (isReply || thread.isHidden) { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: makeStub - } - ] - }); - div = $.el('a', { - className: 'show-thread-link', - textContent: 'Show thread', - href: 'javascript:;' - }); - $.on(div, 'click', ThreadHiding.menu.show); - $.event('AddMenuEntry', { - type: 'post', - el: div, - order: 20, - open: function(_arg) { - var isReply, thread; - - thread = _arg.thread, isReply = _arg.isReply; - if (isReply || !thread.isHidden) { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - } - }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return $.event('AddMenuEntry', { - type: 'post', - el: hideStubLink, - order: 15, - open: function(_arg) { - var isReply, thread; - - thread = _arg.thread, isReply = _arg.isReply; - if (isReply || !thread.isHidden) { - return false; - } - return ThreadHiding.menu.thread = thread; - } - }); - }, - hide: function() { - var makeStub, thread; - - makeStub = $('input', this.parentNode).checked; - thread = ThreadHiding.menu.thread; - ThreadHiding.hide(thread, makeStub); - ThreadHiding.saveHiddenState(thread, makeStub); - return $.event('CloseMenu'); - }, - show: function() { - var thread; - - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.saveHiddenState(thread); - return $.event('CloseMenu'); - }, - hideStub: function() { - var thread; - - thread = ThreadHiding.menu.thread; - ThreadHiding.hide(thread, false); - $.event('CloseMenu'); - } - }, - makeButton: function(thread, type) { - var a; - - a = $.el('a', { - className: "" + type + "-thread-button", - innerHTML: " " + (type === 'hide' ? '-' : '+') + " ", - href: 'javascript:;' - }); - a.dataset.fullID = thread.fullID; - $.on(a, 'click', ThreadHiding.toggle); - return a; - }, - saveHiddenState: function(thread, makeStub) { - var hiddenThreadsOnCatalog; - - hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - if (thread.isHidden) { - ThreadHiding.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: { - makeStub: makeStub - } - }); - hiddenThreadsOnCatalog[thread] = true; - } else { - ThreadHiding.db["delete"]({ - boardID: thread.board.ID, - threadID: thread.ID - }); - delete hiddenThreadsOnCatalog[thread]; - } - return localStorage.setItem("4chan-hide-t-" + g.BOARD, JSON.stringify(hiddenThreadsOnCatalog)); - }, - toggle: function(thread) { - if (!(thread instanceof Thread)) { - thread = g.threads[this.dataset.fullID]; - } - if (thread.isHidden) { - ThreadHiding.show(thread); - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - hide: function(thread, makeStub) { - var OP, a, numReplies, opInfo, span, threadRoot; - - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - OP = thread.OP; - threadRoot = OP.nodes.root.parentNode; - thread.isHidden = true; - if (!makeStub) { - threadRoot.hidden = threadRoot.nextElementSibling.hidden = true; - return; - } - numReplies = ((span = $('.summary', threadRoot)) ? +span.textContent.match(/\d+/) : 0) + $$('.opContainer ~ .replyContainer', threadRoot).length; - numReplies = numReplies === 1 ? '1 reply' : "" + (numReplies || 'No') + " replies"; - opInfo = Conf['Anonymize'] ? 'Anonymous' : OP.info.name; - a = ThreadHiding.makeButton(thread, 'show'); - $.add(a, $.tn(" " + opInfo + " (" + numReplies + ")")); - thread.stub = $.el('div', { - className: 'stub' - }); - $.add(thread.stub, Conf['Menu'] ? [a, $.tn(' '), Menu.makeButton()] : a); - return $.prepend(threadRoot, thread.stub); - }, - show: function(thread) { - var threadRoot; - - if (thread.stub) { - $.rm(thread.stub); - delete thread.stub; - } - threadRoot = thread.OP.nodes.root.parentNode; - return threadRoot.nextElementSibling.hidden = threadRoot.hidden = thread.isHidden = false; - } - }; - - QuoteBacklink = { - init: function() { - var format; - - if (g.VIEW === 'catalog' || !Conf['Quote Backlinks']) { - return; - } - format = Conf['backlink'].replace(/%id/g, "' + id + '"); - this.funk = Function('id', "return '" + format + "'"); - this.containers = {}; - Post.prototype.callbacks.push({ - name: 'Quote Backlinking Part 1', - cb: this.firstNode - }); - return Post.prototype.callbacks.push({ - name: 'Quote Backlinking Part 2', - cb: this.secondNode - }); - }, - firstNode: function() { - var a, clone, container, containers, frag, link, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; - - if (this.isClone || !this.quotes.length) { - return; - } - a = $.el('a', { - href: "/" + this.board + "/res/" + this.thread + "#p" + this, - className: this.isHidden ? 'filtered backlink' : 'backlink', - textContent: (QuoteBacklink.funk(this.ID)) + (Conf['Mark Quotes of You'] && this.info.yours ? '\u00A0(You)' : '') - }); - _ref = this.quotes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quote = _ref[_i]; - containers = [QuoteBacklink.getContainer(quote)]; - if ((post = g.posts[quote]) && post.nodes.backlinkContainer) { - _ref1 = post.clones; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - clone = _ref1[_j]; - containers.push(clone.nodes.backlinkContainer); - } - } - for (_k = 0, _len2 = containers.length; _k < _len2; _k++) { - container = containers[_k]; - frag = [$.tn(' '), link = a.cloneNode(true)]; - if (Conf['Quote Previewing']) { - $.on(link, 'mouseover', QuotePreview.mouseover); - } - if (Conf['Quote Inlining']) { - $.on(link, 'click', QuoteInline.toggle); - if (Conf['Quote Hash Navigation']) { - frag.push.apply(frag, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); - } - } - $.add(container, frag); - } - } - }, - secondNode: function() { - var container; - - if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { - this.nodes.backlinkContainer = $('.container', this.nodes.info); - return; - } - if (!(this.isReply || Conf['OP Backlinks'])) { - return; - } - container = QuoteBacklink.getContainer(this.fullID); - this.nodes.backlinkContainer = container; - return $.add(this.nodes.info, container); - }, - getContainer: function(id) { - var _base; - - return (_base = this.containers)[id] || (_base[id] = $.el('span', { - className: 'container' - })); - } - }; - - QuoteCT = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Mark Cross-thread Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.text = '\u00A0(Cross-thread)'; - return Post.prototype.callbacks.push({ - name: 'Mark Cross-thread Quotes', - cb: this.node - }); - }, - node: function() { - var board, boardID, quotelink, thread, threadID, _i, _len, _ref, _ref1, _ref2; - - if (this.isClone && this.thread === this.context.thread) { - return; - } - _ref = this.isClone ? this.context : this, board = _ref.board, thread = _ref.thread; - _ref1 = this.nodes.quotelinks; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - quotelink = _ref1[_i]; - _ref2 = Get.postDataFromLink(quotelink), boardID = _ref2.boardID, threadID = _ref2.threadID; - if (!threadID) { - continue; - } - if (this.isClone) { - quotelink.textContent = quotelink.textContent.replace(QuoteCT.text, ''); - } - if (boardID === board.ID && threadID !== thread.ID) { - $.add(quotelink, $.tn(QuoteCT.text)); - } - } - } - }; - - QuoteInline = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) { - return; - } - if (Conf['Quote Hash Navigation']) { - this.node = function() { - var link, _i, _len, _ref; - - _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - if (!this.isClone) { - $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); - } - $.on(link, 'click', QuoteInline.toggle); - } - }; - } else { - this.node = function() { - var link, _i, _len, _ref; - - _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - $.on(link, 'click', QuoteInline.toggle); - } - }; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Post.prototype.callbacks.push({ - name: 'Quote Inlining', - cb: this.node - }); - }, - qiQuote: function(link, hidden) { - return [ - $.tn(' '), $.el('a', { - className: hidden ? 'hashlink filtered' : 'hashlink', - textContent: '#', - href: link.href - }) - ]; - }, - toggle: function(e) { - var boardID, context, postID, threadID, _ref; - - if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { - return; - } - e.preventDefault(); - _ref = Get.postDataFromLink(this), boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; - context = Get.contextFromNode(this); - if ($.hasClass(this, 'inlined')) { - QuoteInline.rm(this, boardID, threadID, postID, context); - } else { - if ($.x("ancestor::div[@id='p" + postID + "']", this)) { - return; - } - QuoteInline.add(this, boardID, threadID, postID, context); - } - return this.classList.toggle('inlined'); - }, - findRoot: function(quotelink, isBacklink) { - if (isBacklink) { - return quotelink.parentNode.parentNode; - } else { - return $.x('ancestor-or-self::*[parent::blockquote][1]', quotelink); - } - }, - add: function(quotelink, boardID, threadID, postID, context) { - var inline, isBacklink, post, qroot, root; - - isBacklink = $.hasClass(quotelink, 'backlink'); - inline = $.el('div', { - id: "i" + postID, - className: 'inline' - }); - root = QuoteInline.findRoot(quotelink, isBacklink); - $.after(root, inline); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - $.addClass(qroot, 'hasInline'); - Get.postClone(boardID, threadID, postID, inline, context); - if (!((post = g.posts["" + boardID + "." + postID]) && context.thread === post.thread)) { - return; - } - if (isBacklink && Conf['Forward Hiding']) { - $.addClass(post.nodes.root, 'forwarded'); - post.forwarded++ || (post.forwarded = 1); - } - if (!Unread.posts) { - return; - } - return Unread.readSinglePost(post); - }, - rm: function(quotelink, boardID, threadID, postID, context) { - var el, inlined, isBacklink, post, qroot, root, _ref; - - isBacklink = $.hasClass(quotelink, 'backlink'); - root = QuoteInline.findRoot(quotelink, isBacklink); - root = $.x("following-sibling::div[@id='i" + postID + "'][1]", root); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - $.rm(root); - if (!$('.inline', qroot)) { - $.rmClass(qroot, 'hasInline'); - } - if (!(el = root.firstElementChild)) { - return; - } - post = g.posts["" + boardID + "." + postID]; - post.rmClone(el.dataset.clone); - if (Conf['Forward Hiding'] && isBacklink && context.thread === g.threads["" + boardID + "." + threadID] && !--post.forwarded) { - delete post.forwarded; - $.rmClass(post.nodes.root, 'forwarded'); - } - while (inlined = $('.inlined', el)) { - _ref = Get.postDataFromLink(inlined), boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; - QuoteInline.rm(inlined, boardID, threadID, postID, context); - $.rmClass(inlined, 'inlined'); - } - } - }; - - QuoteOP = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Mark OP Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.text = '\u00A0(OP)'; - return Post.prototype.callbacks.push({ - name: 'Mark OP Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref; - - if (this.isClone && this.thread === this.context.thread) { - return; - } - if (!(quotes = this.quotes).length) { - return; - } - quotelinks = this.nodes.quotelinks; - if (this.isClone && quotes.contains(this.thread.fullID)) { - i = 0; - while (quotelink = quotelinks[i++]) { - quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, ''); - } - } - fullID = (this.isClone ? this.context : this).thread.fullID; - if (!quotes.contains(fullID)) { - return; - } - i = 0; - while (quotelink = quotelinks[i++]) { - _ref = Get.postDataFromLink(quotelink), boardID = _ref.boardID, postID = _ref.postID; - if (("" + boardID + "." + postID) === fullID) { - $.add(quotelink, $.tn(QuoteOP.text)); - } - } - } - }; - - QuotePreview = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Quote Previewing']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Post.prototype.callbacks.push({ - name: 'Quote Previewing', - cb: this.node - }); - }, - node: function() { - var link, _i, _len, _ref; - - _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - $.on(link, 'mouseover', QuotePreview.mouseover); - } - }, - mouseover: function(e) { - var boardID, clone, origin, post, postID, posts, qp, quote, quoterID, threadID, _i, _j, _len, _len1, _ref, _ref1; - - if ($.hasClass(this, 'inlined')) { - return; - } - _ref = Get.postDataFromLink(this), boardID = _ref.boardID, threadID = _ref.threadID, postID = _ref.postID; - qp = $.el('div', { - id: 'qp', - className: 'dialog' - }); - $.add(Header.hover, qp); - Get.postClone(boardID, threadID, postID, qp, Get.contextFromNode(this)); - UI.hover({ - root: this, - el: qp, - latestEvent: e, - endEvents: 'mouseout click', - cb: QuotePreview.mouseout, - asapTest: function() { - return qp.firstElementChild; - } - }); - if (!(origin = g.posts["" + boardID + "." + postID])) { - return; - } - if (Conf['Quote Highlighting']) { - posts = [origin].concat(origin.clones); - posts.pop(); - for (_i = 0, _len = posts.length; _i < _len; _i++) { - post = posts[_i]; - $.addClass(post.nodes.post, 'qphl'); - } - } - quoterID = $.x('ancestor::*[@id][1]', this).id.match(/\d+$/)[0]; - clone = Get.postFromRoot(qp.firstChild); - _ref1 = clone.nodes.quotelinks.concat(__slice.call(clone.nodes.backlinks)); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - quote = _ref1[_j]; - if (quote.hash.slice(2) === quoterID) { - $.addClass(quote, 'forwardlink'); - } - } - }, - mouseout: function() { - var clone, post, root, _i, _len, _ref; - - if (!(root = this.el.firstElementChild)) { - return; - } - clone = Get.postFromRoot(root); - post = clone.origin; - post.rmClone(root.dataset.clone); - if (!Conf['Quote Highlighting']) { - return; - } - _ref = [post].concat(post.clones); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - post = _ref[_i]; - $.rmClass(post.nodes.post, 'qphl'); - } - } - }; - - QuoteStrikeThrough = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) { - return; - } - return Post.prototype.callbacks.push({ - name: 'Strike-through Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, postID, quotelink, _i, _len, _ref, _ref1, _ref2; - - if (this.isClone) { - return; - } - _ref = this.nodes.quotelinks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quotelink = _ref[_i]; - _ref1 = Get.postDataFromLink(quotelink), boardID = _ref1.boardID, postID = _ref1.postID; - if ((_ref2 = g.posts["" + boardID + "." + postID]) != null ? _ref2.isHidden : void 0) { - $.addClass(quotelink, 'filtered'); - } - } - } - }; - - /* - <3 aeosynth - */ - - - QuoteThreading = { - init: function() { - var input; - - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - this.enabled = true; - this.controls = $.el('span', { - innerHTML: '' - }); - input = $('input', this.controls); - $.on(input, 'change', QuoteThreading.toggle); - $.event('AddMenuEntry', { - type: 'header', - el: this.controls, - order: 98 - }); - $.on(d, '4chanXInitFinished', this.setup); - return Post.prototype.callbacks.push({ - name: 'Quote Threading', - cb: this.node - }); - }, - setup: function() { - var ID, post, posts; - - $.off(d, '4chanXInitFinished', QuoteThreading.setup); - posts = g.posts; - for (ID in posts) { - post = posts[ID]; - if (post.cb) { - post.cb.call(post); - } - } - return QuoteThreading.hasRun = true; - }, - node: function() { - var ID, fullID, keys, len, post, posts, qid, quote, quotes, uniq, _i, _len; - - if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { - return; - } - quotes = this.quotes, ID = this.ID, fullID = this.fullID; - posts = g.posts; - if (!(post = posts[fullID]) || post.isHidden) { - return; - } - uniq = {}; - len = ("" + g.BOARD).length + 1; - for (_i = 0, _len = quotes.length; _i < _len; _i++) { - quote = quotes[_i]; - qid = quote; - if (!(qid.slice(len) < ID)) { - continue; - } - if (qid in posts) { - uniq[qid.slice(len)] = true; - } - } - keys = Object.keys(uniq); - if (keys.length !== 1) { - return; - } - this.threaded = "" + g.BOARD + "." + keys[0]; - return this.cb = QuoteThreading.nodeinsert; - }, - nodeinsert: function() { - var bottom, height, qpost, qroot, threadContainer, top, _ref; - - qpost = g.posts[this.threaded]; - delete this.threaded; - delete this.cb; - if (this.thread.OP === qpost) { - return false; - } - if (QuoteThreading.hasRun) { - height = doc.clientHeight; - _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(Unread.posts.contains(qpost) || ((bottom < height) && (top > 0)))) { - return false; - } - } - qroot = qpost.nodes.root; - if (!$.hasClass(qroot, 'threadOP')) { - $.addClass(qroot, 'threadOP'); - threadContainer = $.el('div', { - className: 'threadContainer' - }); - $.after(qroot, threadContainer); - } else { - threadContainer = qroot.nextSibling; - } - $.add(threadContainer, this.nodes.root); - return true; - }, - toggle: function() { - var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; - - thread = $('.thread'); - replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); - QuoteThreading.enabled = this.checked; - if (this.checked) { - QuoteThreading.hasRun = false; - for (_i = 0, _len = replies.length; _i < _len; _i++) { - reply = replies[_i]; - QuoteThreading.node.call(node = Get.postFromRoot(reply)); - if (node.cb) { - node.cb(); - } - } - QuoteThreading.hasRun = true; - } else { - replies.sort(function(a, b) { - var aID, bID; - - aID = Number(a.id.slice(2)); - bID = Number(b.id.slice(2)); - return aID - bID; - }); - $.add(thread, replies); - containers = $$('.threadContainer', thread); - for (_j = 0, _len1 = containers.length; _j < _len1; _j++) { - container = containers[_j]; - $.rm(container); - } - _ref = $$('.threadOP'); - for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) { - post = _ref[_k]; - $.rmClass(post, 'threadOP'); - } - } - return Unread.update(true); - }, - kb: function() { - var control; - - control = $.id('threadingControl'); - return control.click(); - } - }; - - QuoteYou = { - init: function() { - if (!(g.VIEW !== 'catalog' && Conf['Mark Quotes of You'] && Conf['Quick Reply'])) { - return; - } - if (Conf['Highlight Own Posts']) { - $.addClass(doc, 'highlight-own'); - } - if (Conf['Highlight Posts Quoting You']) { - $.addClass(doc, 'highlight-you'); - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Post.prototype.callbacks.push({ - name: 'Mark Quotes of You', - cb: this.node - }); - }, - node: function() { - var quotelink, _i, _len, _ref; - - if (this.isClone) { - return; - } - if (this.info.yours) { - $.addClass(this.nodes.root, 'yourPost'); - } - if (!this.quotes.length) { - return; - } - _ref = this.nodes.quotelinks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quotelink = _ref[_i]; - if (!(QR.db.get(Get.postDataFromLink(quotelink)))) { - continue; - } - $.add(quotelink, $.tn('\u00A0(You)')); - $.addClass(quotelink, 'you'); - $.addClass(this.nodes.root, 'quotesYou'); - } - }, - cb: { - seek: function(type) { - var highlight, post, posts, result, str; - - if (!(Conf['Mark Quotes of You'] && Conf['Quick Reply'])) { - return; - } - if (highlight = $('.highlight')) { - $.rmClass(highlight, 'highlight'); - } - if (!QuoteYou.lastRead) { - if (!(post = QuoteYou.lastRead = $('.quotesYou'))) { - new Notice('warning', 'No posts are currently quoting you, loser.', 20); - return; - } - if (QuoteYou.cb.scroll(post)) { - return; - } - } else { - post = QuoteYou.lastRead; - } - str = "" + type + "::div[contains(@class,'quotesYou')]"; - while (post = (result = $.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0)) { - if (QuoteYou.cb.scroll(post)) { - return; - } - } - posts = $$('.quotesYou'); - return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]); - }, - scroll: function(post) { - if (Get.postFromRoot(post).isHidden) { - return false; - } else { - QuoteYou.lastRead = post; - window.location = "#" + post.id; - Header.scrollToPost(post); - $.addClass($('.post', post), 'highlight'); - return true; - } - } - } - }; - - Quotify = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Resurrect Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Post.prototype.callbacks.push({ - name: 'Resurrect Quotes', - cb: this.node - }); - }, - node: function() { - var deadlink, _i, _len, _ref; - - _ref = $$('.deadlink', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - deadlink = _ref[_i]; - if (this.isClone) { - if ($.hasClass(deadlink, 'quotelink')) { - this.nodes.quotelinks.push(deadlink); - } - } else { - Quotify.parseDeadlink.call(this, deadlink); - } - } - }, - parseDeadlink: function(deadlink) { - var a, boardID, m, post, postID, quote, quoteID, redirect, _ref; - - if ($.hasClass(deadlink.parentNode, 'prettyprint')) { - Quotify.fixDeadlink(deadlink); - return; - } - quote = deadlink.textContent; - if (!(postID = (_ref = quote.match(/\d+$/)) != null ? _ref[0] : void 0)) { - return; - } - if (postID[0] === '0') { - Quotify.fixDeadlink(deadlink); - return; - } - boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID; - quoteID = "" + boardID + "." + postID; - if (post = g.posts[quoteID]) { - if (!post.isDead) { - a = $.el('a', { - href: "/" + boardID + "/res/" + post.thread + "#p" + postID, - className: 'quotelink', - textContent: quote - }); - } else { - a = $.el('a', { - href: "/" + boardID + "/res/" + post.thread + "#p" + postID, - className: 'quotelink deadlink', - target: '_blank', - textContent: "" + quote + "\u00A0(Dead)" - }); - $.extend(a.dataset, { - boardID: boardID, - threadID: post.thread.ID, - postID: postID - }); - } - } else if (redirect = Redirect.to('thread', { - boardID: boardID, - threadID: 0, - postID: postID - })) { - a = $.el('a', { - href: redirect, - className: 'deadlink', - target: '_blank', - textContent: "" + quote + "\u00A0(Dead)" - }); - if (Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - $.addClass(a, 'quotelink'); - $.extend(a.dataset, { - boardID: boardID, - postID: postID - }); - } - } - if (!this.quotes.contains(quoteID)) { - this.quotes.push(quoteID); - } - if (!a) { - deadlink.textContent = "" + quote + "\u00A0(Dead)"; - return; - } - $.replace(deadlink, a); - if ($.hasClass(a, 'quotelink')) { - return this.nodes.quotelinks.push(a); - } - }, - fixDeadlink: function(deadlink) { - return $.replace(deadlink, __slice.call(deadlink.childNodes)); - } - }; - - Linkify = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Linkify']) { - return; - } - this.regString = /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/])|[-a-z\d]+[.](aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|[a-z]{2})(\/|(?!.))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i; - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - if (Conf['Title Link']) { - $.sync('CachedTitles', Linkify.titleSync); - } - return Post.prototype.callbacks.push({ - name: 'Linkify', - cb: this.node - }); - }, - node: function() { - var data, el, end, endNode, i, index, items, length, link, links, node, result, saved, snapshot, space, test, word, _i, _len, _ref; - - if (this.isClone) { - if (Conf['Embedding']) { - i = 0; - items = $$('.embed', this.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Linkify.cb.toggle); - if ($.hasClass(el, 'embedded')) { - Linkify.cb.toggle.call(el); - } - } - } - return; - } - test = /[^\s'"]+/g; - space = /[\s'"]/; - snapshot = $.X('.//br|.//text()', this.nodes.comment); - i = 0; - links = []; - while (node = snapshot.snapshotItem(i++)) { - data = node.data; - if (node.parentElement.nodeName === "A" || !data) { - continue; - } - while (result = test.exec(data)) { - index = result.index; - endNode = node; - word = result[0]; - if ((length = index + word.length) === data.length) { - test.lastIndex = 0; - while ((saved = snapshot.snapshotItem(i++))) { - if (saved.nodeName === 'BR') { - break; - } - endNode = saved; - data = saved.data; - word += data; - length = data.length; - if (end = space.exec(data)) { - test.lastIndex = length = end.index; - i--; - break; - } - } - } - if (Linkify.regString.exec(word)) { - links.push(Linkify.makeRange(node, endNode, index, length)); - } - if (!(test.lastIndex && node === endNode)) { - break; - } - } - } - _ref = links.reverse(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - this.nodes.links.push(Linkify.makeLink(link, this)); - link.detach(); - } - if (!(Conf['Embedding'] || Conf['Link Title'])) { - return; - } - links = this.nodes.links; - i = 0; - while (link = links[i++]) { - if (data = Linkify.services(link)) { - if (Conf['Embedding']) { - Linkify.embed(data); - } - if (Conf['Link Title']) { - Linkify.title(data); - } - } - } - }, - makeRange: function(startNode, endNode, startOffset, endOffset) { - var range; - - range = document.createRange(); - range.setStart(startNode, startOffset); - range.setEnd(endNode, endOffset); - return range; - }, - makeLink: function(range) { - var a, char, i, text; - - text = range.toString(); - i = 0; - while (/[(\[{<>]/.test(text.charAt(i))) { - i++; - } - if (i) { - text = text.slice(i); - while (range.startOffset + i >= range.startContainer.data.length) { - i--; - } - if (i) { - range.setStart(range.startContainer, range.startOffset + i); - } - } - i = 0; - while (/[)\]}>.,]/.test(char = text.charAt(text.length - (1 + i)))) { - if (!(/[.,]/.test(char) || (text.match(/[()\[\]{}<>]/g)).length % 2)) { - break; - } - i++; - } - if (i) { - text = text.slice(0, -i); - while (range.endOffset - i < 0) { - i--; - } - if (i) { - range.setEnd(range.endContainer, range.endOffset - i); - } - } - if (!/(https?|mailto|git|magnet|ftp|irc):/.test(text)) { - text = (/@/.test(text) ? 'mailto:' : 'http://') + text; - } - a = $.el('a', { - className: 'linkify', - rel: 'nofollow noreferrer', - target: '_blank', - href: text - }); - $.add(a, range.extractContents()); - range.insertNode(a); - return a; - }, - services: function(link) { - var href, key, match, type, _ref; - - href = link.href; - _ref = Linkify.types; - for (key in _ref) { - type = _ref[key]; - if (!(match = type.regExp.exec(href))) { - continue; - } - return [key, match[1], match[2], link]; - } - }, - embed: function(data) { - var embed, href, key, link, name, options, uid, value, _ref; - - key = data[0], uid = data[1], options = data[2], link = data[3]; - href = link.href; - embed = $.el('a', { - className: 'embedder', - href: 'javascript:;', - textContent: '(embed)' - }); - _ref = { - key: key, - href: href, - uid: uid, - options: options - }; - for (name in _ref) { - value = _ref[name]; - embed.dataset[name] = value; - } - embed.dataset.nodedata = link.innerHTML; - $.addClass(link, "" + embed.dataset.key); - $.on(embed, 'click', Linkify.cb.toggle); - $.after(link, [$.tn(' '), embed]); - if (Conf['Auto-embed']) { - Linkify.cb.toggle.call(embed); - } - data.push(embed); - }, - title: function(data) { - var embed, err, key, link, options, service, title, titles, uid; - - key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; - if (!(service = Linkify.types[key].title)) { - return; - } - titles = Conf['CachedTitles']; - if (title = titles[uid]) { - if (link) { - link.textContent = title[0]; - } - if (Conf['Embedding']) { - return embed.dataset.title = title[0]; - } - } else { - try { - $.cache(service.api(uid), function() { - return title = Linkify.cb.title(this, data); - }); - } catch (_error) { - err = _error; - if (link) { - link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; - } - return; - } - if (title) { - titles[uid] = [title, Date.now()]; - return $.set('CachedTitles', titles); - } - } - }, - titleSync: function(value) { - return Conf['CachedTitles'] = value; - }, - cb: { - toggle: function() { - var string, _ref; - - _ref = $.hasClass(this, "embedded") ? ['unembed', '(embed)'] : ['embed', '(unembed)'], string = _ref[0], this.textContent = _ref[1]; - $.replace(this.previousElementSibling, Linkify.cb[string](this)); - return $.toggleClass(this, 'embedded'); - }, - embed: function(a) { - var el, style, type; - - el = (type = Linkify.types[a.dataset.key]).el(a); - el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px"; - return el; - }, - unembed: function(a) { - var el; - - el = $.el('a', { - rel: 'nofollow noreferrer', - target: 'blank', - className: 'linkify', - href: a.dataset.href, - innerHTML: a.dataset.title || a.dataset.nodedata - }); - $.addClass(el, a.dataset.key); - return el; - }, - title: function(response, data) { - var embed, key, link, options, service, text, uid; - - key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; - service = Linkify.types[key].title; - switch (response.status) { - case 200: - case 304: - text = "" + (service.text(JSON.parse(response.responseText))); - if (Conf['Embedding']) { - embed.dataset.title = text; - } - break; - case 404: - text = "[" + key + "] Not Found"; - break; - case 403: - text = "[" + key + "] Forbidden or Private"; - break; - default: - text = "[" + key + "] " + this.status + "'d"; - } - if (link) { - return link.textContent = text; - } - } - }, - types: { - audio: { - regExp: /(.*\.(mp3|ogg|wav))$/, - el: function(a) { - return $.el('audio', { - controls: 'controls', - preload: 'auto', - src: a.dataset.uid - }); - } - }, - gist: { - regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/, - el: function(a) { - var div; - - return div = $.el('iframe', { - src: "http://www.purplegene.com/script?url=https://gist.github.com/" + a.dataset.uid + ".js" - }); - }, - title: { - api: function(uid) { - return "https://api.github.com/gists/" + uid; - }, - text: function(_arg) { - var file, files; - - files = _arg.files; - for (file in files) { - if (files.hasOwnProperty(file)) { - return file; - } - } - } - } - }, - image: { - regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, - style: 'border: 0; width: auto; height: auto;', - el: function(a) { - return $.el('div', { - innerHTML: "" - }); - } - }, - InstallGentoo: { - regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/, - el: function(a) { - return $.el('iframe', { - src: "http://paste.installgentoo.com/view/embed/" + a.dataset.uid - }); - } - }, - LiveLeak: { - regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, - el: function(a) { - return $.el('object', { - innerHTML: "" - }); - } - }, - MediaCrush: { - regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i, - style: 'border: 0; width: 640px; height: 480px; resize: both;', - el: function(a) { - return $.el('iframe', { - src: "https://mediacru.sh/" + a.dataset.uid - }); - } - }, - pastebin: { - regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, - el: function(a) { - var div; - - return div = $.el('iframe', { - src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid - }); - } - }, - SoundCloud: { - regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, - style: 'height: auto; width: 500px; display: inline-block;', - el: function(a) { - var div; - - div = $.el('div', { - className: "soundcloud", - name: "soundcloud" - }); - $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + a.dataset.uid, { - onloadend: function() { - return div.innerHTML = JSON.parse(this.responseText).html; - } - }, false); - return div; - }, - title: { - api: function(uid) { - return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, - TwitchTV: { - regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/, - style: "border: none; width: 640px; height: 360px;", - el: function(a) { - var channel, chapter, result, _; - - if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(a.dataset.uid)) { - _ = result[0], channel = result[1], chapter = result[2]; - return $.el('object', { - data: 'http://www.twitch.tv/widgets/archive_embed_player.swf', - innerHTML: "\n" - }); - } else { - channel = (/(\w+)/.exec(a.dataset.uid))[0]; - return $.el('object', { - data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel, - innerHTML: "\n\n" - }); - } - } - }, - Vocaroo: { - regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, - style: 'border: 0; width: 150px; height: 45px;', - el: function(a) { - return $.el('object', { - innerHTML: "" - }); - } - }, - Vimeo: { - regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, - el: function(a) { - return $.el('iframe', { - src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, - Vine: { - regExp: /.*(?:vine.co\/)([^#\&\?]*).*/, - style: 'border: none; width: 500px; height: 500px;', - el: function(a) { - return $.el('iframe', { - src: "https://vine.co/" + a.dataset.uid + "/card" - }); - } - }, - YouTube: { - regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, - el: function(a) { - return $.el('iframe', { - src: "//www.youtube.com/embed/" + a.dataset.uid + (a.dataset.option ? '#' + a.dataset.option : '') + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; - }, - text: function(data) { - return data.entry.title.$t; - } - } - } - } - }; - - QR = { - init: function() { - var sc; - - if (!Conf['Quick Reply']) { - return; - } - this.db = new DataBoard('yourPosts'); - if (Conf['QR Shortcut']) { - sc = $.el('a', { - className: "qr-shortcut fourchanx-icon icon-comment " + (!Conf['Persistent QR'] ? 'disabled' : ''), - textContent: 'QR', - title: 'Quick Reply', - href: 'javascript:;' - }); - $.on(sc, 'click', function() { - if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { - $.event('CloseMenu'); - QR.open(); - QR.nodes.com.focus(); - return $.rmClass(this, 'disabled'); - } else { - QR.close(); - return $.addClass(this, 'disabled'); - } - }); - Header.addShortcut(sc); - } - if (Conf['Hide Original Post Form']) { - $.asap((function() { - return doc; - }), function() { - return $.addClass(doc, 'hide-original-post-form'); - }); - } - $.ready(this.initReady); - if (Conf['Persistent QR']) { - if (!(g.BOARD.ID === 'f' && g.VIEW === 'index')) { - $.on(d, '4chanXInitFinished', this.persist); - } else { - $.ready(this.persist); - } - } - return Post.prototype.callbacks.push({ - name: 'Quick Reply', - cb: this.node - }); - }, - initReady: function() { - var link; - - QR.postingIsEnabled = !!$.id('postForm'); - if (!QR.postingIsEnabled) { - return; - } - link = $.el('h1', { - innerHTML: "" + (g.VIEW === 'thread' ? 'Reply to Thread' : 'Start a Thread') + "", - className: "qr-link-container" - }); - $.on(link.firstChild, 'click', function() { - $.event('CloseMenu'); - QR.open(); - QR.nodes.com.focus(); - if (Conf['QR Shortcut']) { - return $.rmClass($('.qr-shortcut'), 'disabled'); - } - }); - $.before($.id('postForm'), link); - $.on(d, 'QRGetSelectedPost', function(_arg) { - var cb; - - cb = _arg.detail; - return cb(QR.selected); - }); - $.on(d, 'QRAddPreSubmitHook', function(_arg) { - var cb; - - cb = _arg.detail; - return QR.preSubmitHooks.push(cb); - }); - $.on(d, 'dragover', QR.dragOver); - $.on(d, 'drop', QR.dropFile); - $.on(d, 'dragstart dragend', QR.drag); - return $.on(d, 'ThreadUpdate', function() { - if (g.DEAD) { - return QR.abort(); - } else { - return QR.status(); - } - }); - }, - node: function() { - return $.on($('a[title="Quote this post"]', this.nodes.info), 'click', QR.quote); - }, - persist: function() { - if (!QR.postingIsEnabled) { - return; - } - QR.open(); - if (Conf['Auto-Hide QR'] || g.VIEW === 'catalog') { - return QR.hide(); - } - }, - open: function() { - var err; - - if (QR.nodes) { - QR.nodes.el.hidden = false; - QR.unhide(); - return; - } - try { - return QR.dialog(); - } catch (_error) { - err = _error; - delete QR.nodes; - return Main.handleErrors({ - message: 'Quick Reply dialog creation crashed.', - error: err - }); - } - }, - close: function() { - var post, _i, _len, _ref; - - if (QR.req) { - QR.abort(); - return; - } - QR.nodes.el.hidden = true; - QR.cleanNotifications(); - d.activeElement.blur(); - $.rmClass(QR.nodes.el, 'dump'); - if (!Conf['Captcha Warning Notifications']) { - if (QR.captcha.isEnabled) { - $.rmClass(QR.captcha.nodes.input, 'error'); - } - } - if (Conf['QR Shortcut']) { - $.toggleClass($('.qr-shortcut'), 'disabled'); - } - new QR.post(true); - _ref = QR.posts.splice(0, QR.posts.length - 1); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - post = _ref[_i]; - post["delete"](); - } - QR.cooldown.auto = false; - return QR.status(); - }, - focusin: function() { - return $.addClass(QR.nodes.el, 'has-focus'); - }, - focusout: function() { - return $.queueTask(function() { - if ($.x('ancestor::div[@id="qr"]', d.activeElement)) { - return; - } - return $.rmClass(QR.nodes.el, 'has-focus'); - }); - }, - hide: function() { - d.activeElement.blur(); - $.addClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = true; - }, - unhide: function() { - $.rmClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = false; - }, - toggleHide: function() { - if (this.checked) { - return QR.hide(); - } else { - return QR.unhide(); - } - }, - error: function(err) { - var el; - - QR.open(); - if (typeof err === 'string') { - el = $.tn(err); - } else { - el = err; - el.removeAttribute('style'); - } - if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) { - QR.captcha.nodes.input.focus(); - if (Conf['Captcha Warning Notifications']) { - QR.notify(el); - } else { - $.addClass(QR.captcha.nodes.input, 'error'); - $.on(QR.captcha.nodes.input, 'keydown', function() { - return $.rmClass(QR.captcha.nodes.input, 'error'); - }); - } - } else { - QR.notify(el); - } - if (d.hidden) { - return alert(el.textContent); - } - }, - notify: function(el) { - var notice, notif; - - notice = new Notice('warning', el); - QR.notifications.push(notice); - if (!Header.areNotificationsEnabled) { - return; - } - notif = new Notification(el.textContent, { - body: el.textContent, - icon: Favicon.logo - }); - return notif.onclick = function() { - return window.focus(); - }; - }, - notifications: [], - cleanNotifications: function() { - var notification, _i, _len, _ref; - - _ref = QR.notifications; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - notification = _ref[_i]; - notification.close(); - } - return QR.notifications = []; - }, - status: function() { - var disabled, status, thread, value; - - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads["" + g.BOARD + "." + thread].isDead) { - value = 404; - disabled = true; - QR.cooldown.auto = false; - } - value = QR.req ? QR.req.progress : QR.cooldown.seconds || value; - status = QR.nodes.status; - status.value = !value ? 'Submit' : QR.cooldown.auto ? "Auto " + value : value; - return status.disabled = disabled || false; - }, - persona: { - pwd: '', - always: {}, - init: function() { - QR.persona.getPassword(); - return $.get('QR.personas', Conf['QR.personas'], function(_arg) { - var arr, item, personas, type, types, _i, _len, _ref; - - personas = _arg['QR.personas']; - types = { - name: [], - email: [], - sub: [] - }; - _ref = personas.split('\n'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - item = _ref[_i]; - QR.persona.parseItem(item.trim(), types); - } - for (type in types) { - arr = types[type]; - QR.persona.loadPersonas(type, arr); - } - }); - }, - parseItem: function(item, types) { - var boards, match, type, val, _ref, _ref1; - - if (item[0] === '#') { - return; - } - if (!(match = item.match(/(name|email|subject|password):"(.*)"/i))) { - return; - } - _ref = match, match = _ref[0], type = _ref[1], val = _ref[2]; - item = item.replace(match, ''); - boards = ((_ref1 = item.match(/boards:([^;]+)/i)) != null ? _ref1[1].toLowerCase() : void 0) || 'global'; - if (boards !== 'global' && !((boards.split(',')).contains(g.BOARD.ID))) { - return; - } - if (type === 'password') { - QR.persona.pwd = val; - return; - } - if (type === 'subject') { - type = 'sub'; - } - if (/always/i.test(item)) { - QR.persona.always[type] = val; - } - if (!types[type].contains(val)) { - return types[type].push(val); - } - }, - loadPersonas: function(type, arr) { - var list, val, _i, _len; - - list = $("#list-" + type, QR.nodes.el); - for (_i = 0, _len = arr.length; _i < _len; _i++) { - val = arr[_i]; - if (val) { - $.add(list, $.el('option', { - textContent: val - })); - } - } - }, - getPassword: function() { - var input, m; - - if (!QR.persona.pwd) { - QR.persona.pwd = (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : (input = $.id('postPassword')) ? input.value : $.id('delPassword').value; - } - return QR.persona.pwd; - }, - get: function(cb) { - return $.get('QR.persona', {}, function(_arg) { - var persona; - - persona = _arg['QR.persona']; - return cb(persona); - }); - }, - set: function(post) { - return $.get('QR.persona', {}, function(_arg) { - var persona; - - persona = _arg['QR.persona']; - persona = { - name: post.name, - email: /^sage$/.test(post.email) ? persona.email : post.email, - sub: Conf['Remember Subject'] ? post.sub : void 0 - }; - return $.set('QR.persona', persona); - }); - } - }, - cooldown: { - init: function() { - var board; - - if (!Conf['Cooldown']) { - return; - } - board = g.BOARD.ID; - QR.cooldown.types = { - thread: (function() { - switch (board) { - case 'q': - return 86400; - case 'b': - case 'soc': - case 'r9k': - return 600; - default: - return 300; - } - })(), - sage: board === 'q' ? 600 : 60, - file: board === 'q' ? 300 : 30, - post: board === 'q' ? 150 : 30 - }; - QR.cooldown.upSpd = 0; - QR.cooldown.upSpdAccuracy = .5; - $.get("cooldown." + board, {}, function(item) { - QR.cooldown.cooldowns = item["cooldown." + board]; - return QR.cooldown.start(); - }); - return $.sync("cooldown." + board, QR.cooldown.sync); - }, - start: function() { - if (!Conf['Cooldown']) { - return; - } - if (QR.cooldown.isCounting) { - return; - } - QR.cooldown.isCounting = true; - return QR.cooldown.count(); - }, - sync: function(cooldowns) { - var id; - - for (id in cooldowns) { - QR.cooldown.cooldowns[id] = cooldowns[id]; - } - return QR.cooldown.start(); - }, - set: function(data) { - var cooldown, delay, hasFile, isReply, isSage, post, req, start, type, upSpd; - - if (!Conf['Cooldown']) { - return; - } - req = data.req, post = data.post, isReply = data.isReply, delay = data.delay; - start = req ? req.uploadEndTime : Date.now(); - if (delay) { - cooldown = { - delay: delay - }; - } else { - if (post.file) { - upSpd = post.file.size / ((req.uploadEndTime - req.uploadStartTime) / $.SECOND); - QR.cooldown.upSpdAccuracy = ((upSpd > QR.cooldown.upSpd * .9) + QR.cooldown.upSpdAccuracy) / 2; - QR.cooldown.upSpd = upSpd; - } - isSage = /sage/i.test(post.email); - hasFile = !!post.file; - type = !isReply ? 'thread' : isSage ? 'sage' : hasFile ? 'file' : 'post'; - cooldown = { - isReply: isReply, - isSage: isSage, - hasFile: hasFile, - timeout: start + QR.cooldown.types[type] * $.SECOND - }; - } - QR.cooldown.cooldowns[start] = cooldown; - $.set("cooldown." + g.BOARD, QR.cooldown.cooldowns); - return QR.cooldown.start(); - }, - unset: function(id) { - delete QR.cooldown.cooldowns[id]; - if (Object.keys(QR.cooldown.cooldowns).length) { - return $.set("cooldown." + g.BOARD, QR.cooldown.cooldowns); - } else { - return $["delete"]("cooldown." + g.BOARD); - } - }, - count: function() { - var cooldown, cooldowns, elapsed, hasFile, isReply, isSage, now, post, seconds, start, type, types, upSpd, upSpdAccuracy, update, _ref; - - if (!Object.keys(QR.cooldown.cooldowns).length) { - $["delete"]("" + g.BOARD + ".cooldown"); - delete QR.cooldown.isCounting; - delete QR.cooldown.seconds; - QR.status(); - return; - } - setTimeout(QR.cooldown.count, $.SECOND); - now = Date.now(); - post = QR.posts[0]; - isReply = post.thread !== 'new'; - isSage = /sage/i.test(post.email); - hasFile = !!post.file; - seconds = null; - _ref = QR.cooldown, types = _ref.types, cooldowns = _ref.cooldowns, upSpd = _ref.upSpd, upSpdAccuracy = _ref.upSpdAccuracy; - for (start in cooldowns) { - cooldown = cooldowns[start]; - if ('delay' in cooldown) { - if (cooldown.delay) { - seconds = Math.max(seconds, cooldown.delay--); - } else { - seconds = Math.max(seconds, 0); - QR.cooldown.unset(start); - } - continue; - } - if (isReply === cooldown.isReply) { - type = !isReply ? 'thread' : isSage && cooldown.isSage ? 'sage' : hasFile && cooldown.hasFile ? 'file' : 'post'; - elapsed = Math.floor((now - start) / $.SECOND); - if (elapsed >= 0) { - seconds = Math.max(seconds, types[type] - elapsed); - if (Conf['Cooldown Prediction'] && hasFile && upSpd) { - seconds -= Math.floor(post.file.size / upSpd * upSpdAccuracy); - seconds = Math.max(seconds, 0); - } - } - } - if (!((start <= now && now <= cooldown.timeout))) { - QR.cooldown.unset(start); - } - } - update = seconds !== null || !!QR.cooldown.seconds; - QR.cooldown.seconds = seconds; - if (update) { - QR.status(); - } - if (seconds === 0 && QR.cooldown.auto && !QR.req) { - return QR.submit(); - } - } - }, - quote: function(e) { - var caretPos, com, index, post, range, s, sel, text, thread, _ref; - - if (e != null) { - e.preventDefault(); - } - if (!QR.postingIsEnabled) { - return; - } - sel = d.getSelection(); - post = Get.postFromNode(this); - text = ">>" + post + "\n"; - if ((s = sel.toString().trim()) && post === Get.postFromNode(sel.anchorNode)) { - s = s.replace(/\n/g, '\n>'); - text += ">" + s + "\n"; - } - QR.open(); - if (QR.selected.isLocked) { - index = QR.posts.indexOf(QR.selected); - (QR.posts[index + 1] || new QR.post()).select(); - $.addClass(QR.nodes.el, 'dump'); - QR.cooldown.auto = true; - } - _ref = QR.nodes, com = _ref.com, thread = _ref.thread; - if (!com.value) { - thread.value = Get.threadFromNode(this); - } - caretPos = com.selectionStart; - com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd); - range = caretPos + text.length; - com.setSelectionRange(range, range); - com.focus(); - QR.selected.save(com); - QR.selected.save(thread); - if (Conf['QR Shortcut']) { - return $.rmClass($('.qr-shortcut'), 'disabled'); - } - }, - characterCount: function() { - var count, counter; - - counter = QR.nodes.charCount; - count = QR.nodes.com.textLength; - counter.textContent = count; - counter.hidden = count < 1000; - return (count > 1500 ? $.addClass : $.rmClass)(counter, 'warning'); - }, - drag: function(e) { - var toggle; - - toggle = e.type === 'dragstart' ? $.off : $.on; - toggle(d, 'dragover', QR.dragOver); - return toggle(d, 'drop', QR.dropFile); - }, - dragOver: function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'copy'; - }, - dropFile: function(e) { - if (!e.dataTransfer.files.length) { - return; - } - e.preventDefault(); - QR.open(); - QR.handleFiles(e.dataTransfer.files); - return $.addClass(QR.nodes.el, 'dump'); - }, - paste: function(e) { - var blob, files, item, _i, _len, _ref; - - files = []; - _ref = e.clipboardData.items; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - item = _ref[_i]; - if (!(item.kind === 'file')) { - continue; - } - blob = item.getAsFile(); - blob.name = 'file'; - if (blob.type) { - blob.name += '.' + blob.type.split('/')[1]; - } - files.push(blob); - } - if (!files.length) { - return; - } - QR.open(); - QR.handleFiles(files); - return $.addClass(QR.nodes.el, 'dump'); - }, - handleFiles: function(files) { - var file, isSingle, max, _i, _len; - - if (this !== QR) { - files = __slice.call(this.files); - this.value = null; - } - if (!files.length) { - return; - } - max = QR.nodes.fileInput.max; - isSingle = files.length === 1; - QR.cleanNotifications(); - for (_i = 0, _len = files.length; _i < _len; _i++) { - file = files[_i]; - QR.handleFile(file, isSingle, max); - } - if (!isSingle) { - return $.addClass(QR.nodes.el, 'dump'); - } - }, - handleFile: function(file, isSingle, max) { - var post; - - if (file.size > max) { - QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); - return; - } else if (!QR.mimeTypes.contains(file.type)) { - if (!/^text/.test(file.type)) { - QR.error("" + file.name + ": Unsupported file type."); - return; - } - if (isSingle) { - post = QR.selected; - } else if ((post = QR.posts[QR.posts.length - 1]).com) { - post = new QR.post(); - } - post.pasteText(file); - return; - } - if (isSingle) { - post = QR.selected; - } else if ((post = QR.posts[QR.posts.length - 1]).file) { - post = new QR.post(); - } - return post.setFile(file); - }, - openFileInput: function(e) { - e.stopPropagation(); - if (e.shiftKey && e.type === 'click') { - return QR.selected.rmFile(); - } - if (e.ctrlKey && e.type === 'click') { - $.addClass(QR.nodes.filename, 'edit'); - QR.nodes.filename.focus(); - return $.on(QR.nodes.filename, 'blur', function() { - return $.rmClass(QR.nodes.filename, 'edit'); - }); - } - if (e.target.nodeName === 'INPUT' || (e.keyCode && ![32, 13].contains(e.keyCode)) || e.ctrlKey) { - return; - } - e.preventDefault(); - return QR.nodes.fileInput.click(); - }, - posts: [], - post: (function() { - function _Class(select) { - this.select = __bind(this.select, this); - var el, elm, event, prev, _i, _j, _len, _len1, _ref, _ref1, - _this = this; - - el = $.el('a', { - className: 'qr-preview', - draggable: true, - href: 'javascript:;', - innerHTML: '×' - }); - this.nodes = { - el: el, - rm: el.firstChild, - label: $('label', el), - spoiler: $('input', el), - span: el.lastChild - }; - _ref = $$('*', el); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - elm = _ref[_i]; - $.on(elm, 'blur', QR.focusout); - $.on(elm, 'focus', QR.focusin); - } - $.on(el, 'click', this.select); - $.on(this.nodes.rm, 'click', function(e) { - e.stopPropagation(); - return _this.rm(); - }); - $.on(this.nodes.label, 'click', function(e) { - return e.stopPropagation(); - }); - $.on(this.nodes.spoiler, 'change', function(e) { - _this.spoiler = e.target.checked; - if (_this === QR.selected) { - return QR.nodes.spoiler.checked = _this.spoiler; - } - }); - $.add(QR.nodes.dumpList, el); - _ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - event = _ref1[_j]; - $.on(el, event.toLowerCase(), this[event]); - } - this.thread = g.VIEW === 'thread' ? g.THREADID : 'new'; - prev = QR.posts[QR.posts.length - 1]; - QR.posts.push(this); - this.nodes.spoiler.checked = this.spoiler = prev && Conf['Remember Spoiler'] ? prev.spoiler : false; - QR.persona.get(function(persona) { - _this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name; - _this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email; - _this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : Conf['Remember Subject'] ? prev ? prev.sub : persona.sub : ''; - if (QR.selected === _this) { - return _this.load(); - } - }); - if (select) { - this.select(); - } - this.unlock(); - } - - _Class.prototype.rm = function() { - var index; - - this["delete"](); - index = QR.posts.indexOf(this); - if (QR.posts.length === 1) { - new QR.post(true); - $.rmClass(QR.nodes.el, 'dump'); - } else if (this === QR.selected) { - (QR.posts[index - 1] || QR.posts[index + 1]).select(); - } - QR.posts.splice(index, 1); - return QR.status(); - }; - - _Class.prototype["delete"] = function() { - $.rm(this.nodes.el); - return URL.revokeObjectURL(this.URL); - }; - - _Class.prototype.lock = function(lock) { - var name, _i, _len, _ref; - - if (lock == null) { - lock = true; - } - this.isLocked = lock; - if (this !== QR.selected) { - return; - } - _ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - QR.nodes[name].disabled = lock; - } - this.nodes.rm.style.visibility = lock ? 'hidden' : ''; - (lock ? $.off : $.on)(QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput); - this.nodes.spoiler.disabled = lock; - return this.nodes.el.draggable = !lock; - }; - - _Class.prototype.unlock = function() { - return this.lock(false); - }; - - _Class.prototype.select = function() { - var rectEl, rectList; - - if (QR.selected) { - QR.selected.nodes.el.id = null; - QR.selected.forceSave(); - } - QR.selected = this; - this.lock(this.isLocked); - this.nodes.el.id = 'selected'; - rectEl = this.nodes.el.getBoundingClientRect(); - rectList = this.nodes.el.parentNode.getBoundingClientRect(); - this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - this.load(); - return $.event('QRPostSelection', this); - }; - - _Class.prototype.load = function() { - var name, _i, _len, _ref; - - _ref = ['thread', 'name', 'email', 'sub', 'com', 'filename']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - QR.nodes[name].value = this[name] || null; - } - this.showFileData(); - return QR.characterCount(); - }; - - _Class.prototype.save = function(input) { - var name, _ref; - - if (input.type === 'checkbox') { - this.spoiler = input.checked; - return; - } - name = input.dataset.name; - this[name] = input.value; - switch (name) { - case 'thread': - return QR.status(); - case 'com': - this.nodes.span.textContent = this.com; - QR.characterCount(); - if (QR.cooldown.auto && this === QR.posts[0] && (0 < (_ref = QR.cooldown.seconds) && _ref <= 5)) { - return QR.cooldown.auto = false; - } - break; - case 'filename': - if (!this.file) { - return; - } - this.file.newName = this.filename.replace(/[/\\]/g, '-'); - if (!/\.(jpe?g|png|gif|pdf|swf)$/i.test(this.filename)) { - this.file.newName += '.jpg'; - } - return this.updateFilename(); - } - }; - - _Class.prototype.forceSave = function() { - var name, _i, _len, _ref; - - if (this !== QR.selected) { - return; - } - _ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - this.save(QR.nodes[name]); - } - }; - - _Class.prototype.setFile = function(file) { - this.file = file; - this.filename = file.name; - this.filesize = $.bytesToString(file.size); - if (QR.spoiler) { - this.nodes.label.hidden = false; - } - URL.revokeObjectURL(this.URL); - this.showFileData(); - if (!/^image/.test(file.type)) { - this.nodes.el.style.backgroundImage = null; - return; - } - return this.setThumbnail(); - }; - - _Class.prototype.setThumbnail = function() { - var fileURL, img, - _this = this; - - img = $.el('img'); - img.onload = function() { - var cv, height, s, width; - - s = 90 * 2; - if (_this.file.type === 'image/gif') { - s *= 3; - } - height = img.height, width = img.width; - if (height < s || width < s) { - _this.URL = fileURL; - _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - return; - } - if (height <= width) { - width = s / height * width; - height = s; - } else { - height = s / width * height; - width = s; - } - cv = $.el('canvas'); - cv.height = img.height = height; - cv.width = img.width = width; - cv.getContext('2d').drawImage(img, 0, 0, width, height); - URL.revokeObjectURL(fileURL); - return cv.toBlob(function(blob) { - _this.URL = URL.createObjectURL(blob); - return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - }); - }; - fileURL = URL.createObjectURL(this.file); - return img.src = fileURL; - }; - - _Class.prototype.rmFile = function() { - if (this.isLocked) { - return; - } - delete this.file; - delete this.filename; - delete this.filesize; - this.nodes.el.title = null; - QR.nodes.fileContainer.title = ''; - this.nodes.el.style.backgroundImage = null; - if (QR.spoiler) { - this.nodes.label.hidden = true; - } - this.showFileData(); - return URL.revokeObjectURL(this.URL); - }; - - _Class.prototype.updateFilename = function() { - var long; - - long = "" + this.filename + " (" + this.filesize + ")\nCtrl+click to edit filename. Shift+click to clear."; - this.nodes.el.title = long; - if (this !== QR.selected) { - return; - } - return QR.nodes.fileContainer.title = long; - }; - - _Class.prototype.showFileData = function() { - if (this.file) { - this.updateFilename(); - QR.nodes.filename.value = this.filename; - QR.nodes.spoiler.checked = this.spoiler; - return $.addClass(QR.nodes.fileSubmit, 'has-file'); - } else { - return $.rmClass(QR.nodes.fileSubmit, 'has-file'); - } - }; - - _Class.prototype.pasteText = function(file) { - var reader, - _this = this; - - reader = new FileReader(); - reader.onload = function(e) { - var text; - - text = e.target.result; - if (_this.com) { - _this.com += "\n" + text; - } else { - _this.com = text; - } - if (QR.selected === _this) { - QR.nodes.com.value = _this.com; - } - return _this.nodes.span.textContent = _this.com; - }; - return reader.readAsText(file); - }; - - _Class.prototype.dragStart = function(e) { - e.dataTransfer.setDragImage(this, e.layerX, e.layerY); - return $.addClass(this, 'drag'); - }; - - _Class.prototype.dragEnd = function() { - return $.rmClass(this, 'drag'); - }; - - _Class.prototype.dragEnter = function() { - return $.addClass(this, 'over'); - }; - - _Class.prototype.dragLeave = function() { - return $.rmClass(this, 'over'); - }; - - _Class.prototype.dragOver = function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'move'; - }; - - _Class.prototype.drop = function() { - var el, index, newIndex, oldIndex, post; - - $.rmClass(this, 'over'); - if (!this.draggable) { - return; - } - el = $('.drag', this.parentNode); - index = function(el) { - return __slice.call(el.parentNode.children).indexOf(el); - }; - oldIndex = index(el); - newIndex = index(this); - (oldIndex < newIndex ? $.after : $.before)(this, el); - post = QR.posts.splice(oldIndex, 1)[0]; - QR.posts.splice(newIndex, 0, post); - return QR.status(); - }; - - return _Class; - - })(), - captcha: { - init: function() { - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$.id('captchaFormPart'))) { - return; - } - return $.asap((function() { - return $.id('recaptcha_challenge_field_holder'); - }), this.ready.bind(this)); - }, - ready: function() { - var imgContainer, input, setLifetime, - _this = this; - - setLifetime = function(e) { - return _this.lifetime = e.detail; - }; - $.on(window, 'captcha:timeout', setLifetime); - $.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))'); - $.off(window, 'captcha:timeout', setLifetime); - imgContainer = $.el('div', { - className: 'captcha-img', - title: 'Reload', - innerHTML: '' - }); - input = $.el('input', { - className: 'captcha-input field', - title: 'Verification', - autocomplete: 'off', - spellcheck: false, - tabIndex: 55 - }); - this.nodes = { - challenge: $.id('recaptcha_challenge_field_holder'), - img: imgContainer.firstChild, - input: input - }; - new MutationObserver(this.load.bind(this)).observe(this.nodes.challenge, { - childList: true - }); - $.on(imgContainer, 'click', this.reload.bind(this)); - $.on(input, 'keydown', this.keydown.bind(this)); - $.on(input, 'focus', function() { - return $.addClass(QR.nodes.el, 'focus'); - }); - $.on(input, 'blur', function() { - return $.rmClass(QR.nodes.el, 'focus'); - }); - $.get('captchas', [], function(_arg) { - var captchas; - - captchas = _arg.captchas; - return _this.sync(captchas); - }); - $.sync('captchas', this.sync); - this.reload(); - $.on(input, 'blur', QR.focusout); - $.on(input, 'focus', QR.focusin); - $.addClass(QR.nodes.el, 'has-captcha'); - return $.after(QR.nodes.com.parentNode, [imgContainer, input]); - }, - sync: function(captchas) { - QR.captcha.captchas = captchas; - return QR.captcha.count(); - }, - getOne: function() { - var captcha, challenge, response; - - this.clear(); - if (captcha = this.captchas.shift()) { - challenge = captcha.challenge, response = captcha.response; - this.count(); - $.set('captchas', this.captchas); - } else { - challenge = this.nodes.img.alt; - if (response = this.nodes.input.value) { - this.reload(); - } - } - if (response) { - response = response.trim(); - if (!/\s/.test(response)) { - response = "" + response + " " + response; - } - } - return { - challenge: challenge, - response: response - }; - }, - save: function() { - var response; - - if (!(response = this.nodes.input.value.trim())) { - return; - } - this.captchas.push({ - challenge: this.nodes.img.alt, - response: response, - timeout: this.timeout - }); - this.count(); - this.reload(); - return $.set('captchas', this.captchas); - }, - clear: function() { - var captcha, i, now, _i, _len, _ref; - - now = Date.now(); - _ref = this.captchas; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - captcha = _ref[i]; - if (captcha.timeout > now) { - break; - } - } - if (!i) { - return; - } - this.captchas = this.captchas.slice(i); - this.count(); - return $.set('captchas', this.captchas); - }, - load: function() { - var challenge; - - if (!this.nodes.challenge.firstChild) { - return; - } - this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE; - challenge = this.nodes.challenge.firstChild.value; - this.nodes.img.alt = challenge; - this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge; - this.nodes.input.value = null; - return this.clear(); - }, - count: function() { - var count; - - count = this.captchas.length; - this.nodes.input.placeholder = (function() { - switch (count) { - case 0: - return 'Verification (Shift + Enter to cache)'; - case 1: - return 'Verification (1 cached captcha)'; - default: - return "Verification (" + count + " cached captchas)"; - } - })(); - return this.nodes.input.alt = count; - }, - reload: function(focus) { - $.globalEval('Recaptcha.reload("t")'); - if (focus) { - return this.nodes.input.focus(); - } - }, - keydown: function(e) { - if (e.keyCode === 8 && !this.nodes.input.value) { - this.reload(); - } else if (e.keyCode === 13 && e.shiftKey) { - this.save(); - } else { - return; - } - return e.preventDefault(); - } - }, - dialog: function() { - var check, dialog, elm, i, items, key, mimeTypes, name, nodes, thread, value, _ref; - - QR.nodes = nodes = { - el: dialog = UI.dialog('qr', 'top:0;right:0;', "
×
No selected file×+
") - }; - _ref = { - move: '.move', - autohide: '#autohide', - thread: 'select', - threadPar: '#qr-thread-select', - close: '.close', - form: 'form', - dumpButton: '#dump-button', - name: '[data-name=name]', - email: '[data-name=email]', - sub: '[data-name=sub]', - com: '[data-name=com]', - dumpList: '#dump-list', - addPost: '#add-post', - charCount: '#char-count', - fileSubmit: '#file-n-submit', - filename: '#qr-filename', - fileContainer: '#qr-filename-container', - fileRM: '#qr-filerm', - fileExtras: '#qr-extras-container', - spoiler: '#qr-file-spoiler', - spoilerPar: '#qr-spoiler-label', - status: '[type=submit]', - fileInput: '[type=file]' - }; - for (key in _ref) { - value = _ref[key]; - nodes[key] = $(value, dialog); - } - check = { - jpg: 'image/jpeg', - pdf: 'application/pdf', - swf: 'application/x-shockwave-flash' - }; - mimeTypes = $('ul.rules > li').textContent.trim().match(/: (.+)/)[1].toLowerCase().replace(/\w+/g, function(type) { - return check[type] || ("image/" + type); - }); - QR.mimeTypes = mimeTypes.split(', '); - QR.mimeTypes.push(''); - nodes.fileInput.max = $('input[name=MAX_FILE_SIZE]').value; - QR.spoiler = !!$('input[name=spoiler]'); - if (QR.spoiler) { - $.addClass(QR.nodes.el, 'has-spoiler'); - } else { - nodes.spoiler.parentElement.hidden = true; - } - if (g.BOARD.ID === 'f') { - nodes.flashTag = $.el('select', { - name: 'filetag', - innerHTML: "\n\n\n\n\n\n" - }); - $.add(nodes.form, nodes.flashTag); - } - for (thread in g.BOARD.threads) { - $.add(nodes.thread, $.el('option', { - value: thread, - textContent: "Thread No." + thread - })); - } - $.on(nodes.filename.parentNode, 'click keyup', QR.openFileInput); - items = $$('*', QR.nodes.el); - i = 0; - while (elm = items[i++]) { - $.on(elm, 'blur', QR.focusout); - $.on(elm, 'focus', QR.focusin); - } - $.on(dialog, 'focusin', QR.focusin); - $.on(dialog, 'focusout', QR.focusout); - $.on(nodes.autohide, 'change', QR.toggleHide); - $.on(nodes.close, 'click', QR.close); - $.on(nodes.dumpButton, 'click', function() { - return nodes.el.classList.toggle('dump'); - }); - $.on(nodes.addPost, 'click', function() { - return new QR.post(true); - }); - $.on(nodes.form, 'submit', QR.submit); - $.on(nodes.fileRM, 'click', function() { - return QR.selected.rmFile(); - }); - $.on(nodes.fileExtras, 'click', function(e) { - return e.stopPropagation(); - }); - $.on(nodes.spoiler, 'change', function() { - return QR.selected.nodes.spoiler.click(); - }); - $.on(nodes.fileInput, 'change', QR.handleFiles); - items = ['name', 'email', 'sub', 'com', 'filename']; - i = 0; - while (name = items[i++]) { - $.on(nodes[name], 'input', function() { - return QR.selected.save(this); - }); - } - $.on(nodes.thread, 'change', function() { - return QR.selected.save(this); - }); - if (Conf['Remember QR Size']) { - $.get('QR Size', '', function(item) { - return nodes.com.style.cssText = item['QR Size']; - }); - $.on(nodes.com, 'mouseup', function(e) { - if (e.button !== 0) { - return; - } - return $.set('QR Size', this.style.cssText); - }); - } - QR.persona.init(); - new QR.post(true); - QR.status(); - QR.cooldown.init(); - QR.captcha.init(); - $.add(d.body, dialog); - return $.event('QRDialogCreation', null, dialog); - }, - preSubmitHooks: [], - submit: function(e) { - var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; - - if (e != null) { - e.preventDefault(); - } - if (QR.req) { - QR.abort(); - return; - } - if (QR.cooldown.seconds) { - QR.cooldown.auto = !QR.cooldown.auto; - QR.status(); - return; - } - post = QR.posts[0]; - post.forceSave(); - if (g.BOARD.ID === 'f') { - filetag = QR.nodes.flashTag.value; - } - threadID = post.thread; - thread = g.BOARD.threads[threadID]; - if (threadID === 'new') { - threadID = null; - if (['vg', 'q'].contains(g.BOARD.ID) && !post.sub) { - err = 'New threads require a subject.'; - } else if (!(post.file || (textOnly = !!$('input[name=textonly]', $.id('postForm'))))) { - err = 'No file selected.'; - } - } else if (g.BOARD.threads[threadID].isClosed) { - err = 'You can\'t reply to this thread anymore.'; - } else if (!(post.com || post.file)) { - err = 'No file selected.'; - } else if (post.file && thread.fileLimit) { - err = 'Max limit of image replies has been reached.'; - } else { - _ref = QR.preSubmitHooks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hook = _ref[_i]; - if (err = hook(post, thread)) { - break; - } - } - } - if (QR.captcha.isEnabled && !err) { - _ref1 = QR.captcha.getOne(), challenge = _ref1.challenge, response = _ref1.response; - if (!response) { - err = 'No valid captcha.'; - } - } - QR.cleanNotifications(); - if (err) { - QR.cooldown.auto = false; - QR.status(); - QR.error(err); - return; - } - QR.cooldown.auto = QR.posts.length > 1; - if (Conf['Auto Hide QR'] && !QR.cooldown.auto) { - QR.hide(); - } - if (!QR.cooldown.auto && $.x('ancestor::div[@id="qr"]', d.activeElement)) { - d.activeElement.blur(); - } - post.lock(); - postData = { - resto: threadID, - name: post.name, - email: post.email, - sub: post.sub, - com: post.com, - upfile: post.file, - filetag: filetag, - spoiler: post.spoiler, - textonly: textOnly, - mode: 'regist', - pwd: QR.persona.pwd, - recaptcha_challenge_field: challenge, - recaptcha_response_field: response - }; - options = { - responseType: 'document', - withCredentials: true, - onload: QR.response, - onerror: function() { - delete QR.req; - post.unlock(); - QR.cooldown.auto = false; - QR.status(); - return QR.error($.el('span', { - innerHTML: "4chan X encountered an error while posting. \n[Banned?] [More info]" - })); - } - }; - extra = { - form: $.formData(postData), - upCallbacks: { - onload: function() { - QR.req.isUploadFinished = true; - QR.req.uploadEndTime = Date.now(); - QR.req.progress = '...'; - return QR.status(); - }, - onprogress: function(e) { - QR.req.progress = "" + (Math.round(e.loaded / e.total * 100)) + "%"; - return QR.status(); - } - } - }; - QR.req = $.ajax($.id('postForm').parentNode.action, options, extra); - QR.req.uploadStartTime = Date.now(); - QR.req.progress = '...'; - return QR.status(); - }, - response: function() { - var URL, ban, board, captchasCount, err, h1, isReply, m, notif, post, postID, postsCount, req, resDoc, threadID, _, _ref, _ref1; - - req = QR.req; - delete QR.req; - post = QR.posts[0]; - post.unlock(); - resDoc = req.response; - if (ban = $('.banType', resDoc)) { - board = $('.board', resDoc).innerHTML; - err = $.el('span', { - innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;
\nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".
\nReason: " + ($('.reason', resDoc).innerHTML) - }); - } else if (err = resDoc.getElementById('errmsg')) { - if ((_ref = $('a', err)) != null) { - _ref.target = '_blank'; - } - } else if (resDoc.title !== 'Post successful!') { - err = 'Connection error with sys.4chan.org.'; - } else if (req.status !== 200) { - err = "Error " + req.statusText + " (" + req.status + ")"; - } - if (err) { - if (/captcha|verification/i.test(err.textContent) || err === 'Connection error with sys.4chan.org.') { - if (/mistyped/i.test(err.textContent)) { - err = 'You seem to have mistyped the CAPTCHA.'; - } - QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : err === 'Connection error with sys.4chan.org.' ? true : false; - QR.cooldown.set({ - delay: 2 - }); - } else if (err.textContent && (m = err.textContent.match(/wait\s(\d+)\ssecond/i))) { - QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : true; - QR.cooldown.set({ - delay: m[1] - }); - } else { - QR.cooldown.auto = false; - } - QR.status(); - QR.error(err); - return; - } - h1 = $('h1', resDoc); - QR.cleanNotifications(); - if (Conf['Posting Success Notifications']) { - QR.notifications.push(new Notice('success', h1.textContent, 5)); - } - QR.persona.set(post); - _ref1 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = _ref1[0], threadID = _ref1[1], postID = _ref1[2]; - postID = +postID; - threadID = +threadID || postID; - isReply = threadID !== postID; - QR.db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID, - val: true - }); - ThreadUpdater.postID = postID; - $.event('QRPostSuccessful', { - board: g.BOARD, - threadID: threadID, - postID: postID - }); - postsCount = QR.posts.length; - QR.cooldown.auto = postsCount > 1 && isReply; - if (QR.cooldown.auto && QR.captcha.isEnabled && (captchasCount = QR.captcha.captchas.length) < 3 && captchasCount < postsCount) { - notif = new Notification('Quick reply warning', { - body: "You are running low on cached captchas. Cache count: " + captchasCount + ".", - icon: Favicon.logo - }); - notif.onclick = function() { - QR.open(); - QR.captcha.nodes.input.focus(); - return window.focus(); - }; - setTimeout(function() { - return notif.close(); - }, 7 * $.SECOND); - } - if (!(Conf['Persistent QR'] || QR.cooldown.auto)) { - QR.close(); - } else { - post.rm(); - } - QR.cooldown.set({ - req: req, - post: post, - isReply: isReply - }); - URL = threadID === postID ? "/" + g.BOARD + "/res/" + threadID : g.VIEW === 'index' && !QR.cooldown.auto && Conf['Open Post in New Tab'] ? "/" + g.BOARD + "/res/" + threadID + "#p" + postID : void 0; - if (URL) { - if (Conf['Open Post in New Tab']) { - $.open(URL); - } else { - window.location = URL; - } - } - return QR.status(); - }, - abort: function() { - if (QR.req && !QR.req.isUploadFinished) { - QR.req.abort(); - delete QR.req; - QR.posts[0].unlock(); - QR.cooldown.auto = false; - QR.notifications.push(new Notice('info', 'QR upload aborted.', 5)); - } - return QR.status(); - } - }; - - FappeTyme = { - init: function() { - var el, input; - - if (!(Conf['Fappe Tyme'] || Conf['Werk Tyme']) || g.VIEW === 'catalog' || g.BOARD === 'f') { - return; - } - if (Conf['Fappe Tyme']) { - el = $.el('label', { - innerHTML: " Fappe Tyme", - title: 'Fappe Tyme' - }); - FappeTyme.fappe = input = el.firstElementChild; - $.on(input, 'change', FappeTyme.cb.fappe); - $.event('AddMenuEntry', { - type: 'header', - el: el, - order: 97 - }); - } - if (Conf['Werk Tyme']) { - el = $.el('label', { - innerHTML: " Werk Tyme", - title: 'Werk Tyme' - }); - FappeTyme.werk = input = el.firstElementChild; - $.on(input, 'change', FappeTyme.cb.werk); - $.event('AddMenuEntry', { - type: 'header', - el: el, - order: 98 - }); - } - return Post.prototype.callbacks.push({ - name: 'Fappe Tyme', - cb: this.node - }); - }, - node: function() { - if (this.file) { - return; - } - return $.addClass(this.nodes.root, "noFile"); - }, - cb: { - fappe: function() { - $.toggleClass(doc, 'fappeTyme'); - return FappeTyme.fappe.checked = $.hasClass(doc, 'fappeTyme'); - }, - werk: function() { - $.toggleClass(doc, 'werkTyme'); - return FappeTyme.werk.checked = $.hasClass(doc, 'werkTyme'); - } - } - }; - - Gallery = { - init: function() { - var el; - - if (g.VIEW === 'catalog' || g.BOARD === 'f' || !Conf['Gallery']) { - return; - } - el = $.el('a', { - href: 'javascript:;', - id: 'appchan-gal', - title: 'Gallery', - className: 'fourchanx-icon icon-picture', - textContent: 'Gallery' - }); - $.on(el, 'click', this.cb.toggle); - Header.addShortcut(el); - return Post.prototype.callbacks.push({ - name: 'Gallery', - cb: this.node - }); - }, - node: function() { - var _ref; - - if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { - return; - } - if (Gallery.nodes) { - Gallery.generateThumb($('.file', this.nodes.root)); - Gallery.nodes.total.textContent = Gallery.images.length; - } - if (!Conf['Image Expansion']) { - return $.on(this.file.thumb.parentNode, 'click', Gallery.cb.image); - } - }, - build: function(image) { - var cb, createSubEntry, dialog, el, file, files, i, key, menuButton, name, nodes, value, _i, _len, _ref, _ref1; - - Gallery.images = []; - nodes = Gallery.nodes = {}; - nodes.el = dialog = $.el('div', { - id: 'a-gallery', - innerHTML: "
\n \n \n ×\n \n \n / \n
\n
\n \n
\n
\n
\n
" - }); - _ref = { - frame: '.gal-image', - name: '.gal-name', - count: '.count', - total: '.total', - thumbs: '.gal-thumbnails', - next: '.gal-image a', - current: '.gal-image img' - }; - for (key in _ref) { - value = _ref[key]; - nodes[key] = $(value, dialog); - } - menuButton = $('.menu-button', dialog); - nodes.menu = new UI.Menu('gallery'); - cb = Gallery.cb; - $.on(nodes.frame, 'click', cb.blank); - $.on(nodes.current, 'click', cb.download); - $.on(nodes.next, 'click', cb.next); - $.on($('.gal-prev', dialog), 'click', cb.prev); - $.on($('.gal-next', dialog), 'click', cb.next); - $.on($('.gal-close', dialog), 'click', cb.close); - $.on(menuButton, 'click', function(e) { - return nodes.menu.toggle(e, this, g); - }); - createSubEntry = Gallery.menu.createSubEntry; - _ref1 = ['Fit width', 'Fit height', 'Hide thumbnails']; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - name = _ref1[_i]; - el = createSubEntry(name).el; - $.event('AddMenuEntry', { - type: 'gallery', - el: el, - order: 0 - }); - } - $.on(d, 'keydown', cb.keybinds); - $.off(d, 'keydown', Keybinds.keydown); - i = 0; - files = $$('.post .file'); - while (file = files[i++]) { - if ($('.fileDeletedRes, .fileDeleted', file)) { - continue; - } - Gallery.generateThumb(file); - } - $.add(d.body, dialog); - nodes.thumbs.scrollTop = 0; - nodes.current.parentElement.scrollTop = 0; - Gallery.cb.open.call(image ? $("[href='" + (image.href.replace(/https?:/, '')) + "']", nodes.thumbs) : Gallery.images[0]); - d.body.style.overflow = 'hidden'; - return nodes.total.textContent = --i; - }, - generateThumb: function(file) { - var double, thumb, title; - - title = ($('.fileText a', file)).textContent; - thumb = ($('.fileThumb', file)).cloneNode(true); - if (double = $('img + img', thumb)) { - $.rm(double); - } - thumb.className = 'gal-thumb'; - thumb.title = title; - thumb.dataset.id = Gallery.images.length; - thumb.firstElementChild.style.cssText = ''; - $.on(thumb, 'click', Gallery.cb.open); - Gallery.images.push(thumb); - return $.add(Gallery.nodes.thumbs, thumb); - }, - cb: { - keybinds: function(e) { - var cb, key; - - if (!(key = Keybinds.keyCode(e))) { - return; - } - cb = (function() { - switch (key) { - case 'Esc': - case Conf['Open Gallery']: - return Gallery.cb.close; - case 'Right': - case 'Enter': - return Gallery.cb.next; - case 'Left': - case '': - return Gallery.cb.prev; - } - })(); - if (!cb) { - return; - } - e.stopPropagation(); - e.preventDefault(); - return cb(); - }, - open: function(e) { - var el, img, name, nodes; - - if (e) { - e.preventDefault(); - } - nodes = Gallery.nodes; - name = nodes.name; - if (el = $('.gal-highlight', Gallery.thumbs)) { - $.rmClass(el, 'gal-highlight'); - } - $.addClass(this, 'gal-highlight'); - img = $.el('img', { - src: name.href = this.href, - title: name.download = name.textContent = this.title - }); - img.dataset.id = this.dataset.id; - $.replace(nodes.current, img); - nodes.count.textContent = +this.dataset.id + 1; - nodes.current = img; - nodes.frame.scrollTop = 0; - return nodes.current.focus(); - }, - image: function(e) { - e.preventDefault(); - e.stopPropagation(); - return Gallery.build(this); - }, - prev: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id - 1]); - }, - next: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id + 1]); - }, - toggle: function() { - return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); - }, - blank: function(e) { - if (e.target === this) { - return Gallery.cb.close(); - } - }, - close: function() { - $.rm(Gallery.nodes.el); - delete Gallery.nodes; - d.body.style.overflow = ''; - $.off(d, 'keydown', Gallery.cb.keybinds); - return $.on(d, 'keydown', Keybinds.keydown); - } - }, - menu: { - init: function() { - var createSubEntry, el, name, subEntries, _i, _len, _ref; - - if (g.VIEW === 'catalog' || !Conf['Gallery'] || Conf['Image Expansion']) { - return; - } - el = $.el('span', { - textContent: 'Gallery', - className: 'gallery-link' - }); - createSubEntry = Gallery.menu.createSubEntry; - subEntries = []; - _ref = ['Fit width', 'Fit height', 'Hide thumbnails']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - subEntries.push(createSubEntry(name)); - } - return $.event('AddMenuEntry', { - type: 'header', - el: el, - order: 105, - subEntries: subEntries - }); - }, - createSubEntry: function(name) { - var input, label; - - label = $.el('label', { - innerHTML: " " + name - }); - input = label.firstElementChild; - $.on(input, 'change', ImageExpand.cb.setFitness); - input.checked = Conf[name]; - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - return { - el: label - }; - } - } - }; - - ImageExpand = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Image Expansion']) { - return; - } - this.EAI = $.el('a', { - className: 'expand-all-shortcut fourchanx-icon icon-resize-full', - textContent: 'EAI', - title: 'Expand All Images', - href: 'javascript:;' - }); - $.on(this.EAI, 'click', ImageExpand.cb.toggleAll); - Header.addShortcut(this.EAI, 2); - return Post.prototype.callbacks.push({ - name: 'Image Expansion', - cb: this.node - }); - }, - node: function() { - var thumb, _ref; - - if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { - return; - } - thumb = this.file.thumb; - $.on(thumb.parentNode, 'click', ImageExpand.cb.toggle); - if (this.isClone && $.hasClass(thumb, 'expanding')) { - ImageExpand.contract(this); - ImageExpand.expand(this); - return; - } - if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) { - return ImageExpand.expand(this); - } - }, - cb: { - toggle: function(e) { - if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { - return; - } - e.preventDefault(); - return ImageExpand.toggle(Get.postFromNode(this)); - }, - toggleAll: function() { - var ID, file, func, post, _i, _len, _ref, _ref1; - - $.event('CloseMenu'); - if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { - ImageExpand.EAI.className = 'contract-all-shortcut fourchanx-icon icon-resize-small'; - ImageExpand.EAI.title = 'Contract All Images'; - func = ImageExpand.expand; - } else { - ImageExpand.EAI.className = 'expand-all-shortcut fourchanx-icon icon-resize-full'; - ImageExpand.EAI.title = 'Expand All Images'; - func = ImageExpand.contract; - } - _ref = g.posts; - for (ID in _ref) { - post = _ref[ID]; - _ref1 = [post].concat(post.clones); - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - post = _ref1[_i]; - file = post.file; - if (!(file && file.isImage && doc.contains(post.nodes.root))) { - continue; - } - if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && file.thumb.getBoundingClientRect().top < 0)) { - continue; - } - $.queueTask(func, post); - } - } - }, - setFitness: function() { - return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-')); - } - }, - toggle: function(post) { - var headRect, rect, root, thumb, x, y; - - thumb = post.file.thumb; - if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { - ImageExpand.expand(post); - return; - } - ImageExpand.contract(post); - root = post.nodes.root; - rect = (Conf['Advance on contract'] ? (function() { - var next; - - next = root; - while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { - if ($('.stub', next) || next.offsetHeight === 0) { - continue; - } - return next; - } - return root; - })() : root).getBoundingClientRect(); - if (rect.top < 0) { - y = rect.top; - if (Conf['Fixed Header'] && !Conf['Bottom Header']) { - headRect = Header.bar.getBoundingClientRect(); - y -= headRect.top + headRect.height; - } - } - if (rect.left < 0) { - x = -window.scrollX; - } - if (x || y) { - return window.scrollBy(x, y); - } - }, - contract: function(post) { - $.rmClass(post.nodes.root, 'expanded-image'); - $.rmClass(post.file.thumb, 'expanding'); - return post.file.isExpanded = false; - }, - expand: function(post, src) { - var img, thumb; - - thumb = post.file.thumb; - if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) { - return; - } - $.addClass(thumb, 'expanding'); - if (post.file.fullImage) { - $.asap((function() { - return post.file.fullImage.naturalHeight; - }), function() { - return ImageExpand.completeExpand(post); - }); - return; - } - post.file.fullImage = img = $.el('img', { - className: 'full-image', - src: src || post.file.URL - }); - $.on(img, 'error', ImageExpand.error); - $.asap((function() { - return post.file.fullImage.naturalHeight; - }), function() { - return ImageExpand.completeExpand(post); - }); - return $.after(thumb, img); - }, - completeExpand: function(post) { - var prev, thumb; - - thumb = post.file.thumb; - if (!$.hasClass(thumb, 'expanding')) { - return; - } - post.file.isExpanded = true; - if (!post.nodes.root.parentNode) { - $.addClass(post.nodes.root, 'expanded-image'); - $.rmClass(post.file.thumb, 'expanding'); - return; - } - prev = post.nodes.root.getBoundingClientRect(); - return $.queueTask(function() { - var curr; - - $.addClass(post.nodes.root, 'expanded-image'); - $.rmClass(post.file.thumb, 'expanding'); - if (!(prev.top + prev.height <= 0)) { - return; - } - curr = post.nodes.root.getBoundingClientRect(); - return window.scrollBy(0, curr.height - prev.height + curr.top - prev.top); - }); - }, - error: function() { - var URL, post, src, timeoutID; - - post = Get.postFromNode(this); - $.rm(this); - delete post.file.fullImage; - if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) { - return; - } - ImageExpand.contract(post); - src = this.src.split('/'); - if (src[2] === 'images.4chan.org') { - URL = Redirect.to('file', { - boardID: src[3], - filename: src[5] - }); - if (URL) { - setTimeout(ImageExpand.expand, 10000, post, URL); - return; - } - if (g.DEAD || post.isDead || post.file.isDead) { - return; - } - } - timeoutID = setTimeout(ImageExpand.expand, 10000, post); - return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { - onload: function() { - var postObj, _i, _len, _ref; - - if (this.status !== 200) { - return; - } - _ref = JSON.parse(this.response).posts; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - postObj = _ref[_i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - clearTimeout(timeoutID); - return post.kill(); - } else if (postObj.filedeleted) { - clearTimeout(timeoutID); - return post.kill(true); - } - } - }); - }, - menu: { - init: function() { - var conf, createSubEntry, el, name, subEntries, _ref; - - if (g.VIEW === 'catalog' || !Conf['Image Expansion']) { - return; - } - el = $.el('span', { - textContent: 'Image Expansion', - className: 'image-expansion-link' - }); - createSubEntry = ImageExpand.menu.createSubEntry; - subEntries = []; - _ref = Config.imageExpansion; - for (name in _ref) { - conf = _ref[name]; - subEntries.push(createSubEntry(name, conf[1])); - } - return $.event('AddMenuEntry', { - type: 'header', - el: el, - order: 105, - subEntries: subEntries - }); - }, - createSubEntry: function(name, desc) { - var input, label; - - label = $.el('label', { - innerHTML: " " + name, - title: desc - }); - input = label.firstElementChild; - if (name === 'Fit width' || name === 'Fit height') { - $.on(input, 'change', ImageExpand.cb.setFitness); - } - input.checked = Conf[name]; - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - return { - el: label - }; - } - } - }; - - ImageHover = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Image Hover']) { - return; - } - return Post.prototype.callbacks.push({ - name: 'Image Hover', - cb: this.node - }); - }, - node: function() { - var _ref; - - if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { - return; - } - return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover); - }, - mouseover: function(e) { - var el, post; - - post = Get.postFromNode(this); - el = $.el('img', { - id: 'ihover', - src: post.file.URL - }); - el.dataset.fullID = post.fullID; - $.add(Header.hover, el); - UI.hover({ - root: this, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - asapTest: function() { - return el.naturalHeight; - } - }); - return $.on(el, 'error', ImageHover.error); - }, - error: function() { - var URL, post, src, timeoutID, - _this = this; - - if (!doc.contains(this)) { - return; - } - post = g.posts[this.dataset.fullID]; - src = this.src.split('/'); - if (src[2] === 'images.4chan.org') { - URL = Redirect.to('file', { - boardID: src[3], - filename: src[5].replace(/\?.+$/, '') - }); - if (URL) { - this.src = URL; - return; - } - if (g.DEAD || post.isDead || post.file.isDead) { - return; - } - } - timeoutID = setTimeout((function() { - return _this.src = post.file.URL + '?' + Date.now(); - }), 3000); - return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { - onload: function() { - var postObj, _i, _len, _ref; - - if (this.status !== 200) { - return; - } - _ref = JSON.parse(this.response).posts; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - postObj = _ref[_i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - clearTimeout(timeoutID); - return post.kill(); - } else if (postObj.filedeleted) { - clearTimeout(timeoutID); - return post.kill(true); - } - } - }); - } - }; - - ImageLoader = { - init: function() { - var prefetch; - - if (g.VIEW === 'catalog') { - return; - } - if (!(Conf["Image Prefetching"] || Conf["Replace JPG"] || Conf["Replace PNG"] || Conf["Replace GIF"])) { - return; - } - Post.prototype.callbacks.push({ - name: 'Image Replace', - cb: this.node - }); - if (!(Conf['Image Prefetching'] && g.VIEW === 'thread')) { - return; - } - prefetch = $.el('label', { - innerHTML: ' Prefetch Images' - }); - this.el = prefetch.firstElementChild; - $.on(this.el, 'change', this.toggle); - return $.event('AddMenuEntry', { - type: 'header', - el: prefetch, - order: 104 - }); - }, - node: function() { - var URL, img, string, style, thumb, type, _ref, _ref1; - - if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) { - return; - } - _ref1 = this.file, thumb = _ref1.thumb, URL = _ref1.URL; - if (!((Conf[string = "Replace " + ((type = (URL.match(/\w{3}$/))[0].toUpperCase()) === 'PEG' ? 'JPG' : type)] && !/spoiler/.test(thumb.src)) || Conf['prefetch'])) { - return; - } - if (this.file.isSpoiler) { - style = thumb.style; - style.maxHeight = style.maxWidth = this.isReply ? '125px' : '250px'; - } - img = $.el('img'); - if (Conf[string]) { - $.on(img, 'load', function() { - return thumb.src = URL; - }); - } - return img.src = URL; - }, - toggle: function() { - var enabled, id, post, _ref; - - enabled = Conf['prefetch'] = this.checked; - if (enabled) { - _ref = g.threads["" + g.BOARD.ID + "." + g.THREADID].posts; - for (id in _ref) { - post = _ref[id]; - ImageLoader.node.call(post); - } - } - } - }; - - RevealSpoilers = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Reveal Spoiler Thumbnails']) { - return; - } - return Post.prototype.callbacks.push({ - name: 'Reveal Spoiler Thumbnails', - cb: this.node - }); - }, - node: function() { - var thumb, _ref; - - if (this.isClone || !((_ref = this.file) != null ? _ref.isSpoiler : void 0)) { - return; - } - thumb = this.file.thumb; - thumb.removeAttribute('style'); - return thumb.src = this.file.thumbURL; - } - }; - - Sauce = { - init: function() { - var err, link, links, _i, _len, _ref; - - if (g.VIEW === 'catalog' || !Conf['Sauce']) { - return; - } - links = []; - _ref = Conf['sauces'].split('\n'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - try { - if (link[0] !== '#') { - links.push(this.createSauceLink(link.trim())); - } - } catch (_error) { - err = _error; - } - } - if (!links.length) { - return; - } - this.links = links; - this.link = $.el('a', { - target: '_blank' - }); - return Post.prototype.callbacks.push({ - name: 'Sauce', - cb: this.node - }); - }, - createSauceLink: function(link) { - var m, text; - - link = link.replace(/%(T?URL|MD5|board)/ig, function(parameter) { - switch (parameter) { - case '%TURL': - return "' + encodeURIComponent(post.file.thumbURL) + '"; - case '%URL': - return "' + encodeURIComponent(post.file.URL) + '"; - case '%MD5': - return "' + encodeURIComponent(post.file.MD5) + '"; - case '%board': - return "' + encodeURIComponent(post.board) + '"; - default: - return parameter; - } - }); - text = (m = link.match(/;text:(.+)$/)) ? m[1] : link.match(/(\w+)\.\w+\//)[1]; - link = link.replace(/;text:.+$/, ''); - return Function('post', 'a', "a.href = '" + link + "';\na.textContent = '" + text + "';\nreturn a;"); - }, - node: function() { - var link, nodes, _i, _len, _ref; - - if (this.isClone || !this.file) { - return; - } - nodes = []; - _ref = Sauce.links; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - nodes.push($.tn('\u00A0'), link(this, Sauce.link.cloneNode(true))); - } - return $.add(this.file.info, nodes); - } - }; - - ArchiveLink = { - init: function() { - var div, entry, type, _i, _len, _ref; - - if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Archive Link']) { - return; - } - div = $.el('div', { - textContent: 'Archive' - }); - entry = { - type: 'post', - el: div, - order: 90, - open: function(_arg) { - var ID, board, thread; - - ID = _arg.ID, thread = _arg.thread, board = _arg.board; - return !!Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - }, - subEntries: [] - }; - _ref = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['E-mail', 'email'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']]; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - type = _ref[_i]; - entry.subEntries.push(this.createSubEntry(type[0], type[1])); - } - return $.event('AddMenuEntry', entry); - }, - createSubEntry: function(text, type) { - var el, open; - - el = $.el('a', { - textContent: text, - target: '_blank' - }); - open = type === 'post' ? function(_arg) { - var ID, board, thread; - - ID = _arg.ID, thread = _arg.thread, board = _arg.board; - el.href = Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - return true; - } : function(post) { - var value; - - value = Filter[type](post); - if (!value) { - return false; - } - el.href = Redirect.to('search', { - boardID: post.board.ID, - type: type, - value: value, - isSearch: true - }); - return true; - }; - return { - el: el, - open: open - }; - } - }; - - DeleteLink = { - init: function() { - var div, fileEl, fileEntry, postEl, postEntry; - - if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Delete Link']) { - return; - } - div = $.el('div', { - className: 'delete-link', - textContent: 'Delete' - }); - postEl = $.el('a', { - className: 'delete-post', - href: 'javascript:;' - }); - fileEl = $.el('a', { - className: 'delete-file', - href: 'javascript:;' - }); - postEntry = { - el: postEl, - open: function() { - postEl.textContent = 'Post'; - $.on(postEl, 'click', DeleteLink["delete"]); - return true; - } - }; - fileEntry = { - el: fileEl, - open: function(_arg) { - var file; - - file = _arg.file; - if (!file || file.isDead) { - return false; - } - fileEl.textContent = 'File'; - $.on(fileEl, 'click', DeleteLink["delete"]); - return true; - } - }; - return $.event('AddMenuEntry', { - type: 'post', - el: div, - order: 40, - open: function(post) { - var node; - - if (post.isDead || post.board.ID === 'q') { - return false; - } - DeleteLink.post = post; - node = div.firstChild; - node.textContent = 'Delete'; - DeleteLink.cooldown.start(post, node); - return true; - }, - subEntries: [postEntry, fileEntry] - }); - }, - "delete": function() { - var fileOnly, form, link, post; - - post = DeleteLink.post; - if (DeleteLink.cooldown.counting === post) { - return; - } - $.off(this, 'click', DeleteLink["delete"]); - fileOnly = $.hasClass(this, 'delete-file'); - this.textContent = "Deleting " + (fileOnly ? 'file' : 'post') + "..."; - form = { - mode: 'usrdel', - onlyimgdel: fileOnly, - pwd: QR.persona.getPassword() - }; - form[post.ID] = 'delete'; - link = this; - return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), { - responseType: 'document', - withCredentials: true, - onload: function() { - return DeleteLink.load(link, post, fileOnly, this.response); - }, - onerror: function() { - return DeleteLink.error(link); - } - }, { - form: $.formData(form) - }); - }, - load: function(link, post, fileOnly, resDoc) { - var msg, s; - - if (resDoc.title === '4chan - Banned') { - s = 'Banned!'; - } else if (msg = resDoc.getElementById('errmsg')) { - s = msg.textContent; - $.on(link, 'click', DeleteLink["delete"]); - } else { - if (resDoc.title === 'Updating index...') { - (post.origin || post).kill(fileOnly); - } - s = 'Deleted'; - } - return link.textContent = s; - }, - error: function(link) { - link.textContent = 'Connection error, please retry.'; - return $.on(link, 'click', DeleteLink["delete"]); - }, - cooldown: { - start: function(post, node) { - var length, seconds, _ref; - - if (!((_ref = QR.db) != null ? _ref.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }) : void 0)) { - delete DeleteLink.cooldown.counting; - return; - } - DeleteLink.cooldown.counting = post; - length = 30; - seconds = Math.ceil((length * $.SECOND - (Date.now() - post.info.date)) / $.SECOND); - return DeleteLink.cooldown.count(post, seconds, length, node); - }, - count: function(post, seconds, length, node) { - if (DeleteLink.cooldown.counting !== post) { - return; - } - if (!((0 <= seconds && seconds <= length))) { - if (DeleteLink.cooldown.counting === post) { - node.textContent = 'Delete'; - delete DeleteLink.cooldown.counting; - } - return; - } - setTimeout(DeleteLink.cooldown.count, 1000, post, seconds - 1, length, node); - return node.textContent = "Delete (" + seconds + ")"; - } - } - }; - - DownloadLink = { - init: function() { - var a; - - if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Download Link']) { - return; - } - a = $.el('a', { - className: 'download-link', - textContent: 'Download file' - }); - return $.event('AddMenuEntry', { - type: 'post', - el: a, - order: 100, - open: function(_arg) { - var file; - - file = _arg.file; - if (!file) { - return false; - } - a.href = file.URL; - a.download = file.name; - return true; - } - }); - } - }; - - Menu = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Menu']) { - return; - } - this.menu = new UI.Menu('post'); - return Post.prototype.callbacks.push({ - name: 'Menu', - cb: this.node - }); - }, - node: function() { - if (this.isClone) { - return $.on($('.menu-button', this.nodes.info), 'click', Menu.toggle); - } else { - return $.add(this.nodes.info, [$.tn('\u00A0'), Menu.makeButton()]); - } - }, - makeButton: (function() { - var a; - - a = $.el('a', { - className: 'menu-button brackets-wrap', - innerHTML: '', - href: 'javascript:;' - }); - return function() { - var button; - - button = a.cloneNode(true); - $.on(button, 'click', Menu.toggle); - return button; - }; - })(), - toggle: function(e) { - var post; - - post = Get.postFromNode(this); - return Menu.menu.toggle(e, this, post); - } - }; - - ReportLink = { - init: function() { - var a; - - if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Report Link']) { - return; - } - a = $.el('a', { - className: 'report-link', - href: 'javascript:;', - textContent: 'Report this post' - }); - $.on(a, 'click', ReportLink.report); - return $.event('AddMenuEntry', { - type: 'post', - el: a, - order: 10, - open: function(post) { - ReportLink.post = post; - return !post.isDead; - } - }); - }, - report: function() { - var id, post, set, url; - - post = ReportLink.post; - url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post; - id = Date.now(); - set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=200"; - return window.open(url, id, set); - } - }; - - Favicon = { - init: function() { - return $.ready(function() { - var href; - - Favicon.el = $('link[rel="shortcut icon"]', d.head); - Favicon.el.type = 'image/x-icon'; - href = Favicon.el.href; - Favicon.SFW = /ws\.ico$/.test(href); - Favicon["default"] = href; - return Favicon["switch"](); - }); - }, - "switch": function() { - switch (Conf['favicon']) { - case 'ferongr': - Favicon.unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAPIGAOgLAnMFAL8AAOkMA/+AgP+rqwAAAAAAACH5BAUKAAYALAAAAAAQABAAQANKaLrcDYDBF8YgAQZiswJVp1mDZ4CB+aUmmkYnq4IFphGFGoMwr0MwySSGs62KGZBAIAJZli2gcLhA9V6STTNkjAkCX803LDmVgwkAOw=='; - Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII='; - Favicon.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAPIGAADX8QBwfgC2zADY8nnl8qLp8gAAAAAAACH5BAUKAAYALAAAAAAQABAAQANKaLrcDYDBF8YgAQZiswJVp1mDZ4CB+aUmmkYnq4IFphGFGoMwr0MwySSGs62KGZBAIAJZli2gcLhA9V6STTNkjAkCX803LDmVgwkAOw=='; - Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg=='; - Favicon.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAPIGAFT+ACh5AEncAFX/Acz/su7/5gAAAAAAACH5BAUKAAYALAAAAAAQABAAQANKaLrcDYDBF8YgAQZiswJVp1mDZ4CB+aUmmkYnq4IFphGFGoMwr0MwySSGs62KGZBAIAJZli2gcLhA9V6STTNkjAkCX803LDmVgwkAOw=='; - Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg=='; - break; - case 'xat-': - Favicon.unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42s1SQQrCMBDsQ8WDIEV6LTT2A4og2Hi0veo7fIAH04e06L1jphIJRtoVLw4MmWZnh2aT6K8Ax82uyFOV6SSJK5Kae74naIZHfhfx5HxaTC8kdeCRhNzms8ayFTaHJuTLzvKpJSE+sVoDhxIoK2qv5vgGDutoz8vfhlJd33w1gDGg5h5r9NArCzA1UNevgPtQQJplmtMeOwI99AYBW73PI8EQqXsvIbjGduAaxwPcQ/oqwF/dUw5r5GfArcLa73gAGxUeHPIycrIAAAAASUVORK5CYII='; - Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA80lEQVQ4y2NgGEzgPwx3TZhYVVJRPik7O30uCIPYIDFkNRia/yNhEH9ieszB5ZlxZ0EYxMamhqAhn1KT3gPxB5I1wxT9r6r8B8T/ccnjDAOwhvaO//9nz/n/f85cMBtdHiMEQYG1DOhfkLP/V1T8A2u+eOn//0uXwAYdiIr6ZyQi8ltOWPCLm5vzVuIMuHT5///Ll8EGWEhJ/YcBfn7+lxgGlJSXT4KFNi4vwAA3N/c7DAN6J02uYsATiBqoBrzCmpCwROMHWDRaIBmANRCxGQBLSOCEBcRcUIzXAGQalpRBbB8iXMCAJPEfh9wRKG1HtRwIAJCmKOzjRex1AAAAAElFTkSuQmCC'; - Favicon.unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAzUlEQVQ4y2NgGEzgPwxP7OuqqigtmZSZnj0XhEFskBiyGgzNetMPwzGIH5M/8WBczfKzIAxiY1ND0JCkDZ/eA/EHkjXDFFUe+f8PiP/jkscZBiDcfvr//9lX/v+fA8QgNro8RgiCAiuuetlZkLMrgDaDNF988///pdcQg0BiIDmQGpBaogy4BDTg8htkAz7jNqAcGFWw0MbnBZAakFoMAyZP6K1CDixcgQhiQ9UyEBONH4iNRqwGwBISSQYg07CkjE0OX35gwKEAnxz5AADUHTv3RAHZ7QAAAABJRU5ErkJggg=='; - Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/klEQVQ4y2NgGEzgPwxP7OuqqigtmZSZnj0XhEFskBiyGgzNetMPwzGIH5M/8WBczfKzIAxiY1ND0JCkDZ/eA/EHkjXDFFUe+f8PiP/jkscZBiDcfvr//9lX/v+fA8QgNro8RgiCAiuuetlZkLMrgDaDNF988///pdcQg6KmHPgnomL0W1BM7ours9tWogy4BDTg8huIAVLaFv9hgJ+f/yWGAeXAqIKFNi4vwAA3N/c7DAMmT+itQg4s9EBkF5dDNuAV1oSEJRo/wKKRS1ELbgDWQMRmACwhgdhSoXn/GVnZwRivAcg0LCmD2Ly6VgRdwIAk8R+H3BEobUe1HAgA7g5BI+Q2tn8AAAAASUVORK5CYII='; - Favicon.unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAzklEQVQ4y2NgGEzgPwxP7JpYVVZSMSk9O2suCIPYIDFkNRia084YwzGIHzMx/mDc8vizIAxiY1ND0JCST0nvgfgDyZphinr+V/4D4v+45HGGAQjP+t/+f/X/2UA8B8xGl8cIQVBgxS2LPwtyds//in8gzTf/XwTiS2CDQGIgOZAakFqiDLgF1Hzr/2WEAZ/xGFBWUj4JFtr4vABSA1KLYcDk3slVyIGFKxBBbKhaBmKi8QOx0YjVAFhCIskAZBqWlLHJ4csPDDgU4JMjHwAAAfUvfvahyqUAAAAASUVORK5CYII='; - Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/klEQVQ4y2NgGEzgPwxP7JpYVVZSMSk9O2suCIPYIDFkNRia084YwzGIHzMx/mDc8vizIAxiY1ND0JCST0nvgfgDyZphinr+V/4D4v+45HGGAQjP+t/+f/X/2UA8B8xGl8cIQVBgxS2LPwtyds//in8gzTf/XwTiS2CDMg9E/ZMwEvktKCf4xdnNdStRBtwCar71/zLYADkLqf8wwM/P/xLDgLKS8kmw0MblBRjg5uZ+h2HA5N7JVciBhR6IAgocyAa8wpqQsETjB1g0iulwww3AGojYDIAlJBDbqkT2PwsHExjjNQCZhiVlEFvOhp+gCxiQJP7jkDsCpe2olgMB9UE2wvseYUsAAAAASUVORK5CYII='; - break; - case 'Mayhem': - Favicon.unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFklEQVR4AZ2R4WqEMBCEFy1yiJQQ14gcIhIuFBFR+qPQ93+v66QMksrlTwMfkZ2ZZbMKTgVqYIDl3YAbeCM31lJP/Zul4MAEPJjBQGNDLGsz8PQ6aqLAP5PTdd1WlmU09mSKtdTDRgrkzspJPKq6RxMahfj9yhOzQEZwZAwfzrk1ox3MXibIN8hO4MAjeV72CemJGWblnRsOYOdoGw0jebB20BPAwKzUQPlrFhrXFw1Wagu9yuzZwINzVAZCURRL+gRr7Wd8Vtqg4Th/lsUmewyk9WQ/A7NiwJz5VV/GmO+MNjMrFvh/NPDMigHTaeJN09a27ZHRJmalBg54CgfvAGYSLpoHjlmpuAwFdzDy7oGS/qIpM9UPFGg1b1kUlssAAAAASUVORK5CYII='; - Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVR4AYWSQWq0QBCFCw0SRIK0PQ4hiIhEZBhEySLyewUPEMgqR/JIXiDhzz7kKKYePIZajEzDRxfV9dWU3SO6IiVWUsVxT5R75Y4gTmwNnUh4kCulUiuV8sjChDjmKtaUcHgmHsnNrMPh0IVhiMIjKZGzNXDoyhMzF7C89z2KtFGD+FoNXEUKZdgpaPM8P++cDXTtBDca7EyQK8+bXTufYBccuvLAG26UnqN1LCgI4g/lm7zTgSux4vk0J8rnKw3+m1//pBPbBrVyGZVNmiAITviEtm3t+D+2QcJx7GUxlN4594K4ZY75Xzh0JVWqnad6TdP0H+LRNBjHcYNDV5xS32qwaC4my7Lwn6guu5QoomgbdFmWDYhnM8E8zxscuhLzPWtKA/dGqUizrityX9M0YX+DQ1ciXobnP6vgfmTOM7Znnk70B58pPaEvx+epAAAAAElFTkSuQmCC'; - Favicon.unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAhSREQJIiIXpQwi+tSldkFdWPsLhyEE0ocKH2Fyzg1mNJ4KAQ1arTUeeJMH6qwTUJmCHjMcC6KKtbSIylzdXpl18J/k4fdTpUFmPLOOa9bGe+P4+n5RYYfLXuiMsAlXofBxK2QXpvwN/jqg+AY91vR+pStk+apZe0fEhhMXDhUmWXEoO9WNmrWAzvRPq7jnB2jvUGfWTEgPcJzZFTbZk/0Tnh5QI+af6lVGvq/Do2atwVL4VJ+3QrZo1lr4Pw5wzVqDWaV7SUvHrZDNmrWAHq7g0rphkS3LXDMBVqFGhxGT1gGdDFnWaab6BRmXRvbxDmYiAAAAAElFTkSuQmCC'; - Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4AY2SQUrEQBBFS9CMNFEkhAQdYmiCIUgcZlYGc4VsBcGVF/AuWXme4F7RtXiVWF9+Y9MYtOHRTdX/NZWaEj2RYpQTJeEdK4fKPuA7DjSGXiQkU0qlUqxySmFMEsYsNSU8zEmK4OwdEbmkKCclYoGmolfWCGyenh1O0EJE2gXNWpFC2S0IGrCQ29EbdPCPAmEHmXIxByf8hDAPD71yzAnXypatbSgoAN8Pyju5h4deMUrqJk1z+0uBN+/XX+gxfoFK2QafUJO2aRq//Q+/QIx2wr+Kwq0rusrP/QKf9MTCtbQLf9U1wNvYnz3qug45S68kSvVXgbPbx3nvYPXNOI7cRPWySukK+DcGCvA+urqZ3RmGAbmSXjFK5rpwW8nhWVJP04TYa9/3uO/goVciDiPlZhW8c8ZAHuRSeqIv32FK/GYGL8YAAAAASUVORK5CYII='; - Favicon.unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAihDCKKiAQJShERQx+6o662e2p/4TCEQF468BEm95yLovFr4PBEq9PjgTd5wBcZp6559AiIWDAq6KXV3aJMUMfDOsTf7Mf/XaFBAvYiE9W16b74/vl8UeBAlKOSmWAzUiXwcavMkrrFE9QXVJ+gx5q9XvUVivmqrr1jxIYLCacCs6y6S8psGNU1hw4Bu4JHuUB3pzJBHZcviLiKV9jkyO4vxHyBx1h+qlcY5b2Wj+raE0vlU33dKrNFXWsR/7EgqmtPBIXuIw+dt8osqGsOPaIGSeeGRbZiFtVxsAYeHSbMOgd0MhSzTp3mD4RaQX4aW3NMAAAAAElFTkSuQmCC'; - Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABP0lEQVR4AYWS0UqFQBCGhziImNRBRImDmUgiIaF0kWSP4AMEXXXTE/QiPpL3UdR19Crb/PAvLEtyFj5mmfn/cdxd0RUokbJXEsZYCZUd4D72NBG8wkKmlEqtVMoFhTFJmKuoKelBTVIkjbNE5IainJTIeZqaXjkg8fp+Z7GCjiLQbWgOihTKsCFowUZtoNef4HgDf4JMuTbe8n/Br8NDr5zxhBul52i3FBQE+xflmzzTA69ESmpPmubunwZfztc/6IncBrXSe7/QkK5tW3f8H7dBjHH8q6Kwt033V6Hb4JeeWPgsq42rugfYZ92psWscRwMPvZIo9bEGD2+F2YUnBizLwpeoXnYpbQM34kAB9peP58aueZ4NPPRKxPusaRoYG6UizbquyH1O04T4RA+8EvAwUr6sgjFnDuReLaUn+ANygUa7+9SCWgAAAABJRU5ErkJggg=='; - break; - case 'Original': - Favicon.unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs='; - Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC'; - Favicon.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAC6Xw////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs='; - Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC'; - Favicon.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs='; - Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC'; - } - if (Favicon.SFW) { - Favicon.unread = Favicon.unreadSFW; - return Favicon.unreadY = Favicon.unreadSFWY; - } else { - Favicon.unread = Favicon.unreadNSFW; - return Favicon.unreadY = Favicon.unreadNSFWY; - } - }, - dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', - logo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg==' - }; - - ThreadExcerpt = { - init: function() { - if (g.VIEW !== 'thread' || !Conf['Thread Excerpt']) { - return; - } - return Thread.prototype.callbacks.push({ - name: 'Thread Excerpt', - cb: this.node - }); - }, - node: function() { - return d.title = Get.threadExcerpt(this); - } - }; - - ThreadStats = { - init: function() { - var sc, - _this = this; - - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - innerHTML: "0 / 0" + (Conf["Page Count in Stats"] ? " / 0" : ""), - id: 'thread-stats', - title: 'Post Count / File Count' + (Conf["Page Count in Stats"] ? " / Page Count" : "") - }); - $.ready(function() { - return Header.addShortcut(sc); - }); - } else { - this.dialog = sc = UI.dialog('thread-stats', 'bottom: 0px; right: 0px;', "
0 / 0" + (Conf["Page Count in Stats"] ? " / 0" : "") + "
"); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.postCountEl = $('#post-count', sc); - this.fileCountEl = $('#file-count', sc); - this.pageCountEl = $('#page-count', sc); - return Thread.prototype.callbacks.push({ - name: 'Thread Stats', - cb: this.node - }); - }, - node: function() { - var ID, fileCount, post, postCount, _ref; - - postCount = 0; - fileCount = 0; - _ref = this.posts; - for (ID in _ref) { - post = _ref[ID]; - postCount++; - if (post.file) { - fileCount++; - } - } - ThreadStats.thread = this; - ThreadStats.fetchPage(); - ThreadStats.update(postCount, fileCount); - return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, - onUpdate: function(e) { - var fileCount, postCount, _ref; - - if (e.detail[404]) { - return; - } - _ref = e.detail, postCount = _ref.postCount, fileCount = _ref.fileCount; - return ThreadStats.update(postCount, fileCount); - }, - update: function(postCount, fileCount) { - var fileCountEl, postCountEl, thread; - - thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl; - postCountEl.textContent = postCount; - fileCountEl.textContent = fileCount; - (thread.postLimit && !thread.isSticky ? $.addClass : $.rmClass)(postCountEl, 'warning'); - return (thread.fileLimit && !thread.isSticky ? $.addClass : $.rmClass)(fileCountEl, 'warning'); - }, - fetchPage: function() { - if (!Conf["Page Count in Stats"]) { - return; - } - if (ThreadStats.thread.isDead) { - ThreadStats.pageCountEl.textContent = 'Dead'; - $.addClass(ThreadStats.pageCountEl, 'warning'); - return; - } - setTimeout(ThreadStats.fetchPage, 2 * $.MINUTE); - return $.ajax("//api.4chan.org/" + ThreadStats.thread.board + "/threads.json", { - onload: ThreadStats.onThreadsLoad - }, { - whenModified: true - }); - }, - onThreadsLoad: function() { - var page, pages, thread, _i, _j, _len, _len1, _ref; - - if (!(Conf["Page Count in Stats"] && this.status === 200)) { - return; - } - pages = JSON.parse(this.response); - for (_i = 0, _len = pages.length; _i < _len; _i++) { - page = pages[_i]; - _ref = page.threads; - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - thread = _ref[_j]; - if (thread.no === ThreadStats.thread.ID) { - ThreadStats.pageCountEl.textContent = page.page; - (page.page === pages.length - 1 ? $.addClass : $.rmClass)(ThreadStats.pageCountEl, 'warning'); - return; - } - } - } - } - }; - - ThreadUpdater = { - init: function() { - var checked, conf, el, input, name, sc, settings, subEntries, _ref, - _this = this; - - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - checked = Conf['Auto Update'] ? 'checked' : ''; - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - innerHTML: "", - id: 'updater' - }); - $.ready(function() { - return Header.addShortcut(sc); - }); - } else { - this.dialog = sc = UI.dialog('updater', 'bottom: 0px; left: 0px;', "
"); - $.addClass(doc, 'float'); - $.ready(function() { - $.addClass(doc, 'float'); - return $.add(d.body, sc); - }); - } - this.checkPostCount = 0; - this.timer = $('#update-timer', sc); - this.status = $('#update-status', sc); - $.on(this.timer, 'click', ThreadUpdater.update); - $.on(this.status, 'click', ThreadUpdater.update); - subEntries = []; - _ref = Config.updater.checkbox; - for (name in _ref) { - conf = _ref[name]; - checked = Conf[name] ? 'checked' : ''; - el = $.el('label', { - title: "" + conf[1], - innerHTML: " " + name - }); - input = el.firstElementChild; - $.on(input, 'change', $.cb.checked); - if (input.name === 'Scroll BG') { - $.on(input, 'change', ThreadUpdater.cb.scrollBG); - ThreadUpdater.cb.scrollBG(); - } else if (input.name === 'Auto Update') { - $.on(input, 'change', ThreadUpdater.update); - } - subEntries.push({ - el: el - }); - } - settings = $.el('span', { - innerHTML: 'Interval' - }); - $.on(settings, 'click', this.intervalShortcut); - subEntries.push({ - el: settings - }); - $.event('AddMenuEntry', { - type: 'header', - el: $.el('span', { - textContent: 'Updater' - }), - order: 110, - subEntries: subEntries - }); - return Thread.prototype.callbacks.push({ - name: 'Thread Updater', - cb: this.node - }); - }, - node: function() { - ThreadUpdater.thread = this; - ThreadUpdater.root = this.OP.nodes.root.parentNode; - ThreadUpdater.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0]; - ThreadUpdater.outdateCount = 0; - ThreadUpdater.cb.interval.call($.el('input', { - value: Conf['Interval'] - })); - $.on(window, 'online offline', ThreadUpdater.cb.online); - $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); - $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.cb.online(); - }, - /* - http://freesound.org/people/pierrecartoons1979/sounds/90112/ - cc-by-nc-3.0 - */ - - beep: 'data:audio/wav;base64,UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA', - cb: { - online: function() { - if (ThreadUpdater.online = navigator.onLine) { - ThreadUpdater.outdateCount = 0; - ThreadUpdater.set('timer', ThreadUpdater.getInterval()); - ThreadUpdater.update(); - ThreadUpdater.set('status', null, null); - } else { - ThreadUpdater.set('timer', null); - ThreadUpdater.set('status', 'Offline', 'warning'); - } - return ThreadUpdater.cb.autoUpdate(); - }, - post: function(e) { - if (e.detail.threadID !== ThreadUpdater.thread.ID) { - return; - } - ThreadUpdater.outdateCount = 0; - if (ThreadUpdater.seconds > 2) { - return setTimeout(ThreadUpdater.update, 1000); - } - }, - checkpost: function(e) { - if (!ThreadUpdater.checkPostCount) { - if (e.detail.threadID !== ThreadUpdater.thread.ID) { - return; - } - ThreadUpdater.seconds = 0; - ThreadUpdater.outdateCount = 0; - ThreadUpdater.set('timer', '...'); - } - if (!(g.DEAD || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) { - return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND); - } - ThreadUpdater.set('timer', ThreadUpdater.getInterval()); - ThreadUpdater.checkPostCount = 0; - delete ThreadUpdater.foundPost; - return delete ThreadUpdater.postID; - }, - visibility: function() { - if (d.hidden) { - return; - } - ThreadUpdater.outdateCount = 0; - if (ThreadUpdater.seconds > ThreadUpdater.interval) { - return ThreadUpdater.set('timer', ThreadUpdater.getInterval()); - } - }, - scrollBG: function() { - return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() { - return true; - } : function() { - return !d.hidden; - }; - }, - autoUpdate: function() { - if (ThreadUpdater.online) { - return ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); - } else { - return clearTimeout(ThreadUpdater.timeoutID); - } - }, - interval: function() { - var val; - - val = +this.value; - if (val < 1) { - val = 1; - } - ThreadUpdater.interval = this.value = val; - return $.cb.value.call(this); - }, - load: function() { - var klass, req, text, _ref; - - req = ThreadUpdater.req; - switch (req.status) { - case 200: - g.DEAD = false; - ThreadUpdater.parse(JSON.parse(req.response).posts); - ThreadUpdater.set('timer', ThreadUpdater.getInterval()); - break; - case 404: - g.DEAD = true; - ThreadUpdater.set('timer', null); - ThreadUpdater.set('status', '404', 'warning'); - clearTimeout(ThreadUpdater.timeoutID); - ThreadUpdater.thread.kill(); - $.event('ThreadUpdate', { - 404: true, - thread: ThreadUpdater.thread - }); - break; - default: - ThreadUpdater.outdateCount++; - ThreadUpdater.set('timer', ThreadUpdater.getInterval()); - _ref = req.status === 304 ? [null, null] : ["" + req.statusText + " (" + req.status + ")", 'warning'], text = _ref[0], klass = _ref[1]; - ThreadUpdater.set('status', text, klass); - } - if (ThreadUpdater.postID) { - ThreadUpdater.cb.checkpost(); - } - return delete ThreadUpdater.req; - } - }, - getInterval: function() { - var i, j; - - i = ThreadUpdater.interval; - j = Math.min(ThreadUpdater.outdateCount, 10); - if (!d.hidden) { - j = Math.min(j, 7); - } - return ThreadUpdater.seconds = Conf['Optional Increase'] ? Math.max(i, [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j]) : i; - }, - intervalShortcut: function() { - var settings; - - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('input[name=Interval]', settings).focus(); - }, - set: function(name, text, klass) { - var el, node; - - el = ThreadUpdater[name]; - if (node = el.firstChild) { - node.data = text; - } else { - el.textContent = text; - } - if (klass !== void 0) { - return el.className = klass; - } - }, - timeout: function() { - var n; - - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); - if (!(n = --ThreadUpdater.seconds)) { - return ThreadUpdater.update(); - } else if (n <= -60) { - ThreadUpdater.set('status', 'Retrying', null); - return ThreadUpdater.update(); - } else if (n > 0) { - return ThreadUpdater.set('timer', n); - } - }, - update: function() { - var url; - - if (!ThreadUpdater.online) { - return; - } - ThreadUpdater.seconds = 0; - if (Conf['Auto Update']) { - ThreadUpdater.set('timer', '...'); - } else { - ThreadUpdater.set('timer', 'Update'); - } - if (ThreadUpdater.req) { - ThreadUpdater.req.onloadend = null; - ThreadUpdater.req.abort(); - } - url = "//api.4chan.org/" + ThreadUpdater.thread.board + "/res/" + ThreadUpdater.thread + ".json"; - return ThreadUpdater.req = $.ajax(url, { - onloadend: ThreadUpdater.cb.load - }, { - whenModified: true - }); - }, - updateThreadStatus: function(title, OP) { - var icon, message, root, titleLC; - - titleLC = title.toLowerCase(); - if (ThreadUpdater.thread["is" + title] === !!OP[titleLC]) { - return; - } - if (!(ThreadUpdater.thread["is" + title] = !!OP[titleLC])) { - message = title === 'Sticky' ? 'The thread is not a sticky anymore.' : 'The thread is not closed anymore.'; - new Notice('info', message, 30); - $.rm($("." + titleLC + "Icon", ThreadUpdater.thread.OP.nodes.info)); - return; - } - message = title === 'Sticky' ? 'The thread is now a sticky.' : 'The thread is now closed.'; - new Notice('info', message, 30); - icon = $.el('img', { - src: "//static.4chan.org/image/" + titleLC + ".gif", - alt: title, - title: title, - className: "" + titleLC + "Icon" - }); - root = $('[title="Quote this post"]', ThreadUpdater.thread.OP.nodes.info); - if (title === 'Closed') { - root = $('.stickyIcon', ThreadUpdater.thread.OP.nodes.info) || root; - } - return $.after(root, [$.tn(' '), icon]); - }, - parse: function(postObjects) { - var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _len, _ref; - - OP = postObjects[0]; - Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; - ThreadUpdater.updateThreadStatus('Sticky', OP); - ThreadUpdater.updateThreadStatus('Closed', OP); - ThreadUpdater.thread.postLimit = !!OP.bumplimit; - ThreadUpdater.thread.fileLimit = !!OP.imagelimit; - posts = []; - index = []; - files = []; - count = 0; - for (_i = 0, _len = postObjects.length; _i < _len; _i++) { - postObject = postObjects[_i]; - num = postObject.no; - index.push(num); - if (postObject.fsize) { - files.push(num); - } - if (num <= ThreadUpdater.lastPost) { - continue; - } - count++; - node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID); - posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board)); - } - deletedPosts = []; - deletedFiles = []; - _ref = ThreadUpdater.thread.posts; - for (ID in _ref) { - post = _ref[ID]; - ID = +ID; - if (post.isDead && index.contains(ID)) { - post.resurrect(); - } else if (!index.contains(ID)) { - post.kill(); - deletedPosts.push(post); - } else if (post.file && !post.file.isDead && !files.contains(ID)) { - post.kill(true); - deletedFiles.push(post); - } - if (ThreadUpdater.postID && ThreadUpdater.postID === ID) { - ThreadUpdater.foundPost = true; - } - } - if (!count) { - ThreadUpdater.set('status', null, null); - ThreadUpdater.outdateCount++; - } else { - ThreadUpdater.set('status', "+" + count, 'new'); - ThreadUpdater.outdateCount = 0; - if (Conf['Beep'] && d.hidden && Unread.posts && !Unread.posts.length) { - if (!ThreadUpdater.audio) { - ThreadUpdater.audio = $.el('audio', { - src: ThreadUpdater.beep - }); - } - ThreadUpdater.audio.play(); - } - ThreadUpdater.lastPost = posts[count - 1].ID; - Main.callbackNodes(Post, posts); - scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25; - for (key in posts) { - post = posts[key]; - if (!posts.hasOwnProperty(key)) { - continue; - } - root = post.nodes.root; - if (post.cb) { - if (!post.cb.call(post)) { - $.add(ThreadUpdater.root, root); - } - } else { - $.add(ThreadUpdater.root, root); - } - } - if (scroll) { - if (Conf['Bottom Scroll']) { - window.scrollTo(0, d.body.clientHeight); - } else { - if (root) { - Header.scrollToPost(root); - } - } - } - $.queueTask(function() { - var length, threadID; - - threadID = ThreadUpdater.thread.ID; - length = $$('.thread > .postContainer', ThreadUpdater.root).length; - return Fourchan.parseThread(threadID, length - count, length); - }); - } - return $.event('ThreadUpdate', { - 404: false, - thread: ThreadUpdater.thread, - newPosts: posts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, - postCount: OP.replies + 1, - fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead) - }); - } - }; - - ThreadWatcher = { - init: function() { - var now, sc; - - if (!Conf['Thread Watcher']) { - return; - } - this.shortcut = sc = $.el('a', { - id: 'watcher-link', - textContent: 'Watcher', - href: 'javascript:;', - className: 'disabled fourchanx-icon icon-eye-open' - }); - this.db = new DataBoard('watchedThreads', this.refresh, true); - this.dialog = UI.dialog('thread-watcher', 'top: 50px; left: 0px;', "
Thread Watcher ×
"); - this.status = $('#watcher-status', this.dialog); - this.list = this.dialog.lastElementChild; - $.on(d, 'QRPostSuccessful', this.cb.post); - if (g.VIEW === 'thread') { - $.on(d, 'ThreadUpdate', this.cb.threadUpdate); - } - $.on(sc, 'click', this.toggleWatcher); - $.on($('.move>.close', ThreadWatcher.dialog), 'click', this.toggleWatcher); - $.on(d, '4chanXInitFinished', this.ready); - if (Conf['Toggleable Thread Watcher']) { - Header.addShortcut(sc); - $.addClass(doc, 'fixed-watcher'); - } - now = Date.now(); - if ((this.db.data.lastChecked || 0) < now - 2 * $.HOUR) { - this.db.data.lastChecked = now; - ThreadWatcher.fetchAllStatus(); - this.db.save(); - } - $.get('WatchedThreads', null, function(_arg) { - var WatchedThreads, boardID, data, threadID, threads, _ref; - - WatchedThreads = _arg.WatchedThreads; - if (!WatchedThreads) { - return; - } - _ref = ThreadWatcher.convert(WatchedThreads); - for (boardID in _ref) { - threads = _ref[boardID]; - for (threadID in threads) { - data = threads[threadID]; - ThreadWatcher.db.set({ - boardID: boardID, - threadID: threadID, - val: data - }); - } - } - return $["delete"]('WatchedThreads'); - }); - return Thread.prototype.callbacks.push({ - name: 'Thread Watcher', - cb: this.node - }); - }, - node: function() { - var toggler; - - toggler = $.el('img', { - className: 'watch-thread-link' - }); - $.on(toggler, 'click', ThreadWatcher.cb.toggle); - return $.before($('input', this.OP.nodes.post), toggler); - }, - ready: function() { - $.off(d, '4chanXInitFinished', ThreadWatcher.ready); - if (!Main.isThisPageLegit()) { - return; - } - ThreadWatcher.refresh(); - $.add(d.body, ThreadWatcher.dialog); - if (Conf['Toggleable Thread Watcher']) { - ThreadWatcher.dialog.hidden = true; - } - if (!Conf['Auto Watch']) { - return; - } - return $.get('AutoWatch', 0, function(_arg) { - var AutoWatch, thread; - - AutoWatch = _arg.AutoWatch; - if (!(thread = g.BOARD.threads[AutoWatch])) { - return; - } - ThreadWatcher.add(thread); - return $["delete"]('AutoWatch'); - }); - }, - toggleWatcher: function() { - $.toggleClass(ThreadWatcher.shortcut, 'disabled'); - return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden; - }, - cb: { - openAll: function() { - var a, _i, _len, _ref; - - if ($.hasClass(this, 'disabled')) { - return; - } - _ref = $$('a[title]', ThreadWatcher.list); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - a = _ref[_i]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - checkThreads: function() { - if ($.hasClass(this, 'disabled')) { - return; - } - return ThreadWatcher.fetchAllStatus(); - }, - pruneDeads: function() { - var boardID, data, threadID, _i, _len, _ref, _ref1; - - if ($.hasClass(this, 'disabled')) { - return; - } - _ref = ThreadWatcher.getAll(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], boardID = _ref1.boardID, threadID = _ref1.threadID, data = _ref1.data; - if (!data.isDead) { - continue; - } - delete ThreadWatcher.db.data.boards[boardID][threadID]; - ThreadWatcher.db.deleteIfEmpty({ - boardID: boardID - }); - } - ThreadWatcher.db.save(); - ThreadWatcher.refresh(); - return $.event('CloseMenu'); - }, - toggle: function() { - return ThreadWatcher.toggle(Get.postFromNode(this).thread); - }, - rm: function() { - var boardID, threadID, _ref; - - _ref = this.parentNode.dataset.fullID.split('.'), boardID = _ref[0], threadID = _ref[1]; - return ThreadWatcher.rm(boardID, +threadID); - }, - post: function(e) { - var board, postID, threadID, _ref; - - _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID; - if (postID === threadID) { - if (Conf['Auto Watch']) { - return $.set('AutoWatch', threadID); - } - } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(board.threads[threadID]); - } - }, - threadUpdate: function(e) { - var thread; - - thread = e.detail.thread; - if (!(e.detail[404] && ThreadWatcher.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - }))) { - return; - } - return ThreadWatcher.add(thread); - } - }, - fetchCount: { - fetched: 0, - fetching: 0 - }, - fetchAllStatus: function() { - var thread, threads, _i, _len; - - if (!(threads = ThreadWatcher.getAll()).length) { - return; - } - ThreadWatcher.status.textContent = '...'; - for (_i = 0, _len = threads.length; _i < _len; _i++) { - thread = threads[_i]; - ThreadWatcher.fetchStatus(thread); - } - }, - fetchStatus: function(_arg) { - var boardID, data, fetchCount, threadID; - - boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data; - if (data.isDead) { - return; - } - fetchCount = ThreadWatcher.fetchCount; - fetchCount.fetching++; - return $.ajax("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", { - onloadend: function() { - var status; - - fetchCount.fetched++; - if (fetchCount.fetched === fetchCount.fetching) { - fetchCount.fetched = 0; - fetchCount.fetching = 0; - status = ''; - } else { - status = "" + (Math.round(fetchCount.fetched / fetchCount.fetching * 100)) + "%"; - } - ThreadWatcher.status.textContent = status; - if (this.status !== 404) { - return; - } - if (Conf['Auto Prune']) { - ThreadWatcher.rm(boardID, threadID); - } else { - data.isDead = true; - ThreadWatcher.db.set({ - boardID: boardID, - threadID: threadID, - val: data - }); - } - return ThreadWatcher.refresh(); - } - }, { - type: 'head' - }); - }, - getAll: function() { - var all, boardID, data, threadID, threads, _ref; - - all = []; - _ref = ThreadWatcher.db.data.boards; - for (boardID in _ref) { - threads = _ref[boardID]; - if (Conf['Current Board'] && boardID !== g.BOARD.ID) { - continue; - } - for (threadID in threads) { - data = threads[threadID]; - all.push({ - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - return all; - }, - makeLine: function(boardID, threadID, data) { - var div, fullID, href, link, x; - - x = $.el('a', { - textContent: '×', - href: 'javascript:;' - }); - $.on(x, 'click', ThreadWatcher.cb.rm); - if (data.isDead) { - href = Redirect.to('thread', { - boardID: boardID, - threadID: threadID - }); - } - link = $.el('a', { - href: href || ("/" + boardID + "/res/" + threadID), - textContent: data.excerpt, - title: data.excerpt - }); - div = $.el('div'); - fullID = "" + boardID + "." + threadID; - div.dataset.fullID = fullID; - if (g.VIEW === 'thread' && fullID === ("" + g.BOARD + "." + g.THREADID)) { - $.addClass(div, 'current'); - } - if (data.isDead) { - $.addClass(div, 'dead-thread'); - } - $.add(div, [x, $.tn(' '), link]); - return div; - }, - refresh: function() { - var boardID, data, helper, list, nodes, refresher, thread, threadID, toggler, watched, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; - - nodes = []; - _ref = ThreadWatcher.getAll(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], boardID = _ref1.boardID, threadID = _ref1.threadID, data = _ref1.data; - nodes.push(ThreadWatcher.makeLine(boardID, threadID, data)); - } - list = ThreadWatcher.list; - $.rmAll(list); - $.add(list, nodes); - _ref2 = g.BOARD.threads; - for (threadID in _ref2) { - thread = _ref2[threadID]; - toggler = $('.watch-thread-link', thread.OP.nodes.post); - watched = ThreadWatcher.db.get({ - boardID: thread.board.ID, - threadID: threadID - }); - helper = watched ? ['addClass', 'Unwatch'] : ['rmClass', 'Watch']; - $[helper[0]](toggler, 'watched'); - toggler.title = "" + helper[1] + " Thread"; - } - _ref3 = ThreadWatcher.menu.refreshers; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - refresher = _ref3[_j]; - refresher(); - } - }, - toggle: function(thread) { - var boardID, threadID; - - boardID = thread.board.ID; - threadID = thread.ID; - if (ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - return ThreadWatcher.rm(boardID, threadID); - } else { - return ThreadWatcher.add(thread); - } - }, - add: function(thread) { - var boardID, data, threadID; - - data = {}; - boardID = thread.board.ID; - threadID = thread.ID; - if (thread.isDead) { - if (Conf['Auto Prune'] && ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - ThreadWatcher.rm(boardID, threadID); - return; - } - data.isDead = true; - } - data.excerpt = Get.threadExcerpt(thread); - ThreadWatcher.db.set({ - boardID: boardID, - threadID: threadID, - val: data - }); - return ThreadWatcher.refresh(); - }, - rm: function(boardID, threadID) { - ThreadWatcher.db["delete"]({ - boardID: boardID, - threadID: threadID - }); - return ThreadWatcher.refresh(); - }, - convert: function(oldFormat) { - var boardID, data, newFormat, threadID, threads; - - newFormat = {}; - for (boardID in oldFormat) { - threads = oldFormat[boardID]; - for (threadID in threads) { - data = threads[threadID]; - (newFormat[boardID] || (newFormat[boardID] = {}))[threadID] = { - excerpt: data.textContent - }; - } - } - return newFormat; - }, - menu: { - refreshers: [], - init: function() { - var menu; - - if (!Conf['Thread Watcher']) { - return; - } - menu = new UI.Menu('thread watcher'); - $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { - return menu.toggle(e, this, ThreadWatcher); - }); - this.addHeaderMenuEntry(); - return this.addMenuEntries(); - }, - addHeaderMenuEntry: function() { - var entryEl; - - if (g.VIEW !== 'thread') { - return; - } - entryEl = $.el('a', { - href: 'javascript:;' - }); - $.event('AddMenuEntry', { - type: 'header', - el: entryEl, - order: 60 - }); - $.on(entryEl, 'click', function() { - return ThreadWatcher.toggle(g.threads["" + g.BOARD + "." + g.THREADID]); - }); - return this.refreshers.push(function() { - var addClass, rmClass, text, _ref; - - _ref = $('.current', ThreadWatcher.list) ? ['unwatch-thread', 'watch-thread', 'Unwatch thread'] : ['watch-thread', 'unwatch-thread', 'Watch thread'], addClass = _ref[0], rmClass = _ref[1], text = _ref[2]; - $.addClass(entryEl, addClass); - $.rmClass(entryEl, rmClass); - return entryEl.textContent = text; - }); - }, - addMenuEntries: function() { - var cb, conf, entries, entry, name, refresh, subEntries, _i, _len, _ref, _ref1, _results; - - entries = []; - entries.push({ - cb: ThreadWatcher.cb.openAll, - entry: { - type: 'thread watcher', - el: $.el('a', { - textContent: 'Open all threads' - }) - }, - refresh: function() { - return (ThreadWatcher.list.firstElementChild ? $.rmClass : $.addClass)(this.el, 'disabled'); - } - }); - entries.push({ - cb: ThreadWatcher.cb.checkThreads, - entry: { - type: 'thread watcher', - el: $.el('a', { - textContent: 'Check 404\'d threads' - }) - }, - refresh: function() { - return ($('div:not(.dead-thread)', ThreadWatcher.list) ? $.rmClass : $.addClass)(this.el, 'disabled'); - } - }); - entries.push({ - cb: ThreadWatcher.cb.pruneDeads, - entry: { - type: 'thread watcher', - el: $.el('a', { - textContent: 'Prune 404\'d threads' - }) - }, - refresh: function() { - return ($('.dead-thread', ThreadWatcher.list) ? $.rmClass : $.addClass)(this.el, 'disabled'); - } - }); - subEntries = []; - _ref = Config.threadWatcher; - for (name in _ref) { - conf = _ref[name]; - subEntries.push(this.createSubEntry(name, conf[1])); - } - entries.push({ - entry: { - type: 'thread watcher', - el: $.el('span', { - textContent: 'Settings' - }), - subEntries: subEntries - } - }); - _results = []; - for (_i = 0, _len = entries.length; _i < _len; _i++) { - _ref1 = entries[_i], entry = _ref1.entry, cb = _ref1.cb, refresh = _ref1.refresh; - if (entry.el.nodeName === 'A') { - entry.el.href = 'javascript:;'; - } - if (cb) { - $.on(entry.el, 'click', cb); - } - if (refresh) { - this.refreshers.push(refresh.bind(entry)); - } - _results.push($.event('AddMenuEntry', entry)); - } - return _results; - }, - createSubEntry: function(name, desc) { - var entry, input; - - entry = { - type: 'thread watcher', - el: $.el('label', { - innerHTML: " " + name, - title: desc - }) - }; - input = entry.el.firstElementChild; - input.checked = Conf[name]; - $.on(input, 'change', $.cb.checked); - if (name === 'Current Board') { - $.on(input, 'change', ThreadWatcher.refresh); - } - return entry; - } - } - }; - - Unread = { - init: function() { - if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) { - return; - } - this.db = new DataBoard('lastReadPosts', this.sync); - this.hr = $.el('hr', { - id: 'unread-line' - }); - this.posts = []; - this.postsQuotingYou = []; - return Thread.prototype.callbacks.push({ - name: 'Unread', - cb: this.node - }); - }, - node: function() { - Unread.thread = this; - Unread.title = d.title; - Unread.lastReadPost = Unread.db.get({ - boardID: this.board.ID, - threadID: this.ID, - defaultValue: 0 - }); - $.on(d, '4chanXInitFinished', Unread.ready); - $.on(d, 'ThreadUpdate', Unread.onUpdate); - $.on(d, 'scroll visibilitychange', Unread.read); - if (Conf['Unread Line']) { - return $.on(d, 'visibilitychange', Unread.setLine); - } - }, - ready: function() { - var ID, post, posts, _ref; - - $.off(d, '4chanXInitFinished', Unread.ready); - posts = []; - _ref = Unread.thread.posts; - for (ID in _ref) { - post = _ref[ID]; - if (post.isReply) { - posts.push(post); - } - } - Unread.addPosts(posts); - return Unread.scroll(); - }, - scroll: function() { - var checkPosition, hash, onload, post, posts, root; - - if (!Conf['Scroll to Last Read Post']) { - return; - } - if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { - return; - } - if (post = Unread.posts[0]) { - while (root = $.x('preceding-sibling::div[contains(@class,"replyContainer")][1]', post.nodes.root)) { - if (!(post = Get.postFromRoot(root)).isHidden) { - break; - } - } - if (!root) { - return; - } - onload = function() { - if (checkPosition(root)) { - return root.scrollIntoView(false); - } - }; - } else { - posts = Object.keys(Unread.thread.posts); - root = Unread.thread.posts[posts[posts.length - 1]].nodes.root; - onload = function() { - if (checkPosition(root)) { - return Header.scrollToPost(root); - } - }; - } - checkPosition = function(target) { - return target.getBoundingClientRect().bottom > doc.clientHeight; - }; - return $.on(window, 'load', onload); - }, - sync: function() { - var lastReadPost; - - lastReadPost = Unread.db.get({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - defaultValue: 0 - }); - if (!(Unread.lastReadPost < lastReadPost)) { - return; - } - Unread.lastReadPost = lastReadPost; - Unread.readArray(Unread.posts); - Unread.readArray(Unread.postsQuotingYou); - if (Conf['Unread Line']) { - Unread.setLine(); - } - return Unread.update(); - }, - addPosts: function(posts) { - var ID, data, post, _i, _len; - - for (_i = 0, _len = posts.length; _i < _len; _i++) { - post = posts[_i]; - ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden) { - continue; - } - if (QR.db) { - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (QR.db.get(data)) { - continue; - } - } - Unread.posts.push(post); - Unread.addPostQuotingYou(post); - } - if (Conf['Unread Line']) { - Unread.setLine(posts.contains(Unread.posts[0])); - } - Unread.read(); - return Unread.update(); - }, - addPostQuotingYou: function(post) { - var quotelink, _i, _len, _ref; - - if (!QR.db) { - return; - } - _ref = post.nodes.quotelinks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quotelink = _ref[_i]; - if (!(QR.db.get(Get.postDataFromLink(quotelink)))) { - continue; - } - Unread.postsQuotingYou.push(post); - Unread.openNotification(post); - } - }, - openNotification: function(post) { - var name, notif; - - if (!Header.areNotificationsEnabled) { - return; - } - name = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', post.nodes.info).textContent.trim(); - notif = new Notification("" + name + " replied to you", { - body: post.info.comment, - icon: Favicon.logo - }); - notif.onclick = function() { - Header.scrollToPost(post.nodes.root); - return window.focus(); - }; - return setTimeout(function() { - return notif.close(); - }, 7 * $.SECOND); - }, - onUpdate: function(e) { - if (e.detail[404]) { - return Unread.update(); - } else { - return Unread.addPosts(e.detail.newPosts); - } - }, - readSinglePost: function(post) { - var i; - - if ((i = Unread.posts.indexOf(post)) === -1) { - return; - } - Unread.posts.splice(i, 1); - if (i === 0) { - Unread.lastReadPost = post.ID; - Unread.saveLastReadPost(); - } - if ((i = Unread.postsQuotingYou.indexOf(post)) !== -1) { - Unread.postsQuotingYou.splice(i, 1); - } - return Unread.update(); - }, - readArray: function(arr) { - var i, post, _i, _len; - - for (i = _i = 0, _len = arr.length; _i < _len; i = ++_i) { - post = arr[i]; - if (post.ID > Unread.lastReadPost) { - break; - } - } - return arr.splice(0, i); - }, - read: $.debounce(50, function(e) { - var ID, height, i, post, posts; - - if (d.hidden || !Unread.posts.length) { - return; - } - height = doc.clientHeight; - posts = Unread.posts; - i = 0; - while (post = posts[i]) { - if (post.nodes.root.getBoundingClientRect().bottom < height) { - ID = post.ID; - if (Conf['Mark Quotes of You']) { - if (post.info.yours) { - QuoteYou.lastRead = post.nodes.root; - } - } - if (Conf['Quote Threading']) { - posts.splice(i, 1); - continue; - } - } else { - if (!Conf['Quote Threading']) { - break; - } - } - i++; - } - if (i && !Conf['Quote Threading']) { - posts.splice(0, i); - } - if (!ID) { - return; - } - if (Unread.lastReadPost < ID || !Unread.lastReadPost) { - Unread.lastReadPost = ID; - } - Unread.saveLastReadPost(); - Unread.readArray(Unread.postsQuotingYou); - if (e) { - return Unread.update(); - } - }), - saveLastReadPost: $.debounce(2 * $.SECOND, function() { - if (Unread.thread.isDead) { - return; - } - return Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: Unread.lastReadPost - }); - }), - setLine: function(force) { - var post; - - if (!(d.hidden || force === true)) { - return; - } - if (!(post = Unread.posts[0])) { - return $.rm(Unread.hr); - } - if ($.x('preceding-sibling::div[contains(@class,"replyContainer")]', post.nodes.root)) { - return $.before(post.nodes.root, Unread.hr); - } - }, - update: function() { - var count; - - count = Unread.posts.length; - if (Conf['Unread Count']) { - d.title = "" + (Conf['Quoted Title'] && Unread.postsQuotingYou.length ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? "/" + g.BOARD + "/ - 404" : "" + Unread.title); - } - if (!Conf['Unread Favicon']) { - return; - } - Favicon.el.href = g.DEAD ? Unread.postsQuotingYou[0] ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? Unread.postsQuotingYou[0] ? Favicon.unreadY : Favicon.unread : Favicon["default"]; - return $.add(d.head, Favicon.el); - } - }; - - Redirect = { - data: { - thread: {}, - post: {}, - file: {} - }, - init: function() { - var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2; - - _ref = Conf['selectedArchives']; - for (boardID in _ref) { - data = _ref[boardID]; - for (type in data) { - id = data[type]; - if (archive = Redirect.archives[id]) { - boards = archive[type] || archive['boards']; - if (!boards.contains(boardID)) { - continue; - } - Redirect.data[type][boardID] = archive; - } - } - } - _ref1 = Redirect.archives; - for (name in _ref1) { - archive = _ref1[name]; - _ref2 = archive.boards; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - boardID = _ref2[_i]; - if (!(boardID in Redirect.data.thread)) { - Redirect.data.thread[boardID] = archive; - } - if (!(boardID in Redirect.data.post || archive.software !== 'foolfuuka')) { - Redirect.data.post[boardID] = archive; - } - if (!(boardID in Redirect.data.file || !archive.files.contains(boardID))) { - Redirect.data.file[boardID] = archive; - } - } - } - }, - archives: { - '4plebs': { - domain: 'archive.4plebs.org', - http: true, - software: 'foolfuuka', - boards: ['hr', 'tg', 'tv', 'x'], - files: ['hr', 'tg', 'tv', 'x'] - }, - 'fap archive': { - domain: 'fuuka.worldathleticproject.org', - http: true, - https: false, - software: 'foolfuuka', - boards: ['b', 'e', 'h', 'hc', 'p', 's', 'u'], - files: ['b', 'e', 'h', 'hc', 'p', 's', 'u'] - }, - 'Foolz': { - domain: 'archive.foolz.us', - http: false, - https: true, - software: 'foolfuuka', - boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg'], - files: ['a', 'gd', 'jp', 'm', 'q', 'tg', 'vg', 'vp', 'vr', 'wsg'] - }, - 'Foolz a Shit': { - domain: 'archive.foolzashit.com', - http: true, - https: true, - software: 'foolfuuka', - boards: ['adv', 'asp', 'cm', 'd', 'e', 'i', 'lgbt', 'n', 'o', 'p', 'pol', 's', 's4s', 't', 'trv', 'y'], - files: ['cm', 'd', 'e', 'i', 'n', 'o', 'p', 's', 'trv', 'y'] - }, - 'Foolz Beta': { - domain: 'beta.foolz.us', - http: true, - https: true, - withCredentials: true, - software: 'foolfuuka', - boards: ['a', 'co', 'gd', 'h', 'jp', 'm', 'mlp', 'q', 'sp', 'tg', 'tv', 'u', 'v', 'vg', 'vp', 'vr', 'wsg'], - files: ['a', 'gd', 'h', 'jp', 'm', 'q', 'tg', 'u', 'vg', 'vp', 'vr', 'wsg'] - }, - 'Heinessen': { - domain: 'archive.heinessen.com', - http: true, - software: 'fuuka', - boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy'], - files: ['an', 'k', 'toy'] - }, - 'Install Gentoo': { - domain: 'archive.installgentoo.net', - http: false, - https: true, - software: 'fuuka', - boards: ['diy', 'g', 'sci'], - files: [] - }, - 'NSFW Foolz': { - domain: 'nsfw.foolz.us', - http: false, - https: true, - software: 'foolfuuka', - boards: ['u'], - files: ['u'] - }, - 'Nyafuu': { - domain: 'archive.nyafuu.org', - http: true, - https: true, - software: 'foolfuuka', - boards: ['c', 'w', 'wg'], - files: ['c', 'w', 'wg'] - }, - 'Rebecca Black Tech': { - domain: 'rbt.asia', - http: true, - https: true, - software: 'fuuka', - boards: ['cgl', 'g', 'mu', 'w'], - files: ['cgl', 'g', 'mu', 'w'] - }, - 'The Dark Cave': { - domain: 'archive.thedarkcave.org', - http: true, - https: true, - software: 'foolfuuka', - boards: ['c', 'int', 'out', 'po'], - files: ['c', 'po'] - }, - 'warosu': { - domain: 'fuuka.warosu.org', - http: true, - https: true, - software: 'fuuka', - boards: ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 'tg', 'vr'], - files: ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 'tg', 'vr'] - } - }, - to: function(dest, data) { - var archive; - - archive = (dest === 'search' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; - if (!archive) { - return ''; - } - return Redirect[dest](archive, data); - }, - protocol: function(archive) { - var protocol; - - protocol = location.protocol; - if (!archive[protocol.slice(0, -1)]) { - protocol = protocol === 'https:' ? 'http:' : 'https:'; - } - return "" + protocol + "//"; - }, - thread: function(archive, _arg) { - var boardID, path, postID, threadID; - - boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; - path = threadID ? "" + boardID + "/thread/" + threadID : "" + boardID + "/post/" + postID; - if (archive.software === 'foolfuuka') { - path += '/'; - } - if (threadID && postID) { - path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - post: function(archive, _arg) { - var URL, boardID, postID, protocol; - - boardID = _arg.boardID, postID = _arg.postID; - protocol = Redirect.protocol(archive); - if (['Foolz', 'NSFW Foolz'].contains(archive.name)) { - protocol = 'https://'; - } - URL = new String("" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID); - URL.archive = archive; - return URL; - }, - file: function(archive, _arg) { - var boardID, filename; - - boardID = _arg.boardID, filename = _arg.filename; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; - }, - search: function(archive, _arg) { - var boardID, path, type, value; - - boardID = _arg.boardID, type = _arg.type, value = _arg.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - value = encodeURIComponent(value); - path = archive.software === 'foolfuuka' ? "" + boardID + "/search/" + type + "/" + value : "" + boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - } - }; - - PSAHiding = { - init: function() { - if (!Conf['Announcement Hiding']) { - return; - } - $.addClass(doc, 'hide-announcement'); - return $.on(d, '4chanXInitFinished', this.setup); - }, - setup: function() { - var btn, entry, psa; - - $.off(d, '4chanXInitFinished', PSAHiding.setup); - if (!(psa = $.id('globalMessage'))) { - $.rmClass(doc, 'hide-announcement'); - return; - } - entry = { - type: 'header', - el: $.el('a', { - textContent: 'Show announcement', - className: 'show-announcement', - href: 'javascript:;' - }), - order: 50, - open: function() { - return psa.hidden; - } - }; - $.event('AddMenuEntry', entry); - $.on(entry.el, 'click', PSAHiding.toggle); - PSAHiding.btn = btn = $.el('a', { - innerHTML: ' - ', - title: 'Hide announcement.', - className: 'hide-announcement', - href: 'javascript:;' - }); - $.on(btn, 'click', PSAHiding.toggle); - $.get('hiddenPSA', 0, function(_arg) { - var hiddenPSA; - - hiddenPSA = _arg.hiddenPSA; - PSAHiding.sync(hiddenPSA); - $.before(psa, btn); - return $.rmClass(doc, 'hide-announcement'); - }); - return $.sync('hiddenPSA', PSAHiding.sync); - }, - toggle: function(e) { - var UTC; - - if ($.hasClass(this, 'hide-announcement')) { - UTC = +$.id('globalMessage').dataset.utc; - $.set('hiddenPSA', UTC); - } else { - $.event('CloseMenu'); - $["delete"]('hiddenPSA'); - } - return PSAHiding.sync(UTC); - }, - sync: function(UTC) { - var hr, psa; - - psa = $.id('globalMessage'); - psa.hidden = PSAHiding.btn.hidden = UTC && UTC >= +psa.dataset.utc ? true : false; - if ((hr = psa.nextElementSibling) && hr.nodeName === 'HR') { - return hr.hidden = psa.hidden; - } - } - }; - - Banner = { - init: function() { - return $.asap((function() { - return d.body; - }), function() { - return $.asap((function() { - return $('.abovePostForm'); - }), Banner.ready); - }); - }, - ready: function() { - var banner, child, children, i; - - banner = $(".boardBanner"); - children = banner.children; - i = 0; - while (child = children[i++]) { - if (i === 1) { - child.id = "Banner"; - child.title = "Click to change"; - $.on(child, 'click', Banner.cb.toggle); - continue; - } - if (Conf['Custom Board Titles']) { - Banner.custom(child).title = "Ctrl+click to edit board " + (i === 3 ? 'sub' : '') + "title"; - child.spellcheck = false; - } - } - }, - cb: { - toggle: (function() { - var types; - - types = { - jpg: 227, - png: 270, - gif: 253 - }; - return function() { - var num, type; - - type = Object.keys(types)[Math.floor(3 * Math.random())]; - num = Math.floor(types[type] * Math.random()); - return this.src = "//static.4chan.org/image/title/" + num + "." + type; - }; - })(), - click: function(e) { - if (e.ctrlKey) { - this.contentEditable = true; - return this.focus(); - } - }, - keydown: function(e) { - e.stopPropagation(); - if (!e.shiftKey && e.keyCode === 13) { - return this.blur(); - } - }, - focus: function() { - var items, string, string2; - - this.textContent = this.innerHTML; - string = "" + g.BOARD + "." + this.className; - string2 = "" + string + ".orig"; - items = { - title: this.innerHTML - }; - items[string] = ''; - items[string2] = false; - $.get(items, function(items) { - if (!(items[string2] && items.title === items[string])) { - return $.set(string2, items.title); - } - }); - }, - blur: function() { - this.innerHTML = this.textContent; - this.contentEditable = false; - return $.set("" + g.BOARD + "." + this.className, this.textContent); - } - }, - custom: function(child) { - var cachedTest, string; - - cachedTest = child.innerHTML; - string = "" + g.BOARD + "." + child.className; - $.on(child, 'click keydown focus blur', function(e) { - return Banner.cb[e.type].apply(this, [e]); - }); - $.get(string, cachedTest, function(item) { - var string2, title; - - if (!(title = item[string])) { - return; - } - if (Conf['Persistent Custom Board Titles']) { - return child.innerHTML = title; - } - string2 = "" + string + ".orig"; - return $.get(string2, cachedTest, function(itemb) { - if (cachedTest === itemb[string2]) { - return child.innerHTML = title; - } else { - $.set(string, cachedTest); - return $.set(string2, cachedTest); - } - }); - }); - return child; - } - }; - - CatalogLinks = { - init: function() { - var el, input; - - if (!Conf['Catalog Links']) { - return; - } - el = $.el('label', { - id: 'toggleCatalog', - href: 'javascript:;', - innerHTML: " Catalog Links", - title: "Turn catalog links " + (Conf['Header catalog links'] ? 'off' : 'on') + "." - }); - input = $('input', el); - $.on(input, 'change', this.toggle); - $.sync('Header catalog links', CatalogLinks.set); - $.event('AddMenuEntry', { - type: 'header', - el: el, - order: 95 - }); - return $.on(d, '4chanXInitFinished', function() { - return CatalogLinks.set(Conf['Header catalog links']); - }); - }, - toggle: function() { - var useCatalog; - - $.event('CloseMenu'); - $.set('Header catalog links', useCatalog = this.checked); - return CatalogLinks.set(useCatalog); - }, - set: function(useCatalog) { - var a, board, path, _i, _len, _ref; - - path = useCatalog ? 'catalog' : ''; - _ref = $$("#board-list a[href*=\"boards.4chan.org\"]:not(.catalog),\n#boardNavDesktopFoot a[href*=\"boards.4chan.org\"]"); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - a = _ref[_i]; - board = a.pathname.split('/')[1]; - if (['f', 'status', '4chan'].contains(board) || !board) { - continue; - } - if (Conf['External Catalog']) { - a.href = useCatalog ? CatalogLinks.external(board) : "//boards.4chan.org/" + board + "/"; - } else { - a.pathname = "/" + board + "/" + path; - } - } - return this.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; - }, - external: function(board) { - return (['a', 'c', 'g', 'co', 'k', 'm', 'o', 'p', 'v', 'vg', 'w', 'cm', '3', 'adv', 'an', 'cgl', 'ck', 'diy', 'fa', 'fit', 'int', 'jp', 'mlp', 'lit', 'mu', 'n', 'po', 'sci', 'toy', 'trv', 'tv', 'vp', 'x', 'q'].contains(board) ? "http://catalog.neet.tv/" + board : ['d', 'e', 'gif', 'h', 'hr', 'hc', 'r9k', 's', 'pol', 'soc', 'u', 'i', 'ic', 'hm', 'r', 'w', 'wg', 'wsg', 't', 'y'].contains(board) ? "http://4index.gropes.us/" + board : "//boards.4chan.org/" + board + "/catalog"); - } - }; - - IDColor = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Color User IDs']) { - return; - } - this.ids = {}; - return Post.prototype.callbacks.push({ - name: 'Color User IDs', - cb: this.node - }); - }, - node: function() { - var rgb, span, style, uid; - - if (this.isClone || !(uid = this.info.uniqueID)) { - return; - } - span = $('.hand', this.nodes.uniqueID); - if (!(span && span.nodeName === 'SPAN')) { - return; - } - rgb = IDColor.compute(uid); - style = span.style; - style.color = rgb[3]; - style.backgroundColor = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; - $.addClass(span, 'painted'); - return span.title = 'Highlight posts by this ID'; - }, - compute: function(uid) { - var hash, rgb; - - if (IDColor.ids[uid]) { - return IDColor.ids[uid]; - } - hash = IDColor.hash(uid); - rgb = [(hash >> 24) & 0xFF, (hash >> 16) & 0xFF, (hash >> 8) & 0xFF]; - rgb[3] = (rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) > 125 ? '#000' : '#fff'; - return this.ids[uid] = rgb; - }, - hash: function(uid) { - var i, msg; - - msg = 0; - i = 0; - while (i < 8) { - msg = (msg << 5) - msg + uid.charCodeAt(i++); - } - return msg; - } - }; - - CustomCSS = { - init: function() { - if (!Conf['Custom CSS']) { - return; - } - return this.addStyle(); - }, - addStyle: function() { - return this.style = $.addStyle(Conf['usercss']); - }, - rmStyle: function() { - if (this.style) { - $.rm(this.style); - return delete this.style; - } - }, - update: function() { - if (!this.style) { - this.addStyle(); - } - return this.style.textContent = Conf['usercss']; - } - }; - - Dice = { - init: function() { - if (g.BOARD.ID !== 'tg' || g.VIEW === 'catalog' || !Conf['Show Dice Roll']) { - return; - } - return Post.prototype.callbacks.push({ - name: 'Show Dice Roll', - cb: this.node - }); - }, - node: function() { - var dicestats, roll, _ref; - - if (this.isClone || !(dicestats = (_ref = this.info.email) != null ? _ref.match(/dice[+\s](\d+)d(\d+)/) : void 0)) { - return; - } - roll = $('b', this.nodes.comment).firstChild; - return roll.data = "Rolled " + dicestats[1] + "d" + dicestats[2] + ": " + (roll.data.slice(7)); - } - }; - - Emoji = { - init: function() { - var css, icon, name, pos, _ref; - - if (!Conf['Emoji']) { - return; - } - pos = Conf['emojiPos']; - css = ["a.useremail[href]:last-of-type::" + pos + " {\n vertical-align: top;\n margin-" + (pos === "before" ? "right" : "left") + ": 5px;\n}\n"]; - this.icons["PlanNine"] = Emoji.icons["Plan9"]; - this.icons['Sage'] = Emoji.sage[Conf['sageEmoji']]; - _ref = this.icons; - for (name in _ref) { - icon = _ref[name]; - if (!this.icons.hasOwnProperty(name)) { - continue; - } - css.push("a.useremail[href*='" + name + "']:last-of-type::" + pos + ",\na.useremail[href*='" + (name.toLowerCase()) + "']:last-of-type::" + pos + ",\na.useremail[href*='" + (name.toUpperCase()) + "']:last-of-type::" + pos + " {\n content: url('data:image/png;base64," + icon + "');\n}\n"); - } - return $.addStyle(css.join(""), 'emoji'); - }, - sage: { - '4chan SS': 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAa9JREFUKFOdkt0rg2EUwM95b2zlL0CRRLngksznXrJsNtYW1tjYhM3mY6+IXZAbikhTKJp8XZAp81UmWYhIRHHhUi60e7s6ntdCa2449es8PfU7z+k5B6AbyuE/wQlc4BcO2d06unAUBCgFE0hianOd3NHIcy8NPwrUf9NBPZcOEi7ayXZiea/1V7+ljaXeYAfOgg2So2TOwQWGnwQafOgi962TnMFmatozUeNu4yetASspVvgXiUvii5K5Nm6z56ol3Hdtpy+cwSYy+HRUt1nLsoEato0kXyh6wTac+24brThWv6MNOYNW9prlG/uxmbRrFaT0VrCspZoNPSUNJNyCBcoiLZuhLH0o9U6UrAfGKCz7RlLM81Q8XUwqr4oKPLIQmnA8IupBigacVy7yrya/2JouhryJHJJNykg+UxLGOtz6+SQNpEiMcduls4Wvoli9WklVKz+ol5SU4U6ngql8Qj2eRI+GyajBhSRH4r3cUxhSeRVhsYBmWUWiyM+UMDmDUI2nsfuSC1I27nLgYZJlP8jhjJ3PY8iE+L8tWx4kQC6MQA5b1D9HNiRCFhx8AF/e2qh92VnKAAAAAElFTkSuQmCC', - 'appchan': 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAABa1BMVEUAAACqrKiCgYIAAAAAAAAAAACHmX5pgl5NUEx/hnx4hXRSUVMiIyKwrbFzn19SbkZ1d3OvtqtpaWhcX1ooMyRsd2aWkZddkEV8vWGcpZl+kHd7jHNdYFuRmI4bHRthaV5WhUFsfGZReUBFZjdJazpGVUBnamYfHB9TeUMzSSpHgS1cY1k1NDUyOC8yWiFywVBoh1lDSEAZHBpucW0ICQgUHhBjfFhCRUA+QTtEQUUBAQFyo1praWspKigWFRZHU0F6j3E9Oz5VWFN0j2hncWONk4sAAABASDxJWkJKTUgAAAAvNC0fJR0DAwMAAAA9QzoWGhQAAAA8YytvrFOJsnlqyT9oqExqtkdrsExpsUsqQx9rpVJDbzBBbi5utk9jiFRuk11iqUR64k5Wf0JIZTpadk5om1BkyjmF1GRNY0FheFdXpjVXhz86XSp2yFJwslR3w1NbxitbtDWW5nNnilhFXTtYqDRwp1dSijiJ7H99AAAAUnRSTlMAJTgNGQml71ypu3cPEN/RDh8HBbOwQN7wVg4CAQZ28vs9EDluXjo58Ge8xwMy0P3+rV8cT73sawEdTv63NAa3rQwo4cUdAl3hWQSWvS8qqYsjEDiCzAAAAIVJREFUeNpFx7GKAQAYAOD/A7GbZVAWZTBZFGQw6LyCF/MIkiTdcOmWSzYbJVE2u1KX0J1v+8QDv/EkyS0yXF/NgeEILiHfyc74mICTQltqYXBeAWU9HGxU09YqqEvAElGjyZYjPyLqitjzHSEiGkrsfMWr0VLe+oy/djGP//YwfbeP8bN3Or0bkqEVblAAAAAASUVORK5CYII=' - }, - icons: { - 'Plan9': 'iVBORw0KGgoAAAANSUhEUgAAAAwAAAAPCAYAAAGn5h7fAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAzE15J1s7QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVQoz3WSz4sSARTHvzMjygpqYg3+KIhkE83DKtKlf0C9SrTRuZNEx0VowU6CuSeJNlwwpEO2kJ6SQBiIUAzFjRDF4wrjKosnGx3HmdehFDfpe/2+z/s++D5gU7IsEwRByICIiAEAIiIAYAFAXsjYVr/fLxMRNVvN+prJ5/OA3+/XERFNf02JyeVyDx0OxyvLNQsnimLKfcf9KRQKXQAAnE6nlf5qMpnQycnbP/kAoKoqsSwLAJhOp+AAwOv1otvtpqxWq73dbt/r9XqvEQ6HUalUEvF4XLd5IpvNZqlerzd5nlf6/f6tTCZjBACk0+nb+XxeW4UrikLJZPImAGA0Gq0NIqJyuSyyANDr9Q5Wu1utFvR6/SULAI1G4+vK8Pv90DTtGwsAJpPpaGUYDAZ0Op3PHAAEg8H3tVqtbrtu21sqyxuRSOQJk0ql9IvF4r7b7f7pcrlejkaj57IsH58Pzp8dvjhc/lsBk0gkbLFYrFqtVvd27+4qOk733ePxPDCbzVBVFfP5fCiK4rvhxfDN/qP9wSasGwwGMv1HiqJQsVg8ZlfTHMepkiR1t05gGJBGmM/nMBqNj9nN9kql0lNN064ARISzH2cQBAGz2ewLu2na7XYLwzBbvxYIBBCNRrFj3BmsAZ/PZ+J5/kOhUIAkSVeA8XiMZqt5efrx9OA3GfcgvyVno9cAAAAASUVORK5CYII=', - 'Neko': 'iVBORw0KGgoAAAANSUhEUgAAABMAAAARCAMAAAAIRmf1AAACoFBMVEUAAABnUFZoUVddU1T6+PvFwLzn4eFXVlT/+vZpZGCgm5dKU1Cfnpz//flbWljr5uLp5OCalpNZWFb//f3r6+n28ff9+PRaVVH59Pr//vr38vj57/Dp7eyjn5zq8O5aVVJbYV9nVFhjUFRiWFlZVlFgZGOboJzm5uZhamfz9/bt8fDw6+drb26bl5j/8/lkX1z06uldWFS5r61UT0tfWlbDwr3Ew76moqNRTU7Mx8P75OpeY19pWl1XW1qzr6x5eHaLiojv7+1UT0xIU0uzqadVS0nV0MxkZGT5+PPk497///ra29Xq5eFtY2H28e2hnJignJlUUE1dXV2vrqxkY2FkYF/m3d5vZmfDuruhl5aZlJHx8O75+PZWVVP29vT/9fTj3trv6ubh5eRdXFqTkpBOTUtqZmX88/RMQ0T78vPEvr7HwcHDwsDq6ef///3Gx8H++fXEv7tZWVedmZZXXVudnJp0c3FZU1f79fnb1dlXUVVjXWFrZmy8t7359/qLj455e3q4s69vamZjX1zy4+avpaReWFz/+f1NR0vu6Ozp4+f48/lnYmi8ur3Iw7/69fHz7+xbV1SZmJZVUk1ZV1zq5ez++f/c196uqbDn4uj9+P7z7vRVVVXt6ORiXl/OycXHw8CPi4ihoJ5aWF3/+v/k3+axrLOsp67LzMZYU1m2sq9dWF5WUU1WUk/Au7eYlJGqpqObmphYVV749f7p5Or38fPu6OpiXFz38fH79vLz7urv6+hhYF5cWWKal6D//f/Z09Xg29exraqbl5RqaW6kpKTq5uPv7Of/+PDj29D//vP18Ozs5+OloJymoZ1ZVVJZWVlkYF2hnpmblIyspJmVjYKQi4enop5STUlRTUpcWUhqY1BgWT9ZUjhcV1NiXVkkhke3AAAABHRSTlMA5vjapJ+a9wAAAP9JREFUGBk9wA1EAwEAhuHv3dTQAkLiUlJFJWF0QDLFYDRXIMkomBgxNIYxhOk4wwCqQhQjxgxSGIsALFA5BiYbMZHajz1oJlx51sBJpf6Gd3zONcrqm/r1W8ByK0r+XV1LXyOLLnjW6hMGpu0u1IzPSdO17DgrGC6AadrVodGcDQYbhguP6wAvAaC0BRZQalkUQ8UQDz5tAof0XbejOFcV5xiUoCfjj3O/nf0ZbqAMPYmzU18KSDaRQ08qnfw+B2JNdAEQt2O5vctUGjhoIBU4ygPsj2Vh5zYopDK73hsirdkPTwGCbSHpiYFwYVVC/17pCFSBeUmoqwYQuZtWxx+BVEz0LeVKIQAAAABJRU5ErkJggg==', - 'Madotsuki': 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAMAAADTRh9nAAAALVBMVEUAAAC3iopWLTtWPkHnvqUcBxx5GCZyAAARERGbdXJrRUyGRUyYbY23coZFGDRFGEYfAAAAAXRSTlMAQObYZgAAAGhJREFUeF5Vy1kOQyEMQ1Fshzd12P9y61AixLX4yJFo1cvVUfT23GaflF0HPLln6bhnZVKCcrIWGqpCUcKYSP3JSIRySKTtULPNwMaD8/NC8tsyqsd1hR+6qeqIDHc3LD0B3KdtV1f2A+LJBBIHSgcEAAAAAElFTkSuQmCC', - 'Sega': 'iVBORw0KGgoAAAANSUhEUgAAACwAAAALBAMAAAD2A3K8AAAAMFBMVEUAAACMjpOChImytLmdnqMrKzDIyM55dnkODQ94foQ7PkXm5Olsb3VUUVVhZmw8Sl6klHLxAAAAAXRSTlMAQObYZgAAANFJREFUGJVjYIACRiUlJUUGDHBk4syTkxQwhO3/rQ/4ZYsuymi3YEFUqAhC4LCJZJGIi1uimKKjk3KysbOxsaMnAwNLyqoopaXhttf2it1anrJqke1pr1DlBAZhicLnM5YXZ4RWlIYoezx0zrjYqG6czCDsYRzxIko6Q/qFaKy0690Ij0MxN8K2MIhJXF+hsfxJxuwdpYGVaUU3Mm5bqgKFOZOFit3Vp23J3pgsqLxFUXpLtlD5bgcGBs45794dn6mkOVFQUOjNmXPPz8ysOcAAANw6SHLtrqolAAAAAElFTkSuQmCC', - 'Sakamoto': 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAxVJREFUOE+Nk19IU1EYwK+GQQTVQ39egh6ibKlzw91z7rn3bvfOmddNszl1bjKXc5rJJGmBUr7Yg9qTD0IalFgRBEYg6EDQQB+GovQyQgiaUZsoLcgHMcr069w7MgcGXfi453zn+37fv3MYZt/n99e76tzVj4JN/hP79fvXnV3hnNabwUBjoOHcgTYOu/JQspgTzsqKgn9BfD4vkWTzur287PqLVy+zM+yePB7KsRXLywTjnSpnZctBkPCdW8ccDuU55vBO8RXbkC/oP5ph19V5+7LIky0OY1BKbZEbLcFSt7u6pN7jLmltCVrr3DV5jY3+KovFEsccB1KJNVpefe10BqS2tqqO4/AuphBB4L/LkrRqNgtJs1lMypLls1kU38mytMLz/E8VIlutqVqX6/weZG52OttRXjbE0cP/FYLRlpVjDXuQ/r77x2XZPKkCHA4HBAIBkCQpAygIAvh8Pu2MZgO0Lz+QSa/sQfwN9RfpVN66XC6Ynp6GhYUFGBwczAC1t7fD0tISxONx6O7upgHILmsqvLcHodOggfiV/v5+SCaT4HQ6IRaLgdfr1bIRRREmJyfBZrNBNBqF+fl5sNsdgE2GiAbp6bmbdbXC7qWQbxMTE7C2tgY6nQ5SqRSEw2ENopaoZpCXlwdTU1NaoECgCbgiU6y8QH+ECYWaTymK7TWdys7MzIwGaWtrg42NDejo6AB1WjU1NZo+FArB2NgYrK6uQrAlCASxn2z6wkuMp87VIAhkE2MEAwMDkEgkYHx8HBYXF0HtkQpRy1BLiEQisLy8rPVNKSsFjEzrXH4+z1hlS4xDhKadNu7t7YPR0VHweDzAEVWfHru6HxkZgeHhYVAURYNjkylVWKArZjjMzqmdVi+QCsLUkQiEjvDvncEkvU7/qQ0Vgukeo48Go87IiCJnZNmipxiz7wXEbVDnbUxQOgM12h9n6qTq6NvapRdtkwaP0XK8RmPuYSbxYfaQ/sJJhjfknuFRURUi7AMOozcCwl94hLZp5F+EioDQVwqYI6jomZU1NFtM+rOSxZjVazcyvwHr/p/Kws1jegAAAABJRU5ErkJggg==', - 'Baka': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA0pJREFUOE91k3tI01EUx39JOpA0H4jNx0pbD3XTalISWf8YFlEgldqDsBLLyqjEKBCiLLWiggh6/KEV1WZ7OaelLZvDdDafNW1JFraWe/32+01FrUZ9uy4ylLpw4Z5z7/nc77n3HIqaMRIjZJyEcNX+uFCFeGmI/GZciEIsCFJUTvoAzDz+1y7K76MSwhX5hXl6z+WSbrzU2KB8YEGDwgrTaxZ3b7xHcaHhR3xw7Z5/UviB1ReP5XSg3+TAqYJOxMzWISFIC0GQDomhTVA9skCnsaAwp/vnMq66dBokNuBR9uFd7T9Z1zCunjci0qcRJUVdoJ3DYOhRnC/qBZ+jQbfeCc+37yjY2UEg0iwvJE0k9l8Z+8xqHmTgot0QLdQgTaQFQ2AsOzlHvOu1S5pwOLsHHo8HjHMCq2MazNvTlByKHyrJLDvdR25jMWRxYx5HjeMH2r1BDOOeguRua4OI14jx8a8YH5tA+al3EHKlW6mYOapb2oZBOOwMbEMseAE12L+jjUh3w+VipyAZ65oxn1NP/GMYGR6Ftn4Qsf7qa9S82Y/l/X122G0uL2TbxmZEz1WhXW8mUol8moXu+SCi/OoQ6VsDh3UUwyQ1k9GOaI5MTkX4yWTGHutvgI1F28sviAlRgxeoRm62HvsyW8En9pZ1TYgi6TntoyQtFm86rVgUoJZRvDnKMmXVAGxWmkAYOBwudBqGcHCvHulrGpGT2Uy+z4yT+QYsCXtCUpp8GxbKhx8gDK0ro+KjJGvzdjfDZnN6VdisLD5/JjArQ2zW66PJOj2lEZtStaBphkwah7K6kMJ/GEulp1bMWhAmMbTozOQRaWRtfoZVgjo4iRra4SYgGi26TwjxVeDKhR7Y7U606ixICq9tr7hd7+OthRWL7yUnJ1WPmXotqLhpRICPHCePtuFV6xdUPTAhcWEtRHEqfHpPyto4hPXLXnzflSEJnFaN3OCKDcsFsrEntR9RUmxARLAUgT5iBPuJsXWDBj0dZjRU9yNV+PTbpjTp9OA/pOSk24nRkXf1J462oPxcJ65f6ULlHSMulepRerYDgvj7A0cKpNz/tyTZqbzXO4t0ZZGQJ34RH11lFHIlA8LIqreCCMUZRY3cd2bwL/5/RmjNSXqtAAAAAElFTkSuQmCC', - 'Ponyo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAuNJREFUOE+Nk3tI01EUx39BTytConQTt1am07m5abi5KT5S8z2dj1yOEMUC7aUgIoimlmUEWX9kBZGWaamEmE6U1BI1XNPNGTrnHs33IwuSXrL4NgcJ0mNdOHDh3PPhnPP9XoKwcroJYvMQiRSicHCQKCgUyZC9/T5rNet5KUFs0zCZbZMsFmZ9fTEjEEBDp4/KSSSb/4JoGIyWaTYbiykpWEhOxhSHAzWD0aqkUGhWAcVkW58xlvuPhfh4zItEmOHxYDR3MhcdDaNAsKJydAz5IySKRNjEUmy88vjOVaU8F0iPCqCNjEBHkC/UYaGYFwqxmJoKLYOhkxPElg0QsbNtTlmox9yjRD9UCbnoOR+J/lwRWtOCcdXfDc2BPpg0d7CQlIQZPh9KKlVkAQjJ2x2zmOSsQu7hpzUJfBhLjsNQmADjxcT10Bcl4rE4EHc5LjBEhEPn7f1WTqXSLQB/s1Tp7vslsoIkyPPiMJAbi86McBguiaHKjoEqR4jJy2K0nAxApzMN5iUGrclrKVaz2fUvuF4tRbxDKA90w5VjTFyLZKHpTBSq4/1QnxGB2qxoVIZx0JopRCPHFSNOThfWZzfrXDcZEowH4iA05ATg68hDtBaL0HAuCm3lJ9Bfcx2fFNUoi/DCjRgfNHHd1wCZA2TyXjNkE6F0cBDpPFiojeNi8EkJdFoN3vXch0nbBJOhDd907dANv8JITxNqziag3ZsJbUDAwLin50Q9QWwl1qSYoNOVvUcOoqOqAAa9Fu9H2/F9+B5WZLcwOyxFX18flLI+VASyMGVeoJHD+Tzq5BS1PoaKRrNT8127P74swsq4FCa9FKvqBqwaOiz3hdEuLKueYSyECT2LNW0eIfo3E/WmEbvnG1MUJnWdpWhDGDvxQXZHo+RR0uW2tnv+auPX+TvtJm7zKpaen/4y2yjBUlcxlvtvmvT16ZWDpQeoVv3/60F/NrHjTf4ugazIXtJ8ivjnz/sJ+yGQRjcqUdIAAAAASUVORK5CYII=', - 'Rabite': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAD/0lEQVR4Xl2MXUxbdQDFz/9+9Lb3tkBLCxTKhzgoOOZAsokbJmZxDFHnd+LL4hKVzBgfNCY++ODbjDEaZowvErOM6HRu6hKZY2rIAOkCY4OSDTpFaAsrlJa2t5+39+NvjT7tnJzknIfzI98Nf/C6TuXdguWBd1q9rcb8/CwsZiu2Ywm4nDVo3VWLZCKDaDwJq9mCg31PgjAMKKUwmcyYvTbek9iJRDm6M/XswEDjwNz6plWW6wdZhjUAintFCEEhn0N04zYskljaDLaj8ar49oUrsYR6mrFJNj322w46H8y+mitM/ZJKZmyE4XAvjJSsazpyuSzslVZIkgWKOvvRgQ6Xrdlhqmds7o7bFZoLkctreKxf7GtuCE7IyUQjBQcQ8j/lvxCGQJZz0IoCVpamTtzfIh9nwiaIrCQyjNg8mq11oDLUhNXRJfT1Ozr3tS/PqpnQ80qRgjAmKIqBfK4ItbSLKoOZqR/6neLkENlSUAIhlktvEf+sD2rkm8nWTHtvZCGMVON1ePuaoBER31/MXGly1wSqq9Uug6FluYyWXJiPqFXmjd4Dh9oF9ZKKimYXRtYCx8lmMIDIxlIPGz591av0mtanF7FcCEN6iMXeox2wOJ0QJAmUAoRQaIqCnWAQY1/ewKNGNeQuYXkm0d2NC2e+wvmRr/Hx+6+8PHayrbDyyQBNDb9As3PHKDWG6MTM23RoeJAWsqeoWvyUUv0UHf7pBB0fe4OeeXe3/vmHbx3+8dwIGJ4IsFpMMFe0fbtAn+nwZePr1u4MBK8XIALG/Rt479wYrs2vgeNNAMNgMbiNzybuoKVvn+Gs9kbr6qpBfJfGYHFIkJUCoGwfqcoMX/b27EGhwgOjoCADDlP+CA51ugFFRzoB8FYNaQ1oqKD44+eNL+wNj7zJGQSIhe8+jgQ9thk+27v/KRY6L4FSCkVOwtlQj6P73Qgt/o1ERoKt4iUkE7+jrZMHyzIoK9cOBFfT4LbWAk+0a7ZLnvqHcTNdACgFScfAcjxEdy00VQclHGo7dqGeYxHbvIo6hwhSghCehb3G5p6eW7VxXC5/xGWToMgrKKoaCnIalI9CIARasQAqloMI/x4BWrLLYwE1AEPTwCGHaGjz7pw/leZUNV8wNm9BLy6CxsvxZ1kMbaY4TKIIXlNBsynoVjvAC4CuAoYOVi+CMfLYCUfg95tPHuzZB0YtKzsb58RMucWE/fZmhCbdOP9rNnLnxko6GVoB8lFwyVVw8b/AyeulHoJyN4Rb19dTFyeqBlu6njvfsWcvOJvLs7DMmw/7bvpeE4pU2OIcgcqmp4fGAgt2Txwvqr7lTp5V7LquZxXC6+BqEvGcY5pyjaM1tffJbk89NE3FP5VQ6y7a+paZAAAAAElFTkSuQmCC', - 'Arch': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABCFBMVEUAAAAA//8rqtVAqtUQj88tpdIYks46otwVldUbktEaldMjldM2qNcXk9IWktQZkdIYlc8mnNUXlNEZktEZlNIYktIWlNMXktE7o9klmdMXktFHqdkXk9EWk9EYk9IlmtQXlNEXktAWk9AWlNEYlNFDptkZldMYk9E4otg/p9kXktEXk9AXlNA4otclmdQXk9IYktEXlNEwn9YXk9IXk9FFp9o3otgXk9FPrdwXk9E2otdCptkXk9E/ptkcldIXk9Edl9IXk9EjmdUXk9EXk9EXk9EbldIcldIjmdMmmtQsndUvntYyn9YyoNYzoNc0odc1odc2odc6pNg7pNg9pdlDp9pJqttOrdzlYlFbAAAARXRSTlMAAQYMEBEVFhgcHR0mLS8zNTY3PT4/RU1kdXp6e3+Cg4WIiYqMjZGXl5mbnqSnrbS3zMzV3OPk7Ozv8fT29vf4+fz8/f7SyXIjAAAAmUlEQVR4XlXI1WLCUBQF0YM3SHB3a1B3l7Bx1///E6ANkDtva0jKbCW2XIH1z2hiZEZ4uUgxo7JedTQye/KN/Sb5tbJ+7V9OXd1n+O+38257TL+tah3mADAwSMM7wzQWF4Hff6ubQIZIAIb6vxEF4CZyATXhZa4HwEnEA+2QgoiyQDnIEWkjVSBBZBqXbCRlKYo8+Rwkyx54AOYfFe7HhFa7AAAAAElFTkSuQmCC', - 'CentOS': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB5lBMVEUAAADy8tng4Ovs9tnk5O3c7bX44LLduNO1tdDh7r/eutj43q2kocX23az07N+qqsvUqcmXl7331ZXJj7r40o/Pn8T42qP63KjNw9n21p3Y387Ml7732JzR55z05MSxtMLGn8TC4Hx8eqt8e62Af6/B4HnG4oPC4HzH44fBf7LCgbOkoMTcsrmtn8PWqcfFtKrj4Jvs2ZOz2FnMqLXT3KfY5p60Z6NUU5XRuqHzwWSywqDn3JaiiLWahrWhkry5zJjRmqm1Z6P1wmb1y319fK632mK5cKi5nH+73Gu73Gy73W283W+9eK17e6y1yZS3aqRZWJdcW5ldXJplXZppaKBwb6VwcKV5eKswL306OYNPTpGkfK+m0kGpUJWq1EnEqIuXK3+Xh7ahP4qhkryMfK6BgK+CdpGMaKKMa6O9ea2+eq6+oYW/eq+NbqWVlL2Wlr7AjanA4HnA4HrBkqbBlafB33rCgbLCmKjCxIzC1mSs1UytV5mtxIWt1lCuz2evWpuvXJywxYzHjrvH4oXIjrrN2HXO5pTO5pXUlYnUlYvVl5Hb0G7e0XTg03rhr5fpzHPpzXTp0Hvtz3/wrDHytknyt0zyuE3yuVHzvVr0wGP1x3T1yHf1yXe0ZaL2zYP30o730pD31ZeRIcF5AAAAQ3RSTlMAFBkbHEhJS0xMTk5UWWBsd4SEiIiPkJCVlZaam6CjpK29wMPDxMTFxcnK193e3+Dg4uTn5+fo6e/v8/P4+fn7/P7+J4XBAAAAAOBJREFUeF5Vj1OvAwEYBb/yGlu717atLW0b17Zt2/6nze42TTpvMw8nOZCAmwUpiIY6c5IiLi9tPX64GairqszHQ4X2VB64v1Cs6PxMPJSdHM777s6/jyaMRGiRLyyrb88OpjZ3CzAXrm1sqzSNNeN7kVBPNgB7cG51abE5l9cXDces7emQ1uadHhutFUg6gpPKkSIqQGavwz7r7O/+/3t/rSdjI9XDM3qz4fr3B/3iA0aJTG9x71+9oR/PLDwUe2wm19bly+fTIxHyEETatbPewGEw6Mk/tKZCEqSQQUlIHB/QNBEjjVN1AAAAAElFTkSuQmCC', - 'Debian': 'iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAZ5JREFUOE+Nkk0oBHEYxv8fu5GQj3JwcaDkIAc5IpR87M7MKnIVJVKclaIQ5Sy5OLkgR7n5OigcSNpmd2c2Vyfl4KT8/muWiVU79TTv+7zv837NCBF6PG1X+NpZyEYSD9mIc+tHnBPe23B9xKrCuTmbQA/JKfABrhBswa1hH4A38IwfOxPdX1qcjiCQxO5NyrjKV70TnSbeRPwJvGN3i4yyqnEucPY8ZZX9GSEgGK+RvFfyjk2VKZxzBNG8wJWWgh/xtDOeUXZ7Slr6TrSLYL9N4SMgYTTcwdc2ArvJcElhSVcM6mCNSV8n9hA59yTU5UWMG6HIbLhIWlglgWiC2L4Z79qTdo40D6ISuOWwKCWHyk9Fv8ldpUHOuGTuynwSBUynddPdlbEosVpP9Eu4FnOsRzUYNTsdmZN/d5LDiqM0w+2CMdAFFsFGWgfXxZnheqe/z+0puwEM0HHYV3Z9Sgz8TEz7GkQvpuJ/36ggj2AaHLrSlkULWV5x+h2E8xkZL16YVjGNaAUscfZ/f6c/k9ywLKI2MMcRWl0RLy007idmRbQJ7RIfDAAAAABJRU5ErkJggg==', - 'Fedora': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABPlBMVEUAAAApQXIpQXIpQXIqQ3UpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIqQ3QpQXIpQXIqRHYpQXIpQXIqQ3QqRHYpQXI8brT///8uTYMpQnM5Zqg5ZqnS1+I4ZaY4ZactSn8uRnYrQ3MrRXgsRHUsR3s8bbM8brMtSX4wUosxVI01XZw2X50vUIguToQvR3c6X5o6aKs6aq08Un8qQnM9VIFDWINJXohKcKlXapEqQ3UvUIc2X55bhcBdcJVgcpdhfapmd5tuk8dxgqJ1hKR5jbB6iah/m8Shudq3v9C4wNG/x9bFy9nFzNnFzNrIz9zK0NzK0t/O2+3P1eA2YaDU2eTb3+jb4Oje4urj6fHm6e/s7/Tz9fj3+fz7/P38/f3+/v83YaEa/NNxAAAAHnRSTlMABAoVGyY1SVlpeIuQsLfDzdHW4+3y8/b39/n6+vr4+ns8AAAAyklEQVR4XiWN5XrDMAxF75KOknYdZJS0klNmHjMzMzO9/wvMcH7I37mSJShsJ+5NjMT6umDoHyXDcI/2qJadh++P3cle1de+9yPe3/bTY92wzfzr7wGtP3JrAI72BZGVtcAdQlwHy+JS1pDbBE9qamZF3BYrjQxPEXwKc6dC8bXFm0QIpmt8kn0Rn093q82UCtK8oXZckwFJzuulV8bHkajPyXdbnJnARfDHs0trz+JQ+5AFvzp/L0+cL2qPAINUPrq5OC6p/64F/AMnrST+Dq/r7QAAAABJRU5ErkJggg==', - 'FreeBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAABIAAAASABGyWs+AAAABmJLR0QA/wD/AP+gvaeTAAADXklEQVQYGQXBS2wUZQDA8f83j33M9rF9d7u4loaWklaDpkSo9KDGaIKUaGxshD2YSPRiuDVeTDyhBxosJCoa40ktpAkPDcUqAYVIpUSUPrAulEdD2bbb7e7ObGcfM/P5+4kwKDvq6yJ1FYYcvb+YAkqAHo/HQ7FYrFIoCiurq9ZXJ06YSOkA+kBzfX06bys3zHxS9EL0tXDVyZfefacqV+X/ZSJx5+qLbx98LhaL9RiGEZWlEsWC/Thd9q6Pf3vs2u6Orc83rFsvTwwfLf5obgywT1Vjh2Hh+rbNsnTssJdNLedK5aIrpSuldKVXKsnH4+Pyn6FDXn5tMef9O+3NvdkvP1V4+EYw2AoQ+KSx8dRYS6NXXnwovaItXduSrrkinWxGOmZWJi9OyOK9m1LmsjIz9IH8QUMOd3WfAQwNKCy2tJwbHB5+XasPaxIHmc4g7WWEZ1MquBiRFlJTf1E7+Tl/H/8asavPzTY1nWd2ZkMDRPeBeHPz5ojwsilEQCBvTSKunCF3M8FSNkBGVTHDYYrLj8jVNhDZ2SMa2zo3MTamaIC/u6Ojr3DtrOrvP0BpdATnyBeIhTxpR5ABUlKSUlXS1dWstbVxdz6hPL0l1quGqkLaKwNvVcjEXNRd/4mit4Z19DjefBEPyCKxgQJQcF28dBrHNDGTSZSezsjeff0hraa2Vs2vrvit81O4vj9xLJcC4ADrQA7YAGqBGsAql/EtLdFQE/L7dF1XZmdnSrbPMJfXoLDmolQK8gJyQBowgQhQDRQBD+hsraVhd4e5MH+/oExfvWLJ9q3/3S7qMpNH2hsS40kFS4EUUAMA2IANRIBXv4uzuO67c2PykqkA5YmZ6bN18YPi0Yoknxc4AsJPCMLVAk2BLKDosCWqs/PZaulkuxk9fekcUBAAQGDks5FT0W++3NuYuC0DVUL4DIEdlIQDAj0IRkigaMjArkFx0tf523sffrQHyKsAgHPhwoXLL+yP9/kePNhk5ExUTyKFkJVAUAiCFZrQup4Rv9ftuLV/6ONBYBVABQAArMvJ5MXW7duD6P62sD8UrPAFRU1TpeCpCnGvPZr7WW///v0jpw+VC9ZdAAABAAAAAMLo7drWrmQyPWG/r8tnaGIjaM05ujr16x/ZBFh5AACA/wGZnIuw4Z4A3AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNy0wNFQxMDowOTo0OS0wNDowMOPVpFwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDctMDRUMTA6MDk6NDktMDQ6MDCSiBzgAAAAAElFTkSuQmCC', - 'Gentoo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB9VBMVEUAAAD///+AgICqqv+AgIC/v9+Ojqqii9GAgKptYZKQkOmPj/ddUYBgW4eVjeCTgfiWjO5wbJaZkvPBvepkXomYkNldV4Bzbpl6dJ+Uj7ynoO6Vi+1qZI63se2mnudjXYjOy+GCfaqZjvWlm/Pc2e+Oh7NeWIOWjfeXjeW1sd+gl+diXIfp5/KHgKnn5/F2cZx6c6ZgWoXc2e6dltrAvNu0scrX1eTOyujCvup4c5qpovVpY43///+6uPPJyPXq6fvm5vrz8/z8/P7+/v/d3PixqvmxrPSyrfe0sPO0sfS3tMve2/3r6vy6ufPz8/3d3fi3tM63tPO4tsu5tsu5tvO6tfe6t/Vva5KRjKy7tvW7t/W9vPO/vM+/vvPCwfPEw/TFwvTFxOfGxfTGxvTHxvTIx/TJx/aTiOrNzPXNzfXQzfnRzuHS0fbS0vbT0uHU0e/U0uTU0/bW0+zW1ffX1vfY1/jZ2Pjb2/jc2uSTiemVkLSlnvbe3PTe3vng3fzg3f3g4Pnh4Pnh4fri4enj4/nk5Prl5Prm4/ymn/bn5vro5/rp6O/p6funoPWsqs3t7Pvt7fXv7vzv7v3w7/nx7/3y8f3y8v3z8vytqPWuqPX09P319P319P719f339v739/34+P35+f37+/+uqev9/f6vqvSwrPQAR0dcAAAAPHRSTlMAAQIDBAgJCwwVFyAsNUFHSVBneH+Bh4mVmZmanKCxsrK2tr3ExtDW19rb4ODl5u3t7u/w8/T6+/z9/f4MkNJ1AAAA8ElEQVR4XjXNw5aDURSE0YrRtm3b54+dtm3btm3bz9k3Wek9+2pSYFwT8ibzE93hwAtdJqK3nZo4J9hFXbP+vFHOthV6gnGzstZq94wdCs4UCCDymQ2v7X0LdYoSQ0MIENRYzJbRlPTTHu73ZNAL8vivmVui98PpzuqffX0mIPHJGtOQenukteJ+aS3b9htNpDnT9TeZH1bHAwBRMhGpd6e6uNrLoRgxBKmsX47nBlp678ojpEA40fejcmW4e/No0V8IIPfj6eKgbEJ3ZUnzgE1OqWp9Q3VeWRAsg51f1dZ8c31RmAsc+N5JGbG+zvj3BzDCPrzMDC9SAAAAAElFTkSuQmCC', - 'Mint': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACVVBMVEUAAADh4eEAAAAAAAAAAAAAAAAAAAAsLCyXl5dgYGCnp6eTk5N3d3fBwcGqqqq8vLzNzc3Ozs7Ozs7Pz8/Pz9DQ0NHR0dLS0tLS0tPT09Pf3t/Pz8/i4eLb29vZ2drZ2tna2dra2trf3t/u7O/u7e/u7O/r6+vt7O/w7/Lw8PDy8fTz8fXz8fbx8fHz8/P19fb49/j49/n6+vuPxlmWyGOx437h9NDr9eD6/fj////+/v75/vTA5Jv6/fb7/fnL5bDL5q+AxjeDxUCEzTyGxUaGzjyHxkiHzz6J0D+Kxk6K0kCLyE2M00WNy06P00mSz1OUyF+W2FGX1FiY0F6Z02CZ21ac0Wiez2yfz2+f2mOh4GCi4GOi4WKi4mOk12+k3Wul32um1Hin0nun4G6n5Gin5Wmo23Op2Huq1n+q43Cr526s4Hit23+v6XSw34Cw34Gw6nWx4IKy4IOy44Cy63ez146z34az4IWz4YW03Y217nu38H2625e645G74pK83pu98Iq984W+4ZjA4px0tzDA5ZrB8ZDC5p7D55/E947F6KHF+JHH4qvH6qTI46/K5LLL5LN1tzLL5bN1uTDL57DM5bPM6qzM66/N5rTP6LbP6bTR6rfS573T67vT7LrV7r3X68XX7MHX773Y77/Y9rvZ8cHa7cjd88bi88/j8tTk8djk9tHm8trn89vo89zo9N3p9N3p9d7p9tvq9d/s+93s/dzy+erz+O73+vT4/PX5/fT5/fX5/vN1uzB3vTD6/ff6/fh5uTj8/fv9/vr9/vx8wjV/xDmrMRH0AAAAOXRSTlMAAAECAwQJDzk/RUlNU3F0kpSVlpeYmpucnaKjpKWqqqqtu8LExMTEzdTU1NXY4evy8vP+/v7+/v6LaR1mAAABD0lEQVR4XiXI03bEABAA0KltW9kaW3eSZW3btm3btm3b/q4mp/fxgqKOtpamhrqaqoqykrQYABh+PVMU9fjE5Xp8o54kgPHN0EBHU2N5YXZykiua0HHd2759VF2Sk5IYE5GGsmCEWLV1kVWwt5O+3x/qpgsy8k4ja+cJl2/v5C22tlgCAHtw9TQSa4s+AzfPSm0BRNl9SydhWJzLC567KrNhgrNwHIJ5qTz/2f9w7Jw/DNqIjVr04exW0AEOXcN3Ab7enr9eDW2VTJgehONyc2Z8XP5YdD0Tcuhcc4/r45OjGX51TEjYPbh8THRPvbz+CHusgSZlT7rP8PkCwfQKaQUi9Igr6JsRBMFiWZgb/AHKElRzKopZJQAAAABJRU5ErkJggg==', - 'Osx': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABrVBMVEUAAAD///////+qqqr///+ZmZn///+qqqqAgID///////+tra339/eAgICoqKjx8fGMjIzm5ubh4eGPj4/g4ODIyMiAgICSkpKLi4vS1tbPz8+Xl5eMjIypqanIyMjW1tZ2dnbR0dGamprFxcV3d3d+fn60tbV3d3dcXFx3d3epqal7fHxxcXF+foCnp6hYWFhyc3Ojo6SMjI5fX196enp+fn6Li4xERERqamqgoKFpaWmFhoeen6A/Pz9QUFCWlpeSk5SUlZWUlZaOjo+Tk5RHR0cuLi5YWFgwMDAeHh40NDQ3Nzc6OjpcXF1rbG0XFxdSU1NVVVVXV1dZWVlbW1tnZ2lwcHABAQEEBAQXFxchISI+P0BISUpaW1xHR0kNDg4qKyszNDU1NTY9Pj8NDQ1cXF4XFxhSU1QSEhIDAwMrKywtLS4uLi4wMDFHSElISEggISE0NDVJSktNTU1FRUVWVlhGRkYEBAVBQUE0NTZQUVJQUVMFBQUqKitWV1lXV1daWlpaWlw+Pj8bGxtcXV9dXV1fX19fYGFgYGBkZGRlZmhpaWlsbGxwcHB2dna844Y9AAAAV3RSTlMAAQIDAwUFBggMDhkeICMkKCgqMDIzPj9ERFBib4CCg4iMjZCcnp+jqamrw83W1tvb3ePl6Ojp6+vs7u7v8PHy9PT09PT3+vr7/f39/f39/v7+/v7+/v50ou7NAAAA30lEQVR4XkXIY3vDYABG4SepMdq2bRSz/capzdm2fvOuDO397Rw0Ly4tz2QAQPbcxuZ2E/STJwfxPhWgG355fRrVAIVb1zeP9UDLfiSwkAcADe8fn7tFxWuEXFRDoer/OgoMTRBCumj8yJwPBo8Zhpk14U856/HI8n0ZUtpZ1udrSzfVneA4roNKjdrwpcMRilb8d8G60+lKnrpWcn9bO+B23w2O8Tzfq4aiNSZJqzn5O4Kw16h06fPZ+VUlUHfo97+VAEb7rSh2UgDd4/U+TBlQY7FMj5gBIGvcarVVfQPVPTG94D0j9QAAAABJRU5ErkJggg==', - 'Rhel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABj1BMVEUAAAD///////8AAAD///////8AAAD///8AAAD///////8AAAD///8AAAD+/v4AAAAAAAAAAAArKysAAAD///////8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8AAAD///8AAAAAAAAAAAAAAAB5eXn+/v5JSUnKysrS0tJ5eXmqqqqxsrL+/v4ZCgknJyeHh4eIiIjo6OgZCAdOTk7t7e3///8GCwwPAAArKyv19fX29vb9/f0EAAD////+/v4AAAAGBgYHAAAJAAAMAAANAQAPAQAVAQFyCQV9fX2pIRzmEQjn5+cBAAAFAAAAAADnEQjvEgn////uEQjyEgnsEQjzEgnxEgljBwPaEAj9EwnwEglHBQJHBQNNBQIBAAB3CQR5CQSHCgWLCgWRCgWTCwadDAWmDAapDAa/DgfKDwjWEAgGAADh4eHiEQjmEQjmEQkKAADoEQgLAQDtEQgMAQDuEQnvEQjvEQkPAQAfAgEuAwEvAwE8BAL1Egn3Egn4Egn6Egk+BAL+/v5CBQJrB0muAAAAT3RSTlMAAAMEBAkYGhsbMTRLUmpvcHeIjLe6vcHCxM3P0NbW3Ojp6u/w9ff5+fn6+vr6+/v7+/v8/Pz9/f39/f39/f7+/v7+/v7+/v7+/v7+/v7+Q8UoNAAAAO5JREFUeF4tiwVPA0EYRL9SXIsWl+LuxfcOd2Z3764quLu788NZNrxkksmbDP2R7vH6GioLs+iffEzNXd4+TqPErUUpVqMOvwgdzMPn1rv5vPsVeufBTaBK/bH2FPvkEUuIG5jIIc+sHYn/HJ3dC/Hxuo4y8s44dzwBbFkisHN8bVIdXs6jb+H97aCwbHEIqgcml64CD7YllNkAVQC940MLYe5YzvIeQAXNrd19Roc5MdzfdQLUUKaUYyuG9I8y1g4gj6hIak4X5cBIT2MquZJrJdOqpY11ZpAiqVwbY/C7KY1cRCrZxX4pWXVuiuq/hs49kg4OyP4AAAAASUVORK5CYII=', - 'Sabayon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABvFBMVEUAAAAcUaYdVKwAAAAAAAUABAwWRY4YSZYhZtIhaNYHDx0KCgoFDBcKCgoRMmYSNm0fXL0fXb8AAAAYS5gaTp8fXLwgXsEGBgYFBQUZSpgZTZ4JFSgODg4IEiIOJkwOKVIkW7EnXbQLGzUTExMKGC8LHjwMIkITExMiIiIPEBEPJ00QEhMXOXAaPncOJEgoXbApXbEcHBwwMDAEAgAfHRgQDgo3NC8AAAAHBwcKCgoLCwsJCQkaGhofHx8lJSUwMDA0NDQ4ODiRkZEICQocHBweHh4GBgYHCg8mJiYnJycpKSkrKystLS0uLi4ICAgODg43NzcRERF1dXUUFBSjo6O1tbUbGxsEBAMLGS8MDA0iIiIjIyMkJCQNDQ0NHTYKCQkoKCgPDw8QEBArMDkKCgkRERIREhMxMTEyMjISIz00Njk1NTU2NjYCAgIVFRU5OTo5P0c8PD0+Pj4/QURAQEBHR0dKSkpMTExSUlJiYmJlZWVnZ2cWFhZ2dnZ4eHh8fHx9fX2FhYUXFxeVlZWXl5eYmJiZmZmcnJwZGRmlpaWrq6usrKyvr68KFiq/v7/FxcXY2Nji4uLn5+ft7e0yif9uAAAAN3RSTlMAAAApKSkqKioqg4OEhISEhoa1tra3t7y9vr7S09PT09TU+Pj5+fn5+/v7+/v7+/v7/v7+/v7+70RY/wAAAPpJREFUeF4dyWNjw2AUBeC7dfYyorM6rx1exKltzLZt2/rDa/J8OgBVVlFDX39jcTZoUqCse251a2dvu6ccUtWlanLQ4Vpel+ThlWq1l3wEz58tx4dOt1dMlAJk9A5gMjG75LHwo46hzkwosGOMbejumoRvubC9EOrMviT0E0Us9fvN9dA6zxJCNv6+ECGsb6oNWsgmpZT9/UTUZo3Em6AW34guTL4jiAudiCM1kLcw8/SmHERfT1/eueBiDqR1GK1n9w+K8nglxYxd6QAML4ztXoQuj8YFgWcgqdJp8qzty26vaboCNIxBCshyQDKov0aXr29v1ufq1PwPx5Q7bCoh6eoAAAAASUVORK5CYII=', - 'Slackware': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AcEDi0qZWWDgAAAAx1JREFUOMt9kktoXHUchb/ffc1M7rySSdJMOknFPMRitLgoNKKI8ZHGKkgrjU8SitidimSh2UkXoQmoO1dGQSxJjdvOtqSaqlR0USEGSjVJGxuSmWR6M3fu4/93YX0g4rc9HA6cc4Q7DI+fpzz7PA8++2mxvZAeBZ4xhHtFcJRmXWsWvb36/OLcyxf5B/KHeYHy7DmGx1+YSDjmWTdlobTGMAStQGkNoLXS4tXDq7u7tUcWz49tA8jR8QUuzB5n5NTCV13F9JEo1JJwTLKuzU61QiOMcd0UDb+BncwQK3Rl15eNja3ui/Njq8aF2eMcO/XlBz0H8oO2ZUkum6A13WB99TtyzXlaCi24SaFa+ZFCzsG2DNnfkdbFjsI1APPhk+d6ujqznycdCxFozadYWvyMpx47wa+bPkGksKwUNnsk3TaCGASRXDZh5LpHXPPg4Rcni+3uYBxrtBbQghlscOVKmYHeEm0ZIZ9xyLffw41ND6VAa43SmjiMByzHYtjzwr9arfshxf5jOKlvKZfn8es77N2uks24PPfSFD/9Uvt7AtPKWmEU9d645eHYJo5tcKi/FX/zG+zmQxQH+rANk862DOW5N/hhaY64cJSa5xNFCgDDILZACMKYWAmh73HmzFsMlBQJ06LeiMinE1S3KzRCm5rXIIoUIoKIYCVM36urZFbEoiBLNMIhAE6/NsSB7h6SKZdL8xsUOnpx9j1KbTdARACIowArYe1ergfNT2i0mIbJys0GI6PT3N1/hJvrPxOFdRJNBQIy/FapI4Bpgohgcjuw+jq8jy8tV55MNBWI4ohS802CpizKv8q+FgALZAfYgSyAZtNro1oLaU1VvxCA029Oraxs7u/tKnXiNjn8HyKwur6lI++6vPK4V7IA7u+1Dyu1tr183ddNbkHuXP8/zEIYeFqiLRl6YO/p0bHJdflT/PD9qZa1W+ry99fcvlAlcZwUpuUAglIRYVgnDEIOlna4q0M/NPnuO1/PzMwg/045O/XeibUt5/Xangx6viSVFpK2jtMpvdyWCz+5ryf10clX3/amp6eZmJjgd441URWWJY8BAAAAAElFTkSuQmCC', - 'Trisquel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABjFBMVEX///8AAAAAAAAAAAAAADMAAGYAAAAAHFUAGWYAF10AImYAIGAAHloAHGMAKGsAGmYAJmYAJGEAKnUAJ1gAMXYAJnEAJGQAI2EAK28AK3cAGTEAMHgALXEALXgALG0AFUAAI2oAK3EAMngANoYALXMANIAAM4IANIIAL3gANIcANokANoQANYQAOY0ANIYANooAN4kAN40AOY0APZMANIUAOY0AO5AAPZUAPJAAP5MAPpQAQJUAOYsAPpYANoUAPpoAPpUAM4AAQJkAPZIAPJEAQpgAN4cAPpQAPZUAPJEAO4oAOosAOo8AQJoAOYsAO44AQpsAO48AQp0AP5UAQpoARJwAQ58ARaAAQZgAQ54AQ50AQpgARaIARqMARaMARaIAR6QARaIARaEASakARKEAR6MASqsARKEASKcAR6MARqYAR6UATbEATa8ARqUARKAAR6oARqMASKgATK8AR6QATbIATbAASq0AR6cASKgASqwAR6UASKcATa8ASqoASqwAS6wASKoAS60ATbHn4CTpAAAAhHRSTlMAAQIFBQUGCQoLDxAREhMUFBUYGhobHB0eHh8gIiIjJCQkJCYoLC0xMTE0NDo6Oz1BQUNHSUxOVFVVVldaWl5iY2RkZWZoamtsb3FycnR1ent9f4KDhIiJioyNkJGYm5+foqOkpqamqKmqrKytsLKzs7e4uLy8v8TFxcXGx8rO0NXY2eZc4XYcAAAA00lEQVR4XkWN1VoCUQAG/3NWtwh7CTsQJOyk7BaDxuxA6bbrxf32gt25m7kZqDRYxziooDV7+1AalMUavQh2AsEZoWvzigLun+T17/c8QiJZ7qu2QKiNmyZthdcR1/as353jIeU1GxMHo5XHdqPFeX8IaDMdHPYN6dRN7LR4qQewdTa35HWkyh+fbxERAMjwlAWJv3CPSKDQ+H7XvHdkV4Pua3Gtm4sPKIF/WV8dop4VKBw/NU33B3x1JbTt+XwhkJQoqRfWvHOy28uqH8JIdomR/R+s9yR3Cso77AAAAABJRU5ErkJggg==', - 'Ubuntu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABKVBMVEX////ojFzplGf1zbnqnHLvs5P10b3yuZv1xKrytZXvtJXys5LysI32waT0n3HxiVHwg0jxhk31kFn0h0zxf0P0hUrveTv2iU3yfkD1hEfyejv5eDLybSX0aR7zZxvyayH6ZxnxZBj4YhH7XAb5WALlUQLeTwHgUAHeTgHfTwD65NzdTQDdTQHdTgD31MfcTgLcTADcTQD////xt5/31Mf54dfmfE/dUAbeVQ/jcUDcTgHeWBnnflHohFvpjGbqkGztnX342Mz53dLgXiP65d399PHdUgrtoYLyu6Xzvaf76eLfXB/rkm/fWhvupojwrpTeVhTgYSfgYynzwa30xbL1ybnngFT31snngljhZS3539XhZzDiajbibDn77OX88Ovrl3X99vTjbz1fisGCAAAAMHRSTlMABgYGBwcHJiorMDA1NXGHjY2Nl5mZmZyfn6O5u8XHzc3X193j9fj4+vr6/f39/f08OUojAAAAx0lEQVR4Xi3HZVbDYBhGwQctWqzFPXiQ+36pu+LubvtfBKcN82/UEhld2vWXxyL6F92gbTPabse8hU/uHMx1SZoyyJWPTwq1Rs7GpYE9+Cg+OJcs1MHvU9y4fnrN31yUm18vMCIPjtw3QMndw4rs8ieVzAAcBlewpe1KM3uaBuD3Dda1BhWXAsi6AFY1a2SqifxZ+rnxWYcJDRkUS3fO1R5vwe+XZgw4D4L3RAJiknoXCVX3WeiUpJ5pIxTvVmg45pl5k4Ot/AGV2iqZBWgJJAAAAABJRU5ErkJggg==', - 'Windows': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA+pJREFUOE+F0n84FHYcB3CWSsL9ojo/6ik64c6PnTjmSS0limmrpBm2G002y++xzXRz6zE0R4nbw+RnTj/WD4sbanLkkAe55ccYlyNme4SrO9u9d13PI3/saZ+/vs/3831ez+f9eb5aWsuqy2mjRYeNUa7YmtjfTico7jNJ8z0eG24NB9vvnDrvufzpq89Npnr8VjMddNmuRh9rDfp36mFg91oM7qPIc5JdbDJq3An/JfCu7Hl53W2lpS220pP2OuniN299jAYbYizSENIoAgbCTdrTKtxOJVdvGo8psUwKy7Vxe4ez1YEVudGP8YEZzyveInFJ6mZRHHqYazDspw/pJwTIuERM5JIwmUdGdyo9K7/BszGzzg6fXzZHGJ8KvzQqXKOpoIeZLjofWR++BPWyCEnPY4xFGEKWQcLjMjKmr1MwfcMYwmz/Y4KOgNki0V5k1dkjUWCK93Kp2PMFFawos8cm1gZ2GqjLXktL4mbQPHLQ4B9ZDFE5+S356fQlyuJMqzH++HnTo6ui2OO1ko9Ul+4fxfd3d4F7k4YTReqpuFS88bGZUE2QNNDobuIq8Q5CduHb7lFJaTnvnym9ergjMWD/FG8zf+aKS3G9JO5C01Asah6wUXrvALKEDoitMMHhDKrKJdg8RU2s0EB2EWWur8dd7PDPFv6dUC0Gv3kAN36VPRGP/5k5NS6lljWxG0TDiSr1VKhoPwhevRMSqkwRxDObc/DavGtpP6zoi8XOyZfhnyNEvKANBU0P8VPfI/wyNCGXSn7wlEmyA9KrgmOKGth3eDVvPfyywq2dnUEv2R9qG2rLsH7xJXziKnWcI8tlTvEC7Mu8hROlImTU9aKqcwQ1vWOihWFu+sJknmph5CvxQh87c7bNh/NXo03hrMCosyvLmMNgMF7TQL6J1dsZIUVwjKqEO+cajp5vxPN439U/gKBt8PTcYHzL/BgHCyOf4unAISj6mFC2bYC82kB5Ls460NHRUVsDeYSXpGw7UgC7sAtwShDgzdM38W7BbURXtqpqhfmB8sEQuXwoCM/6faGQuGCxyxyKWhIm+PrSD495WL3cT0hhi8Whc3NbAs9KaOyCTvrJ8qkdX19XBeTUDU00+55USFzVU2yHstcaix0mUAjJkJeuRU868Ucmk0lcguiBnMAVxjbbdHV1yeq8+u4Hgo22huSG+iQXp83ftaxW3lsPZcs6KG5T8OwaAfJiPcxlrVRVRhvF02i0F/t5VbHZ7JWDfErKTLnhE3mFPuRFepg/uxqz6TqLv6euGj3ut87t/4ylvre3t3ZehOWWO1zjSFEqMVP4GfGb/DBykJcjmaZOoLsc+hcVY/LaAgcTQAAAAABJRU5ErkJggg==', - 'OpenBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAykIPu64pQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADTklEQVQ4y32RXUxTdxjGn3N6eujoKT3SUkuk3VoBGfVjgFXAsZ7WkipyYXQbuu3CzUXZmGRbssnFEseFkWzgcGzGXky9MWL8TsC4IeFgtK4oAqOnG5vMVl1pCMVWQD7b/y5M6jLdflfvxfPked/nBQA0NDSChqnGVrLuGkES742NhJAdhAKAuk9yyUs5Gry7RQMZAARCWgivpQiPe71P5DUfH0xaqTL7m/iiLkJmphawa+e4SM2PvUyC4yUIBu8CnAQKAK53rCA5OUtQtStVpJ4Gw/FOBddZVKhCfq4MP4n6+at+DUsJm/e0G9JZzYEvI2tHwlEYjDxomkZ+3nG8WroRtHihZVOhVlorDQzh0okhcByDP4ZGcf+X9XAsvY5/RsBa7Kq5H/CqLctKyl/g08S2i6fq8W/MS3P34T9wNDVYSeDX1eTD9xhiLXbtB/Akwmmv6Kr+ICFkLpGhtNSM3qsSstS3oX8lSsmsxS6ZVn3j6PvVVqhUcvC8AtPxVPxwygVKvngN89WOjgVprggGA4eenjB4nsXsTASpC63I0wVTZYPR11FoKRB8Ax54PCFk6BhMTk5CPR3GSbHouGzknr/bYFq9EAvfc9Tu1sLjHcXNKxLuTOTgzOlOe7IHBc/beAXWpWmXlz8a84nhcLQ+ecVzsAEQrMWuMX+f9HZF2YPZ28FVSNfoPWqOzMUmqYMAJm7+/OOzXQFwHGpyEV+vi+yvtxBC9pDmpgJC4tvI3mo9GTitIxvW24nT7ug67HY/3eDs2bbyrVsrY2day70rV6kRfDAHk5lDLJqAmmeRiD9GJDKHvwb74R8G0mkTPjrQTTG122xkTTbwaV2b1H4u16JQKXGr7yG2b8/H1MQ09IsTSEmRwzf4CCwzD+dmE1re8CI7wwi5XNlFf9vaTXX4dWJg4LLl7h05fpNGwNAMWpp9CIVYNO/tRCzGwpDFQaVMQTS2CKY0BWr3GVGWNSXKACDDaA4Mh976pq9f5Sy09GgKlmeAMIBKzUKpU+BFoxJecRhUfAbMxDi4eADfHVmE79v7q575gvvYeVvjZ58LD5mwsKUyX0hnf0feslnQCWD4zxnc6reKisxsfH2oscqcmTmK/+Ow252cna7K52r+Bky6PqmoT5HBAAAAAElFTkSuQmCC', - 'Gnu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAywUV5gQrwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADcElEQVQ4y43Tb0jjBRzH8c9v+7nNMebcUW21Cc78g/wcuhByIScoMRwoTBmFlZCmIJ14axqkgoYIkXIqKIVBEuJNUBEUPRlpqDC3Q2Ex0nTezun2YOaPLXNIv7Vvj7zgiOj1+PPk/eADjuNEuHN6ekqMw+H4IzMz8xChUCjV1NT0JbO7uxtfXFy8NZvNr21tbd0AAEQikY6I0m1tbQbx2NjYZiqV+vn29jY+PDw8xhYWFj45PDzcb25uhlQqfSTief6X0dFRpqKigvF4PPPipaWlY7lcXhCLxXJnZmY+ZTY2NnzX19ePGxsbHw0MDLivrq5mc3Jy2pPJZLVWq/2cdbvdDSzLholoNJ1OMy6Xq0Ymk5HNZktOTU29qMgA8HYqlaKDgwNKp9M0PT09BgAM/iGuqqoimUx2yPP8U5/P9wEAMB0dHRUKheJHiUTyeGhoqAUAnE7nR0qlsjcQCLwjlsvlz+bm5mQWi0VSWlr6bXV1tU6hUMj6+/vfN5lMN0xxcfG1zWZ7SETTSqWSGhoamPHxcajV6s+8Xu9Xou7u7t9VKtW00+mkSCTC6PV6aDQa8Dw/Wl9fP8UAQCgUosvLSyovL2eWl5dRUFBw7Ha7v9vc3By5K3g1EAg8FQSBiIguLi4IgBwA2LtEjuPuJxKJ62AwKFpdXf0eQBIvYVmW/cLlchEAWK1WAADT09NzX6PR/OTz+eKVlZUzKpVqTyqVvsnzfLCkpGSrtrb2t97eXnFeXl5ZKpWyZ2RkPPP7/UUnJyefGI3GU+zt7aU4jotOTk7mAUBfX1+b1Wq9kcvlBIAcDgctLCyQxWKhoqIi6uzs/BoAVlZW3qqpqbllZmdnf1hfX//Q4/HEzWbzX+3t7fcMBgMFg0EYjUYmEolAEAREo1Hk5+fT+fk5Mzg4GD86OpJ0dXXJGQBoaWl5Ra/XP6yrq3tQVlam2N7ehslkAsuySCaTUKvVSCQS2NnZSXAcJxYEQTEyMvKeIAhLDADY7fZ7BoPhm6ysLFpbWzuan5//WKvVvsHzPEWjUSYSiSA3N5d0Oh0TjUaf+/1+S2Nj46/4FwYAr7e2tnbF4/E/iYjC4TCFw+F0LBaj/f19mpiYeID/IAagAyABYLXb7cLZ2Rml02nyer3POY6rwv8hEr34u0IkEk1mZ2cTgGMA7768/RtL5JKsGzrLIgAAAABJRU5ErkJggg==', - 'CrunchBang': 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAQCAQAAAC45EetAAAA8ElEQVR4XnWOsUpCYQBGz1TIHYu2Qix6g0DEtSeQu/UIISJtUS8gJq61F1wcdMohcBDxKUR8hsz1xA/y44/cs3znbB+RJ0Skl3pSkeFQbUs79VAPzrwPFRmN1Ja0Ug/16I93+1oi4lKte+zMXv32WuoAm43lXMrqzbFncgWw21lORf4+/PREKpAhYqZuPXZ+T/3yXbZEajV1JavUQ104sRcq0myqc5mnHurWqc/7yhExVwuPncl+C4Bu13L60ueAwcByOtLhgAIRCzU38fRGTmSxUBvSSD3Ui1NvQkXWa7Uq1dRD9R17HiqyRUSy1NP6B7e1Yu2GtlUKAAAAAElFTkSuQmCC', - 'Yuno': 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAPCAYAAAD+pA/bAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAABDtJREFUOE+FlHtMm1UYxrtsi8aEgCb+oTFmZur+WNS5RaPERU10C2qGaBgb6hgwLwMmHTIKlIKlQIHSQrmU24BSSmnpBVooUmihtEC5yKWDjVu5uOkcEca4lG5E93j6EQmELX7Jky/fOed9fu973vMdGu0xT3Cgz57yXMZLDdXcy821PFWLKmuA6HqLMqtLX5POl4iYb2ukWW8IOOFe/qfe3/M4n0eOjwyZD8//bldODOk37N1yDJgl+LVdjEGLFKO9KkzZm8hbje7mIrTXZ7sMtTydrJh15H8hHW11XvN/jGS7VudcD5w34ZZzeQYb67fwYO03LN4exo1+LWzNxbA05O5QuzbHqRYn+++CHDx4YK9WLfaedfQzV5em54g5Zbi8OIml+VFMDLWQ7GXoaSmFWZsDZVGCO2u0EbkhHTrhFqi9PmelSsQ8tAtSVch60dpUeGe4kxgZxegzVkBzlQ2NKBG2+iJIMqMok9r8OLRIMqApToSqmAWTmk9B2+o2YW79oshU7ABcuvAFrVGWXkVKpBYoSaBSxIS2mINpiwbjZiUMZRloVfJQyaXDKObBpimBScpHFe8KmmXpaKhK3arGrBVuVBclHN2CiPNin1OVs1tVJYlQlyZBxA6DviQVo6ZaOKd7sTplw53BVugruBBzfsRslw7rZPxaczWutSpQV/gzJPxo1JexyfaxKBBpuiEx+tw+CpKdEvGWTprGlhcwqbIzL5/DYKMYndpK3L1hxf3ZfkrzwybUZjPhnOqmvlcmutFF1jis9QSShOrcWNSXJ1MA0ou/NZWc8Ddfe4VGO3bk0JON1dyMMlK+gmxNrZCFhZF2Kng7YNO0awt4b7wLNp2EqtAsF6ImP56SG0B6siovTYpIjg15gapCVhAfJRUyIBFEo6k8AyuTtkcC/qvG/XbDexulWJvqgYH0o0nKhVHFJ40XwFQnWM5OCX+XMg86c3KvVMSMapCmPpSTIygTxGKZZOcOXhrr3Mp4uzkFuG6B3ajE3TELDDU8qEmsmvRATxquKkxAnSTFjwKEfv3JU9JC5unG6rQ1bTkbQ4Yq/DVgxOqwBWt2K9Yne3ZCZvrgHO2k5paHzOhSiVCZSkdNTgzy40JRlPgDhDHBCxUZdCs91G8fLeK87zOl6XSOICZYXMGNhDqX9fDP/mbK2DXVi/szm03eLpejl5pzOfqwOt4JBT8OeYwQt/4R/BR0OzXiLCM5LOCji/4nXt46rpywgG+zor5RxgSdupBzJdglSY+5ZZbl3XNY6mbn7W0Lcx06zBg1WBjtcC6OmG+OmRTrFrnIUZESZeVeCpwh8TpiPsQ47/tloM97T+/6m8mg55mT3tStyL54mhlwwtszNvjzD8/6HH8i7PvvPPRioZdRWuDBZUR6pEWG7I8P9Xs1Jsj36MfvvO5J/+rTw58dP7afJPfBgeef3XGz/gskFVpJc4HwGwAAAABJRU5ErkJggg==' - } - }; - - ExpandComment = { - init: function() { - if (g.VIEW !== 'index' || !Conf['Comment Expansion']) { - return; - } - if (g.BOARD.ID === 'g') { - this.callbacks.push(Fourchan.code); - } - if (g.BOARD.ID === 'sci') { - this.callbacks.push(Fourchan.math); - } - return Post.prototype.callbacks.push({ - name: 'Comment Expansion', - cb: this.node - }); - }, - node: function() { - var a; - - if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) { - return $.on(a, 'click', ExpandComment.cb); - } - }, - callbacks: [], - cb: function(e) { - e.preventDefault(); - return ExpandComment.expand(Get.postFromNode(this)); - }, - expand: function(post) { - var a; - - if (post.nodes.longComment && !post.nodes.longComment.parentNode) { - $.replace(post.nodes.shortComment, post.nodes.longComment); - post.nodes.comment = post.nodes.longComment; - return; - } - if (!(a = $('.abbr > a', post.nodes.comment))) { - return; - } - a.textContent = "Post No." + post + " Loading..."; - return $.cache("//api.4chan.org" + a.pathname + ".json", function() { - return ExpandComment.parse(this, a, post); - }); - }, - contract: function(post) { - var a; - - if (!post.nodes.shortComment) { - return; - } - a = $('.abbr > a', post.nodes.shortComment); - a.textContent = 'here'; - $.replace(post.nodes.longComment, post.nodes.shortComment); - return post.nodes.comment = post.nodes.shortComment; - }, - parse: function(req, a, post) { - var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; - - status = req.status; - if (![200, 304].contains(status)) { - a.textContent = "Error " + req.statusText + " (" + status + ")"; - return; - } - posts = JSON.parse(req.response).posts; - if (spoilerRange = posts[0].custom_spoiler) { - Build.spoilerRange[g.BOARD] = spoilerRange; - } - for (_i = 0, _len = posts.length; _i < _len; _i++) { - postObj = posts[_i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - a.textContent = "Post No." + post + " not found."; - return; - } - comment = post.nodes.comment; - clone = comment.cloneNode(false); - clone.innerHTML = postObj.com; - _ref = $$('.quotelink', clone); - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - quote = _ref[_j]; - href = quote.getAttribute('href'); - if (href[0] === '/') { - continue; - } - quote.href = "/" + post.board + "/res/" + href; - } - Build.capcodeReplies({ - boardID: post.board.ID, - threadID: post.thread.ID, - bq: clone, - capcodeReplies: postObj.capcode_replies - }); - post.nodes.shortComment = comment; - $.replace(comment, clone); - post.nodes.comment = post.nodes.longComment = clone; - post.parseComment(); - post.parseQuotes(); - _ref1 = ExpandComment.callbacks; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - callback = _ref1[_k]; - callback.call(post); - } - } - }; - - ExpandThread = { - init: function() { - if (g.VIEW !== 'index' || !Conf['Thread Expansion']) { - return; - } - return Thread.prototype.callbacks.push({ - name: 'Thread Expansion', - cb: this.node - }); - }, - node: function() { - var a, files, posts, span, _ref; - - if (!(span = $.x('following-sibling::span[contains(@class,"summary")][1]', this.OP.nodes.root))) { - return; - } - _ref = span.textContent.match(/\d+/g), posts = _ref[0], files = _ref[1]; - a = $.el('a', { - textContent: ExpandThread.text('+', posts, files), - className: 'summary', - href: 'javascript:;' - }); - $.on(a, 'click', ExpandThread.cbToggle); - return $.replace(span, a); - }, - text: function(status, posts, files) { - return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + "."); - }, - cbToggle: function() { - return ExpandThread.toggle(Get.threadFromNode(this)); - }, - toggle: function(thread) { - var a, files, filesCount, inlined, num, post, posts, postsCount, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4; - - threadRoot = thread.OP.nodes.root.parentNode; - a = $('.summary', threadRoot); - switch (thread.isExpanded) { - case false: - case void 0: - _ref = $$('.thread > .postContainer', threadRoot); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - post = _ref[_i]; - ExpandComment.expand(Get.postFromRoot(post)); - } - if (!a) { - thread.isExpanded = true; - return; - } - thread.isExpanded = 'loading'; - _ref1 = a.textContent.match(/\d+/g), posts = _ref1[0], files = _ref1[1]; - a.textContent = ExpandThread.text('...', posts, files); - $.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() { - return ExpandThread.parse(this, thread, a); - }); - break; - case 'loading': - thread.isExpanded = false; - if (!a) { - return; - } - _ref2 = a.textContent.match(/\d+/g), posts = _ref2[0], files = _ref2[1]; - a.textContent = ExpandThread.text('+', posts, files); - break; - case true: - thread.isExpanded = false; - num = (function() { - if (thread.isSticky) { - return 1; - } else { - switch (g.BOARD.ID) { - case 'b': - case 'vg': - case 'q': - return 3; - case 't': - return 1; - default: - return 5; - } - } - })(); - posts = $$(".thread > .replyContainer", threadRoot); - _ref3 = [thread.OP.nodes.root].concat(posts.slice(-num)); - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - post = _ref3[_j]; - ExpandComment.contract(Get.postFromRoot(post)); - } - if (!a) { - return; - } - postsCount = 0; - filesCount = 0; - _ref4 = posts.slice(0, -num); - for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { - reply = _ref4[_k]; - if (Conf['Quote Inlining']) { - while (inlined = $('.inlined', reply)) { - inlined.click(); - } - } - postsCount++; - if ('file' in Get.postFromRoot(reply)) { - filesCount++; - } - $.rm(reply); - } - a.textContent = ExpandThread.text('+', postsCount, filesCount); - } - }, - parse: function(req, thread, a) { - var filesCount, link, post, posts, postsCount, postsObj, postsRoot, reply, root, spoilerRange, _i, _len; - - if (a.textContent[0] === '+') { - return; - } - if (![200, 304].contains(req.status)) { - a.textContent = "Error " + req.statusText + " (" + req.status + ")"; - $.off(a, 'click', ExpandThread.cbToggle); - return; - } - thread.isExpanded = true; - posts = JSON.parse(req.response).posts; - if (spoilerRange = posts.shift().custom_spoiler) { - Build.spoilerRange[thread.board] = spoilerRange; - } - postsObj = []; - postsRoot = []; - filesCount = 0; - for (_i = 0, _len = posts.length; _i < _len; _i++) { - reply = posts[_i]; - if (post = thread.posts[reply.no]) { - if ('file' in post) { - filesCount++; - } - postsRoot.push(post.nodes.root); - continue; - } - root = Build.postFromObject(reply, thread.board.ID); - post = new Post(root, thread, thread.board); - link = $('a[title="Highlight this post"]', root); - link.href = "res/" + thread + "#p" + post; - link.nextSibling.href = "res/" + thread + "#q" + post; - if ('file' in post) { - filesCount++; - } - postsObj.push(post); - postsRoot.push(root); - } - Main.callbackNodes(Post, postsObj); - $.after(a, postsRoot); - postsCount = postsRoot.length; - a.textContent = ExpandThread.text('-', postsCount, filesCount); - return Fourchan.parseThread(thread.ID, 1, postsCount); - } - }; - - FileInfo = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['File Info Formatting']) { - return; - } - this.funk = this.createFunc(Conf['fileInfo']); - return Post.prototype.callbacks.push({ - name: 'File Info Formatting', - cb: this.node - }); - }, - node: function() { - if (!this.file || this.isClone) { - return; - } - return this.file.text.innerHTML = FileInfo.funk(FileInfo, this); - }, - createFunc: function(format) { - var code; - - code = format.replace(/%(.)/g, function(s, c) { - if (c in FileInfo.formatters) { - return "' + FileInfo.formatters." + c + ".call(post) + '"; - } else { - return s; - } - }); - return Function('FileInfo', 'post', "return '" + code + "'"); - }, - convertUnit: function(size, unit) { - var i; - - if (unit === 'B') { - return "" + (size.toFixed()) + " Bytes"; - } - i = 1 + ['KB', 'MB'].indexOf(unit); - while (i--) { - size /= 1024; - } - size = unit === 'MB' ? Math.round(size * 100) / 100 : size.toFixed(); - return "" + size + " " + unit; - }, - escape: function(name) { - return name.replace(/<|>/g, function(c) { - return c === '<' && '<' || '>'; - }); - }, - formatters: { - t: function() { - return this.file.URL.match(/\d+\..+$/)[0]; - }, - T: function() { - return "" + (FileInfo.formatters.t.call(this)) + ""; - }, - l: function() { - return "" + (FileInfo.formatters.n.call(this)) + ""; - }, - L: function() { - return "" + (FileInfo.formatters.N.call(this)) + ""; - }, - n: function() { - var fullname, shortname; - - fullname = this.file.name; - shortname = Build.shortFilename(this.file.name, this.isReply); - if (fullname === shortname) { - return FileInfo.escape(fullname); - } else { - return "" + (FileInfo.escape(shortname)) + "" + (FileInfo.escape(fullname)) + ""; - } - }, - N: function() { - return FileInfo.escape(this.file.name); - }, - p: function() { - if (this.file.isSpoiler) { - return 'Spoiler, '; - } else { - return ''; - } - }, - s: function() { - return this.file.size; - }, - B: function() { - return FileInfo.convertUnit(this.file.sizeInBytes, 'B'); - }, - K: function() { - return FileInfo.convertUnit(this.file.sizeInBytes, 'KB'); - }, - M: function() { - return FileInfo.convertUnit(this.file.sizeInBytes, 'MB'); - }, - r: function() { - if (this.file.isImage) { - return this.file.dimensions; - } else { - return 'PDF'; - } - } - } - }; - - Fourchan = { - init: function() { - var board; - - if (g.VIEW === 'catalog') { - return; - } - board = g.BOARD.ID; - if (board === 'g') { - $.globalEval("window.addEventListener('prettyprint', function(e) {\n var pre = e.detail;\n pre.innerHTML = prettyPrintOne(pre.innerHTML);\n}, false);"); - Post.prototype.callbacks.push({ - name: 'Parse /g/ code', - cb: this.code - }); - } - if (board === 'sci') { - $.globalEval("window.addEventListener('jsmath', function(e) {\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(e.detail);\n } else {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push('ProcessBeforeShowing', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);"); - return Post.prototype.callbacks.push({ - name: 'Parse /sci/ math', - cb: this.math - }); - } - }, - code: function() { - var pre, _i, _len, _ref; - - if (this.isClone) { - return; - } - _ref = $$('.prettyprint:not(.prettyprinted)', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - pre = _ref[_i]; - $.event('prettyprint', pre, window); - $.addClass(pre, 'prettyprinted'); - } - }, - math: function() { - if (this.isClone || !$('.math', this.nodes.comment)) { - return; - } - return $.event('jsmath', this.nodes.post, window); - }, - parseThread: function(threadID, offset, limit) { - return $.event('4chanParsingDone', { - threadId: threadID, - offset: offset, - limit: limit - }); - } - }; - - Keybinds = { - init: function() { - var init; - - if (g.VIEW === 'catalog' || !Conf['Keybinds']) { - return; - } - init = function() { - var node, _i, _len, _ref; - - $.off(d, '4chanXInitFinished', init); - $.on(d, 'keydown', Keybinds.keydown); - _ref = $$('[accesskey]'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - node = _ref[_i]; - node.removeAttribute('accesskey'); - } - }; - return $.on(d, '4chanXInitFinished', init); - }, - keydown: function(e) { - var form, key, notification, notifications, op, target, thread, threadRoot, _i, _len; - - if (!(key = Keybinds.keyCode(e))) { - return; - } - target = e.target; - if (['INPUT', 'TEXTAREA'].contains(target.nodeName)) { - if (!/(Esc|Alt|Ctrl|Meta)/.test(key)) { - return; - } - } - threadRoot = Nav.getThread(); - if (op = $('.op', threadRoot)) { - thread = Get.postFromNode(op).thread; - } - switch (key) { - case Conf['Toggle board list']: - if (Conf['Custom Board Navigation']) { - Header.toggleBoardList(); - } - break; - case Conf['Toggle header']: - Header.toggleBarVisibility(); - break; - case Conf['Open empty QR']: - Keybinds.qr(threadRoot); - break; - case Conf['Open QR']: - Keybinds.qr(threadRoot, true); - break; - case Conf['Open settings']: - Settings.open(); - break; - case Conf['Close']: - if (Settings.dialog) { - Settings.close(); - } else if ((notifications = $$('.notification')).length) { - for (_i = 0, _len = notifications.length; _i < _len; _i++) { - notification = notifications[_i]; - $('.close', notification).click(); - } - } else if (QR.nodes) { - if (Conf['Persistent QR']) { - QR.hide(); - } else { - QR.close(); - } - } - break; - case Conf['Spoiler tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('spoiler', target); - break; - case Conf['Code tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('code', target); - break; - case Conf['Eqn tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('eqn', target); - break; - case Conf['Math tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('math', target); - break; - case Conf['Toggle sage']: - if (QR.nodes) { - Keybinds.sage(); - } - break; - case Conf['Submit QR']: - if (QR.nodes && !QR.status()) { - QR.submit(); - } - break; - case Conf['Watch']: - ThreadWatcher.toggle(thread); - break; - case Conf['Update']: - ThreadUpdater.update(); - break; - case Conf['Expand image']: - Keybinds.img(threadRoot); - break; - case Conf['Expand images']: - Keybinds.img(threadRoot, true); - break; - case Conf['Open Gallery']: - Gallery.cb.toggle(); - break; - case Conf['fappeTyme']: - FappeTyme.cb.fappe(); - break; - case Conf['werkTyme']: - FappeTyme.cb.werk(); - break; - case Conf['Front page']: - window.location = "/" + g.BOARD + "/0#delform"; - break; - case Conf['Open front page']: - $.open("/" + g.BOARD + "/#delform"); - break; - case Conf['Next page']: - if (g.VIEW === 'thread') { - return; - } - if (form = $('.next form')) { - window.location = form.action; - } - break; - case Conf['Previous page']: - if (g.VIEW === 'thread') { - return; - } - if (form = $('.prev form')) { - window.location = form.action; - } - break; - case Conf['Open catalog']: - if (Conf['External Catalog']) { - window.location = CatalogLinks.external(g.BOARD.ID); - } else { - window.location = "/" + g.BOARD + "/catalog"; - } - break; - case Conf['Next thread']: - if (g.VIEW !== 'index') { - return; - } - Nav.scroll(+1); - break; - case Conf['Previous thread']: - if (g.VIEW !== 'index') { - return; - } - Nav.scroll(-1); - break; - case Conf['Expand thread']: - ExpandThread.toggle(thread); - break; - case Conf['Open thread']: - Keybinds.open(thread); - break; - case Conf['Open thread tab']: - Keybinds.open(thread, true); - break; - case Conf['Next reply']: - Keybinds.hl(+1, threadRoot); - break; - case Conf['Previous reply']: - Keybinds.hl(-1, threadRoot); - break; - case Conf['Deselect reply']: - Keybinds.hl(0, threadRoot); - break; - case Conf['Hide']: - if (g.VIEW === 'index') { - ThreadHiding.toggle(thread); - } - break; - case Conf['Previous Post Quoting You']: - QuoteYou.cb.seek('preceding'); - break; - case Conf['Next Post Quoting You']: - QuoteYou.cb.seek('following'); - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }, - keyCode: function(e) { - var kc, key; - - key = (function() { - switch (kc = e.keyCode) { - case 8: - return ''; - case 13: - return 'Enter'; - case 27: - return 'Esc'; - case 37: - return 'Left'; - case 38: - return 'Up'; - case 39: - return 'Right'; - case 40: - return 'Down'; - default: - if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { - return String.fromCharCode(kc).toLowerCase(); - } else { - return null; - } - } - })(); - if (key) { - if (e.altKey) { - key = 'Alt+' + key; - } - if (e.ctrlKey) { - key = 'Ctrl+' + key; - } - if (e.metaKey) { - key = 'Meta+' + key; - } - if (e.shiftKey) { - key = 'Shift+' + key; - } - } - return key; - }, - qr: function(thread, quote) { - if (!(Conf['Quick Reply'] && QR.postingIsEnabled)) { - return; - } - QR.open(); - if (quote) { - QR.quote.call($('input', $('.post.highlight', thread) || thread)); - } - QR.nodes.com.focus(); - if (Conf['QR Shortcut']) { - return $.rmClass($('.qr-shortcut'), 'disabled'); - } - }, - tags: function(tag, ta) { - var range, selEnd, selStart, value; - - value = ta.value; - selStart = ta.selectionStart; - selEnd = ta.selectionEnd; - ta.value = value.slice(0, selStart) + ("[" + tag + "]") + value.slice(selStart, selEnd) + ("[/" + tag + "]") + value.slice(selEnd); - range = ("[" + tag + "]").length + selEnd; - ta.setSelectionRange(range, range); - return $.event('input', null, ta); - }, - sage: function() { - var isSage; - - isSage = /sage/i.test(QR.nodes.email.value); - return QR.nodes.email.value = isSage ? "" : "sage"; - }, - img: function(thread, all) { - var post; - - if (all) { - return ImageExpand.cb.toggleAll(); - } else { - post = Get.postFromNode($('.post.highlight', thread) || $('.op', thread)); - return ImageExpand.toggle(post); - } - }, - open: function(thread, tab) { - var url; - - if (g.VIEW !== 'index') { - return; - } - url = "/" + thread.board + "/res/" + thread; - if (tab) { - return $.open(url); - } else { - return location.href = url; - } - }, - hl: function(delta, thread) { - var axe, headRect, next, postEl, rect, replies, reply, root, topMargin, _i, _len; - - if (!delta) { - if (postEl = $('.reply.highlight', thread)) { - $.rmClass(postEl, 'highlight'); - } - return; - } - if (Conf['Fixed Header'] && Conf['Bottom header']) { - topMargin = 0; - } else { - headRect = Header.bar.getBoundingClientRect(); - topMargin = headRect.top + headRect.height; - } - if (postEl = $('.reply.highlight', thread)) { - $.rmClass(postEl, 'highlight'); - rect = postEl.getBoundingClientRect(); - if (rect.bottom >= topMargin && rect.top <= doc.clientHeight) { - root = postEl.parentNode; - axe = delta === +1 ? 'following' : 'preceding'; - next = $.x("" + axe + "-sibling::div[contains(@class,'replyContainer')][1]/child::div[contains(@class,'reply')]", root); - if (!next) { - this.focus(postEl); - return; - } - if (!(g.VIEW === 'thread' || $.x('ancestor::div[parent::div[@class="board"]]', next) === thread)) { - return; - } - rect = next.getBoundingClientRect(); - if (rect.top < 0 || rect.bottom > doc.clientHeight) { - if (delta === -1) { - window.scrollBy(0, rect.top - topMargin); - } else { - next.scrollIntoView(false); - } - } - this.focus(next); - return; - } - } - replies = $$('.reply', thread); - if (delta === -1) { - replies.reverse(); - } - for (_i = 0, _len = replies.length; _i < _len; _i++) { - reply = replies[_i]; - rect = reply.getBoundingClientRect(); - if (delta === +1 && rect.top >= topMargin || delta === -1 && rect.bottom <= doc.clientHeight) { - this.focus(reply); - return; - } - } - }, - focus: function(post) { - return $.addClass(post, 'highlight'); - } - }; - - Nav = { - init: function() { - var append, next, prev, span; - - switch (g.VIEW) { - case 'index': - if (!Conf['Index Navigation']) { - return; - } - break; - case 'thread': - if (!Conf['Reply Navigation']) { - return; - } - break; - default: - return; - } - span = $.el('span', { - id: 'navlinks' - }); - prev = $.el('a', { - textContent: '▲', - href: 'javascript:;' - }); - next = $.el('a', { - textContent: '▼', - href: 'javascript:;' - }); - $.on(prev, 'click', this.prev); - $.on(next, 'click', this.next); - $.add(span, [prev, $.tn(' '), next]); - append = function() { - $.off(d, '4chanXInitFinished', append); - return $.add(d.body, span); - }; - return $.on(d, '4chanXInitFinished', append); - }, - prev: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, 0); - } else { - return Nav.scroll(-1); - } - }, - next: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, d.body.scrollHeight); - } else { - return Nav.scroll(+1); - } - }, - getThread: function(full) { - var headRect, i, rect, thread, threads, topMargin, _i, _len; - - if (Conf['Bottom header'] || !Conf['Fixed Header']) { - topMargin = 0; - } else { - headRect = Header.bar.getBoundingClientRect(); - topMargin = headRect.top + headRect.height; - } - threads = $$('.thread').filter(function(thread) { - thread = Get.threadFromRoot(thread); - return !(thread.isHidden && !thread.stub); - }); - for (i = _i = 0, _len = threads.length; _i < _len; i = ++_i) { - thread = threads[i]; - rect = thread.getBoundingClientRect(); - if (rect.bottom > topMargin) { - if (full) { - return [threads, thread, i, rect, topMargin]; - } else { - return thread; - } - } - } - return $('.board'); - }, - scroll: function(delta) { - var i, rect, thread, threads, top, topMargin, _ref, _ref1; - - _ref = Nav.getThread(true), threads = _ref[0], thread = _ref[1], i = _ref[2], rect = _ref[3], topMargin = _ref[4]; - top = rect.top - topMargin; - if ((delta === -1 && top > -5) || (delta === +1 && top < 5)) { - top = ((_ref1 = threads[i + delta]) != null ? _ref1.getBoundingClientRect().top : void 0) - topMargin; - } - return window.scrollBy(0, top); - } - }; - - RelativeDates = { - INTERVAL: $.MINUTE / 2, - init: function() { - if (g.VIEW === 'catalog' || !Conf['Relative Post Dates']) { - return; - } - $.on(d, 'visibilitychange ThreadUpdate', this.flush); - this.flush(); - return Post.prototype.callbacks.push({ - name: 'Relative Post Dates', - cb: this.node - }); - }, - node: function() { - var dateEl; - - if (this.isClone) { - return; - } - dateEl = this.nodes.date; - dateEl.title = dateEl.textContent; - return RelativeDates.setUpdate(this); - }, - relative: function(diff, now, date) { - var days, months, number, rounded, unit, years; - - unit = (number = diff / $.DAY) >= 1 ? (years = now.getYear() - date.getYear(), months = now.getMonth() - date.getMonth(), days = now.getDate() - date.getDate(), years > 1 ? (number = years - (months < 0 || months === 0 && days < 0), 'year') : years === 1 && (months > 0 || months === 0 && days >= 0) ? (number = years, 'year') : (months = (months + 12) % 12) > 1 ? (number = months - (days < 0), 'month') : months === 1 && days >= 0 ? (number = months, 'month') : 'day') : (number = diff / $.HOUR) >= 1 ? 'hour' : (number = diff / $.MINUTE) >= 1 ? 'minute' : (number = Math.max(0, diff) / $.SECOND, 'second'); - rounded = Math.round(number); - if (rounded !== 1) { - unit += 's'; - } - return "" + rounded + " " + unit + " ago"; - }, - stale: [], - flush: function() { - var now, update, _i, _len, _ref; - - if (d.hidden) { - return; - } - now = new Date(); - _ref = RelativeDates.stale; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - update = _ref[_i]; - update(now); - } - RelativeDates.stale = []; - clearTimeout(RelativeDates.timeout); - return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); - }, - setUpdate: function(post) { - var markStale, setOwnTimeout, update; - - setOwnTimeout = function(diff) { - var delay; - - delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY; - return setTimeout(markStale, delay); - }; - update = function(now) { - var date, diff, relative, singlePost, _i, _len, _ref; - - date = post.info.date; - diff = now - date; - relative = RelativeDates.relative(diff, now, date); - _ref = [post].concat(post.clones); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - singlePost = _ref[_i]; - singlePost.nodes.date.firstChild.textContent = relative; - } - return setOwnTimeout(diff); - }; - markStale = function() { - return RelativeDates.stale.push(update); - }; - return update(new Date()); - } - }; - - RemoveSpoilers = { - init: function() { - if (Conf['Reveal Spoilers'] && !Conf['Remove Spoilers']) { - $.addClass(doc, 'reveal-spoilers'); - } - if (!Conf['Remove Spoilers']) { - return; - } - if (Conf['Reveal Spoilers']) { - this.wrapper = function(text) { - return "[spoiler]" + text + "[/spoiler]"; - }; - } - return Post.prototype.callbacks.push({ - name: 'Reveal Spoilers', - cb: this.node - }); - }, - wrapper: function(text) { - return text; - }, - node: function(post) { - var spoiler, spoilers, _i, _len; - - spoilers = $$('s', this.nodes.comment); - for (_i = 0, _len = spoilers.length; _i < _len; _i++) { - spoiler = spoilers[_i]; - $.replace(spoiler, $.tn(RemoveSpoilers.wrapper(spoiler.textContent))); - } - } - }; - - Report = { - init: function() { - if (!/report/.test(location.search)) { - return; - } - return $.asap((function() { - return $.id('recaptcha_response_field'); - }), Report.ready); - }, - ready: function() { - var field; - - field = $.id('recaptcha_response_field'); - $.on(field, 'keydown', function(e) { - if (e.keyCode === 8 && !field.value) { - return $.globalEval('Recaptcha.reload("t")'); - } - }); - return $.on($('form'), 'submit', function(e) { - var response; - - e.preventDefault(); - response = field.value.trim(); - if (!/\s/.test(response)) { - field.value = "" + response + " " + response; - } - return this.submit(); - }); - } - }; - - Time = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Time Formatting']) { - return; - } - this.funk = this.createFunc(Conf['time']); - return Post.prototype.callbacks.push({ - name: 'Time Formatting', - cb: this.node - }); - }, - node: function() { - if (this.isClone) { - return; - } - return this.nodes.date.textContent = Time.funk(Time, this.info.date); - }, - createFunc: function(format) { - var code; - - code = format.replace(/%([A-Za-z])/g, function(s, c) { - if (c in Time.formatters) { - return "' + Time.formatters." + c + ".call(date) + '"; - } else { - return s; - } - }); - return Function('Time', 'date', "return '" + code + "'"); - }, - day: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - zeroPad: function(n) { - if (n < 10) { - return "0" + n; - } else { - return n; - } - }, - formatters: { - a: function() { - return Time.day[this.getDay()].slice(0, 3); - }, - A: function() { - return Time.day[this.getDay()]; - }, - b: function() { - return Time.month[this.getMonth()].slice(0, 3); - }, - B: function() { - return Time.month[this.getMonth()]; - }, - d: function() { - return Time.zeroPad(this.getDate()); - }, - e: function() { - return this.getDate(); - }, - H: function() { - return Time.zeroPad(this.getHours()); - }, - I: function() { - return Time.zeroPad(this.getHours() % 12 || 12); - }, - k: function() { - return this.getHours(); - }, - l: function() { - return this.getHours() % 12 || 12; - }, - m: function() { - return Time.zeroPad(this.getMonth() + 1); - }, - M: function() { - return Time.zeroPad(this.getMinutes()); - }, - p: function() { - if (this.getHours() < 12) { - return 'AM'; - } else { - return 'PM'; - } - }, - P: function() { - if (this.getHours() < 12) { - return 'am'; - } else { - return 'pm'; - } - }, - S: function() { - return Time.zeroPad(this.getSeconds()); - }, - y: function() { - return this.getFullYear().toString().slice(2); - }, - Y: function() { - return this.getFullYear(); - } - } - }; - - Settings = { - init: function() { - var link, settings; - - link = $.el('a', { - className: 'settings-link fourchanx-icon icon-wrench', - textContent: 'Settings', - href: 'javascript:;' - }); - $.on(link, 'click', Settings.open); - Header.addShortcut(link); - $.get('previousversion', null, function(item) { - var changelog, el, previous; - - if (previous = item['previousversion']) { - if (previous === g.VERSION) { - return; - } - changelog = 'https://github.com/seaweedchan/4chan-x/blob/master/CHANGELOG.md'; - el = $.el('span', { - innerHTML: "4chan X has been updated to version " + g.VERSION + "." - }); - if (Conf['Show Updated Notifications']) { - new Notice('info', el, 30); - } - } else { - $.on(d, '4chanXInitFinished', Settings.open); - } - return $.set('previousversion', g.VERSION); - }); - Settings.addSection('Main', Settings.main); - Settings.addSection('Filter', Settings.filter); - Settings.addSection('Sauce', Settings.sauce); - Settings.addSection('Advanced', Settings.advanced); - Settings.addSection('Keybinds', Settings.keybinds); - $.on(d, 'AddSettingsSection', Settings.addSection); - $.on(d, 'OpenSettings', function(e) { - return Settings.open(e.detail); - }); - settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; - if (settings.disableAll) { - return; - } - settings.disableAll = true; - return localStorage.setItem('4chan-settings', JSON.stringify(settings)); - }, - open: function(openSection) { - var dialog, html, link, links, overlay, section, sectionToOpen, _i, _len, _ref; - - $.off(d, '4chanXInitFinished', Settings.open); - if (Settings.dialog) { - return; - } - $.event('CloseMenu'); - html = "
"; - Settings.overlay = overlay = $.el('div', { - id: 'overlay' - }); - Settings.dialog = dialog = $.el('div', { - id: 'fourchanx-settings', - className: 'dialog', - innerHTML: html - }); - $.on($('.export', Settings.dialog), 'click', Settings["export"]); - $.on($('.import', Settings.dialog), 'click', Settings["import"]); - $.on($('input', Settings.dialog), 'change', Settings.onImport); - links = []; - _ref = Settings.sections; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - section = _ref[_i]; - link = $.el('a', { - className: "tab-" + section.hyphenatedTitle, - textContent: section.title, - href: 'javascript:;' - }); - $.on(link, 'click', Settings.openSection.bind(section)); - links.push(link, $.tn(' | ')); - if (section.title === openSection) { - sectionToOpen = link; - } - } - links.pop(); - $.add($('.sections-list', dialog), links); - (sectionToOpen ? sectionToOpen : links[0]).click(); - $.on($('.close', dialog), 'click', Settings.close); - $.on(overlay, 'click', Settings.close); - $.add(d.body, [overlay, dialog]); - return $.event('OpenSettings', null, dialog); - }, - close: function() { - if (!Settings.dialog) { - return; - } - $.rm(Settings.overlay); - $.rm(Settings.dialog); - delete Settings.overlay; - return delete Settings.dialog; - }, - sections: [], - addSection: function(title, open) { - var hyphenatedTitle, _ref; - - if (typeof title !== 'string') { - _ref = title.detail, title = _ref.title, open = _ref.open; - } - hyphenatedTitle = title.toLowerCase().replace(/\s+/g, '-'); - return Settings.sections.push({ - title: title, - hyphenatedTitle: hyphenatedTitle, - open: open - }); - }, - openSection: function() { - var section, selected; - - if (selected = $('.tab-selected', Settings.dialog)) { - $.rmClass(selected, 'tab-selected'); - } - $.addClass($(".tab-" + this.hyphenatedTitle, Settings.dialog), 'tab-selected'); - section = $('section', Settings.dialog); - $.rmAll(section); - section.className = "section-" + this.hyphenatedTitle; - this.open(section, g); - section.scrollTop = 0; - return $.event('OpenSettings', null, section); - }, - main: function(section) { - var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref; - - items = {}; - inputs = {}; - _ref = Config.main; - for (key in _ref) { - obj = _ref[key]; - fs = $.el('fieldset', { - innerHTML: "" + key + "" - }); - for (key in obj) { - arr = obj[key]; - description = arr[1]; - div = $.el('div', { - innerHTML: ": " + description + "" - }); - input = $('input', div); - $.on(input, 'change', $.cb.checked); - items[key] = Conf[key]; - inputs[key] = input; - $.add(fs, div); - } - $.add(section, fs); - } - $.get(items, function(items) { - var val; - - for (key in items) { - val = items[key]; - inputs[key].checked = val; - } - }); - div = $.el('div', { - innerHTML: ": Clear manually-hidden threads and posts on all boards. Refresh the page to apply." - }); - button = $('button', div); - hiddenNum = 0; - $.get('hiddenThreads', { - boards: {} - }, function(item) { - var ID, board, thread, _ref1; - - _ref1 = item.hiddenThreads.boards; - for (ID in _ref1) { - board = _ref1[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum++; - } - } - return button.textContent = "Hidden: " + hiddenNum; - }); - $.get('hiddenPosts', { - boards: {} - }, function(item) { - var ID, board, post, thread, _ref1; - - _ref1 = item.hiddenPosts.boards; - for (ID in _ref1) { - board = _ref1[ID]; - for (ID in board) { - thread = board[ID]; - for (ID in thread) { - post = thread[ID]; - hiddenNum++; - } - } - } - return button.textContent = "Hidden: " + hiddenNum; - }); - $.on(button, 'click', function() { - this.textContent = 'Hidden: 0'; - return $.get('hiddenThreads', { - boards: {} - }, function(item) { - var boardID; - - for (boardID in item.hiddenThreads.boards) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - return $["delete"](['hiddenThreads', 'hiddenPosts']); - }); - }); - return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div); - }, - "export": function(now, data) { - var a, db, p, _i, _len, _ref; - - if (typeof now !== 'number') { - now = Date.now(); - data = { - version: g.VERSION, - date: now - }; - _ref = DataBoard.keys; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - db = _ref[_i]; - Conf[db] = { - boards: {} - }; - } - $.get(Conf, function(Conf) { - delete Conf['archives']; - data.Conf = Conf; - return Settings["export"](now, data); - }); - return; - } - a = $.el('a', { - className: 'warning', - textContent: 'Save me!', - download: "4chan X v" + g.VERSION + "-" + now + ".json", - href: "data:application/json;base64," + (btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))))), - target: '_blank' - }); - p = $('.imp-exp-result', Settings.dialog); - $.rmAll(p); - return $.add(p, a); - }, - "import": function() { - return this.nextElementSibling.click(); - }, - onImport: function() { - var file, output, reader; - - if (!(file = this.files[0])) { - return; - } - output = $('.imp-exp-result'); - if (!confirm('Your current settings will be entirely overwritten, are you sure?')) { - output.textContent = 'Import aborted.'; - return; - } - reader = new FileReader(); - reader.onload = function(e) { - var data, err; - - try { - data = JSON.parse(e.target.result); - Settings.loadSettings(data); - if (confirm('Import successful. Refresh now?')) { - return window.location.reload(); - } - } catch (_error) { - err = _error; - output.textContent = 'Import failed due to an error.'; - return c.error(err.stack); - } - }; - return reader.readAsText(file); - }, - loadSettings: function(data) { - var key, val, version, _ref; - - version = data.version.split('.'); - if (version[0] === '2') { - data = Settings.convertSettings(data, { - 'Disable 4chan\'s extension': '', - 'Catalog Links': '', - 'Reply Navigation': '', - 'Show Stubs': 'Stubs', - 'Image Auto-Gif': 'Auto-GIF', - 'Expand From Current': '', - 'Unread Tab Icon': 'Unread Favicon', - 'Post in Title': 'Thread Excerpt', - 'Auto Hide QR': '', - 'Open Reply in New Tab': '', - 'Remember QR size': '', - 'Quote Inline': 'Quote Inlining', - 'Quote Preview': 'Quote Previewing', - 'Indicate OP quote': 'Mark OP Quotes', - 'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes', - 'Reply Hiding': 'Reply Hiding Buttons', - 'Thread Hiding': 'Thread Hiding Buttons', - 'uniqueid': 'uniqueID', - 'mod': 'capcode', - 'country': 'flag', - 'md5': 'MD5', - 'openEmptyQR': 'Open empty QR', - 'openQR': 'Open QR', - 'openOptions': 'Open settings', - 'close': 'Close', - 'spoiler': 'Spoiler tags', - 'code': 'Code tags', - 'submit': 'Submit QR', - 'watch': 'Watch', - 'update': 'Update', - 'unreadCountTo0': '', - 'expandAllImages': 'Expand images', - 'expandImage': 'Expand image', - 'zero': 'Front page', - 'nextPage': 'Next page', - 'previousPage': 'Previous page', - 'nextThread': 'Next thread', - 'previousThread': 'Previous thread', - 'expandThread': 'Expand thread', - 'openThreadTab': 'Open thread', - 'openThread': 'Open thread tab', - 'nextReply': 'Next reply', - 'previousReply': 'Previous reply', - 'hide': 'Hide', - 'Scrolling': 'Auto Scroll', - 'Verbose': '' - }); - data.Conf.sauces = data.Conf.sauces.replace(/\$\d/g, function(c) { - switch (c) { - case '$1': - return '%TURL'; - case '$2': - return '%URL'; - case '$3': - return '%MD5'; - case '$4': - return '%board'; - default: - return c; - } - }); - _ref = Config.hotkeys; - for (key in _ref) { - val = _ref[key]; - if (key in data.Conf) { - data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) { - return "" + (s[0].toUpperCase()) + s.slice(1); - }).replace(/(^|.+\+)[A-Z]$/g, function(s) { - return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase()); - }); - } - } - data.Conf['WatchedThreads'] = data.WatchedThreads; - } - if (data.Conf['WatchedThreads']) { - data.Conf['watchedThreads'] = { - boards: ThreadWatcher.convert(data.Conf['WatchedThreads']) - }; - delete data.Conf['WatchedThreads']; - } - return $.set(data.Conf); - }, - convertSettings: function(data, map) { - var newKey, prevKey; - - for (prevKey in map) { - newKey = map[prevKey]; - if (newKey) { - data.Conf[newKey] = data.Conf[prevKey]; - } - delete data.Conf[prevKey]; - } - return data; - }, - filter: function(section) { - var select; - - section.innerHTML = "
"; - select = $('select', section); - $.on(select, 'change', Settings.selectFilter); - return Settings.selectFilter.call(select); - }, - selectFilter: function() { - var div, name, ta; - - div = this.nextElementSibling; - if ((name = this.value) !== 'guide') { - $.rmAll(div); - ta = $.el('textarea', { - name: name, - className: 'field', - spellcheck: false - }); - $.get(name, Conf[name], function(item) { - return ta.value = item[name]; - }); - $.on(ta, 'change', $.cb.value); - $.add(div, ta); - return; - } - return div.innerHTML = "
Filter is disabled.

\nUse regular expressions, one per line.
\nLines starting with a # will be ignored.
\nFor example, /weeaboo/i will filter posts containing the string `weeaboo`, case-insensitive.
\nMD5 filtering uses exact string matching, not regular expressions.\n

    You can use these settings with each regular expression, separate them with semicolons:\n
  • \n Per boards, separate them with commas. It is global if not specified.
    \n For example: boards:a,jp;.\n
  • \n Filter OPs only along with their threads (`only`), replies only (`no`), or both (`yes`, this is default).
    \n For example: op:only;, op:no; or op:yes;.\n
  • \n Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
    \n For example: stub:yes; or stub:no;.\n
  • \n Highlight instead of hiding. You can specify a class name to use with a userstyle.
    \n For example: highlight; or highlight:wallpaper;.\n
  • \n Highlighted OPs will have their threads put on top of board pages by default.
    \n For example: top:yes; or top:no;.\n
"; - }, - sauce: function(section) { - var ta; - - section.innerHTML = "
Sauce is disabled.
Lines starting with a # will be ignored.
You can specify a display text by appending ;text:[text] to the URL.
    These parameters will be replaced by their corresponding values:\n
  • %TURL: Thumbnail URL.
  • %URL: Full image URL.
  • %MD5: MD5 hash.
  • %board: Current board.
"; - ta = $('textarea', section); - $.get('sauces', Conf['sauces'], function(item) { - return ta.value = item['sauces']; - }); - return $.on(ta, 'change', $.cb.value); - }, - advanced: function(section) { - var archive, boardID, boardOptions, boardSelect, boards, data, event, input, inputs, item, items, name, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4; - - section.innerHTML = "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Disabled selections indicate that only one archive is available for that board and redirection type.
Custom Board Navigation
New lines will be converted into spaces.

In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; - items = {}; - inputs = {}; - _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'sageEmoji', 'emojiPos', 'usercss']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - input = $("[name=" + name + "]", section); - items[name] = Conf[name]; - inputs[name] = input; - event = ['favicon', 'usercss', 'sageEmoji', 'emojiPos'].contains(name) ? 'change' : 'input'; - $.on(input, event, $.cb.value); - } - ta = $('.personafield', section); - $.get('QR.personas', Conf['QR.personas'], function(item) { - return ta.value = item['QR.personas']; - }); - $.on(ta, 'change', $.cb.value); - $.get(items, function(items) { - var key, val; - - for (key in items) { - val = items[key]; - if (['emojiPos'].contains(key)) { - continue; - } - input = inputs[key]; - input.value = val; - if (key === 'usercss') { - continue; - } - $.on(input, event, Settings[key]); - Settings[key].call(input); - } - }); - $.on($('input[name=Interval]', section), 'change', ThreadUpdater.cb.interval); - $.on($('input[name="Custom CSS"]', section), 'change', Settings.togglecss); - $.on($.id('apply-css'), 'click', Settings.usercss); - boards = {}; - _ref1 = Redirect.archives; - for (name in _ref1) { - archive = _ref1[name]; - _ref2 = archive.boards; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - boardID = _ref2[_j]; - data = boards[boardID] || (boards[boardID] = { - thread: [], - post: [], - file: [] - }); - data.thread.push(name); - if (archive.software === 'foolfuuka') { - data.post.push(name); - } - if (archive.files.contains(boardID)) { - data.file.push(name); - } - } - } - rows = []; - boardOptions = []; - _ref3 = Object.keys(boards).sort(); - for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { - boardID = _ref3[_k]; - row = $.el('tr', { - className: "board-" + boardID - }); - row.hidden = boardID !== g.BOARD.ID; - boardOptions.push($.el('option', { - textContent: "/" + boardID + "/", - value: "board-" + boardID, - selected: boardID === g.BOARD.ID - })); - data = boards[boardID]; - _ref4 = ['thread', 'post', 'file']; - for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { - item = _ref4[_l]; - $.add(row, Settings.addArchiveCell(boardID, data, item)); - } - rows.push(row); - } - $.add($('tbody', section), rows); - boardSelect = $('#archive-board-select', section); - $.add(boardSelect, boardOptions); - table = $.id('archive-table'); - $.on(boardSelect, 'change', function() { - $('tbody > :not([hidden])', table).hidden = true; - return $("tbody > ." + this.value, table).hidden = false; - }); - $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { - var option, selectedArchives, type; - - selectedArchives = _arg.selectedArchives; - for (boardID in selectedArchives) { - data = selectedArchives[boardID]; - for (type in data) { - name = data[type]; - if (option = $("select[data-boardid='" + boardID + "'][data-type='" + type + "'] > option[value='" + name + "']", section)) { - option.selected = true; - } - } - } - }); - }, - addArchiveCell: function(boardID, data, type) { - var archive, i, length, options, select, td; - - length = data[type].length; - td = $.el('td', { - className: 'archive-cell' - }); - if (!length) { - td.textContent = '--'; - return td; - } - options = []; - i = 0; - while (i < length) { - archive = data[type][i++]; - options.push($.el('option', { - textContent: archive, - value: archive - })); - } - td.innerHTML = ''; - select = td.firstElementChild; - if (!(select.disabled = length === 1)) { - select.setAttribute('data-boardid', boardID); - select.setAttribute('data-type', type); - $.on(select, 'change', Settings.saveSelectedArchive); - } - $.add(select, options); - return td; - }, - saveSelectedArchive: function() { - var _this = this; - - return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { - var selectedArchives, _name; - - selectedArchives = _arg.selectedArchives; - (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value; - return $.set('selectedArchives', selectedArchives); - }); - }, - boardnav: function() { - return Header.generateBoardList(this.value); - }, - time: function() { - var funk; - - funk = Time.createFunc(this.value); - return this.nextElementSibling.textContent = funk(Time, new Date()); - }, - backlink: function() { - return this.nextElementSibling.textContent = this.value.replace(/%id/, '123456789'); - }, - fileInfo: function() { - var data, funk; - - data = { - isReply: true, - file: { - URL: '//images.4chan.org/g/src/1334437723720.jpg', - name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', - size: '276 KB', - sizeInBytes: 276 * 1024, - dimensions: '1280x720', - isImage: true, - isSpoiler: true - } - }; - funk = FileInfo.createFunc(this.value); - return this.nextElementSibling.innerHTML = funk(FileInfo, data); - }, - favicon: function() { - Favicon["switch"](); - if (g.VIEW === 'thread' && Conf['Unread Favicon']) { - Unread.update(); - } - return this.nextElementSibling.innerHTML = "\n\n\n"; - }, - sageEmoji: function() { - return this.nextElementSibling.innerHTML = ""; - }, - togglecss: function() { - if ($('textarea[name=usercss]', $.x('ancestor::fieldset[1]', this)).disabled = !this.checked) { - CustomCSS.rmStyle(); - } else { - CustomCSS.addStyle(); - } - return $.cb.checked.call(this); - }, - usercss: function() { - return CustomCSS.update(); - }, - keybinds: function(section) { - var arr, input, inputs, items, key, tbody, tr, _ref; - - section.innerHTML = "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
"; - tbody = $('tbody', section); - items = {}; - inputs = {}; - _ref = Config.hotkeys; - for (key in _ref) { - arr = _ref[key]; - tr = $.el('tr', { - innerHTML: "" + arr[1] + "" - }); - input = $('input', tr); - input.name = key; - input.spellcheck = false; - items[key] = Conf[key]; - inputs[key] = input; - $.on(input, 'keydown', Settings.keybind); - $.add(tbody, tr); - } - return $.get(items, function(items) { - var val; - - for (key in items) { - val = items[key]; - inputs[key].value = val; - } - }); - }, - keybind: function(e) { - var key; - - if (e.keyCode === 9) { - return; - } - e.preventDefault(); - e.stopPropagation(); - if ((key = Keybinds.keyCode(e)) == null) { - return; - } - this.value = key; - return $.cb.value.call(this); - } - }; - - Main = { - init: function() { - var db, flatten, _i, _len, _ref; - - flatten = function(parent, obj) { - var key, val; - - if (obj instanceof Array) { - Conf[parent] = obj[0]; - } else if (typeof obj === 'object') { - for (key in obj) { - val = obj[key]; - flatten(key, val); - } - } else { - Conf[parent] = obj; - } - }; - flatten(null, Config); - _ref = DataBoard.keys; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - db = _ref[_i]; - Conf[db] = { - boards: {} - }; - } - Conf['selectedArchives'] = {}; - Conf['CachedTitles'] = []; - $.get(Conf, function(items) { - $.extend(Conf, items); - return Main.initFeatures(); - }); - $.on(d, '4chanMainInit', Main.initStyle); - return $.asap((function() { - return d.head && $('link[rel="shortcut icon"]', d.head) || d.readyState !== 'loading'; - }), Main.initStyle); - }, - initFeatures: function() { - var init, pathname, _ref; - - pathname = location.pathname.split('/'); - g.BOARD = new Board(pathname[1]); - if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') { - return; - } - g.VIEW = (function() { - switch (pathname[2]) { - case 'res': - return 'thread'; - case 'catalog': - return 'catalog'; - default: - return 'index'; - } - })(); - if (g.VIEW === 'thread') { - g.THREADID = +pathname[3]; - } - switch (location.hostname) { - case 'api.4chan.org': - return; - case 'sys.4chan.org': - Report.init(); - return; - case 'images.4chan.org': - $.ready(function() { - var URL; - - if (Conf['404 Redirect'] && ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { - Redirect.init(); - pathname = location.pathname.split('/'); - URL = Redirect.to('file', { - boardID: g.BOARD.ID, - filename: pathname[pathname.length - 1] - }); - if (URL) { - return location.replace(URL); - } - } - }); - return; - } - init = function(features) { - var err, module, name; - - for (name in features) { - module = features[name]; - try { - module.init(); - } catch (_error) { - err = _error; - Main.handleErrors({ - message: "\"" + name + "\" initialization crashed.", - error: err - }); - } - } - }; - init({ - 'Polyfill': Polyfill, - 'Redirect': Redirect, - 'Header': Header, - 'Catalog Links': CatalogLinks, - 'Settings': Settings, - 'Announcement Hiding': PSAHiding, - 'Fourchan thingies': Fourchan, - 'Emoji': Emoji, - 'Color User IDs': IDColor, - 'Reveal Spoilers': RemoveSpoilers, - 'Custom CSS': CustomCSS, - 'Linkify': Linkify, - 'Resurrect Quotes': Quotify, - 'Filter': Filter, - 'Thread Hiding Buttons': ThreadHiding, - 'Reply Hiding Buttons': PostHiding, - 'Recursive': Recursive, - 'Strike-through Quotes': QuoteStrikeThrough, - 'Quick Reply': QR, - 'Menu': Menu, - 'Report Link': ReportLink, - 'Thread Hiding (Menu)': ThreadHiding.menu, - 'Reply Hiding (Menu)': PostHiding.menu, - 'Delete Link': DeleteLink, - 'Filter (Menu)': Filter.menu, - 'Download Link': DownloadLink, - 'Archive Link': ArchiveLink, - 'Quote Inlining': QuoteInline, - 'Quote Previewing': QuotePreview, - 'Quote Backlinks': QuoteBacklink, - 'Mark Quotes of You': QuoteYou, - 'Mark OP Quotes': QuoteOP, - 'Mark Cross-thread Quotes': QuoteCT, - 'Anonymize': Anonymize, - 'Time Formatting': Time, - 'Relative Post Dates': RelativeDates, - 'File Info Formatting': FileInfo, - 'Fappe Tyme': FappeTyme, - 'Gallery': Gallery, - 'Sauce': Sauce, - 'Image Expansion': ImageExpand, - 'Image Expansion (Menu)': ImageExpand.menu, - 'Reveal Spoiler Thumbnails': RevealSpoilers, - 'Image Loading': ImageLoader, - 'Image Hover': ImageHover, - 'Comment Expansion': ExpandComment, - 'Thread Expansion': ExpandThread, - 'Thread Excerpt': ThreadExcerpt, - 'Favicon': Favicon, - 'Unread': Unread, - 'Quote Threading': QuoteThreading, - 'Thread Stats': ThreadStats, - 'Thread Updater': ThreadUpdater, - 'Thread Watcher': ThreadWatcher, - 'Thread Watcher (Menu)': ThreadWatcher.menu, - 'Index Navigation': Nav, - 'Keybinds': Keybinds, - 'Show Dice Roll': Dice, - 'Banner': Banner - }); - $.on(d, 'AddCallback', Main.addCallback); - return $.ready(Main.initReady); - }, - initStyle: function() { - var mainStyleSheet, setStyle, style, styleSheets, _ref; - - $.off(d, '4chanMainInit', Main.initStyle); - if (!Main.isThisPageLegit() || $.hasClass(doc, 'fourchan-x')) { - return; - } - if ((_ref = $('link[href*=mobile]', d.head)) != null) { - _ref.disabled = true; - } - $.addClass(doc, 'gecko'); - $.addClass(doc, 'fourchan-x'); - $.addClass(doc, 'seaweedchan'); - $.addClass(doc, g.VIEW); - $.addStyle(Main.css); - if (g.VIEW === 'catalog') { - $.addClass(doc, $.id('base-css').href.match(/catalog_(\w+)/)[1].replace('_new', '').replace(/_+/g, '-')); - return; - } - style = 'yotsuba-b'; - mainStyleSheet = $('link[title=switch]', d.head); - styleSheets = $$('link[rel="alternate stylesheet"]', d.head); - setStyle = function() { - var styleSheet, _i, _len; - - $.rmClass(doc, style); - for (_i = 0, _len = styleSheets.length; _i < _len; _i++) { - styleSheet = styleSheets[_i]; - if (styleSheet.href === mainStyleSheet.href) { - style = styleSheet.title.toLowerCase().replace('new', '').trim().replace(/\s+/g, '-'); - break; - } - } - return $.addClass(doc, style); - }; - setStyle(); - if (!mainStyleSheet) { - return; - } - return new MutationObserver(setStyle).observe(mainStyleSheet, { - attributes: true, - attributeFilter: ['href'] - }); - }, - initReady: function() { - var board, err, errors, href, passLink, postRoot, posts, styleSelector, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1; - - if (['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { - if (Conf['404 Redirect'] && g.VIEW === 'thread') { - href = Redirect.to('thread', { - boardID: g.BOARD.ID, - threadID: g.THREADID, - postID: +location.hash.match(/\d+/) - }); - location.replace(href || ("/" + g.BOARD + "/")); - } - return; - } - Main.initStyle(); - if (board = $('.board')) { - threads = []; - posts = []; - _ref = $$('.board > .thread', board); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - threadRoot = _ref[_i]; - thread = new Thread(+threadRoot.id.slice(1), g.BOARD); - threads.push(thread); - _ref1 = $$('.thread > .postContainer', threadRoot); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - postRoot = _ref1[_j]; - try { - posts.push(new Post(postRoot, thread, g.BOARD)); - } catch (_error) { - err = _error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Post No." + (postRoot.id.match(/\d+/)) + " failed. Post will be skipped.", - error: err - }); - } - } - } - if (errors) { - Main.handleErrors(errors); - } - Main.callbackNodes(Thread, threads); - Main.callbackNodesDB(Post, posts, function() { - return $.event('4chanXInitFinished'); - }); - if (styleSelector = $.id('styleSelector')) { - passLink = $.el('a', { - textContent: '4chan Pass', - href: 'javascript:;' - }); - $.on(passLink, 'click', function() { - return window.open('//sys.4chan.org/auth', 'This will steal your data.', 'left=0,top=0,width=500,height=255,toolbar=0,resizable=0'); - }); - $.before(styleSelector.previousSibling, [$.tn('['), passLink, $.tn(']\u00A0\u00A0')]); - } - return; - } - try { - localStorage.getItem('4chan-settings'); - } catch (_error) { - err = _error; - new Notice('warning', 'Cookies need to be enabled on 4chan for 4chan X to properly function.', 30); - Main.disableReports = true; - } - return $.event('4chanXInitFinished'); - }, - callbackNodes: function(klass, nodes) { - var callback, err, errors, i, len, node, _i, _len, _ref; - - len = nodes.length; - _ref = klass.prototype.callbacks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - callback = _ref[_i]; - i = 0; - while (i < len) { - node = nodes[i++]; - try { - callback.cb.call(node); - } catch (_error) { - err = _error; - if (!errors) { - errors = []; - } - errors.push({ - message: "\"" + callback.name + "\" crashed on " + klass.name + " No." + node + " (/" + node.board + "/).", - error: err - }); - } - } - } - if (errors) { - return Main.handleErrors(errors); - } - }, - callbackNodesDB: function(klass, nodes, cb) { - var errors, func, i, len, node, queue, softTask; - - queue = []; - softTask = function() { - var args, func, task; - - task = queue.shift(); - func = task[0]; - args = Array.prototype.slice.call(task, 1); - func.apply(func, args); - if (!queue.length) { - return; - } - if ((queue.length % 7) === 0) { - return setTimeout(softTask, 0); - } else { - return softTask(); - } - }; - len = nodes.length; - i = 0; - errors = null; - func = function(node, i) { - var callback, err, _i, _len, _ref; - - _ref = klass.prototype.callbacks; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - callback = _ref[_i]; - try { - callback.cb.call(node); - } catch (_error) { - err = _error; - if (!errors) { - errors = []; - } - errors.push({ - message: "\"" + callback.name + "\" crashed on " + klass.name + " No." + node + " (/" + node.board + "/).", - error: err - }); - } - } - if (i === len) { - if (errors) { - Main.handleErrors(errors); - } - if (cb) { - return cb(); - } - } - }; - while (i < len) { - node = nodes[i]; - queue.push([func, node, ++i]); - } - return softTask(); - }, - addCallback: function(e) { - var Klass, obj; - - obj = e.detail; - if (typeof obj.callback.name !== 'string') { - throw new Error("Invalid callback name: " + obj.callback.name); - } - switch (obj.type) { - case 'Post': - Klass = Post; - break; - case 'Thread': - Klass = Thread; - break; - default: - return; - } - obj.callback.isAddon = true; - return Klass.prototype.callbacks.push(obj.callback); - }, - handleErrors: function(errors) { - var div, error, logs, _i, _len; - - if (!(errors instanceof Array)) { - error = errors; - } else if (errors.length === 1) { - error = errors[0]; - } - if (error) { - new Notice('error', Main.parseError(error), 15); - return; - } - div = $.el('div', { - innerHTML: "" + errors.length + " errors occurred. [show]" - }); - $.on(div.lastElementChild, 'click', function() { - var _ref; - - return _ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = _ref[0], logs.hidden = _ref[1], _ref; - }); - logs = $.el('div', { - hidden: true - }); - for (_i = 0, _len = errors.length; _i < _len; _i++) { - error = errors[_i]; - $.add(logs, Main.parseError(error)); - } - return new Notice('error', [div, logs], 30); - }, - parseError: function(data) { - var error, message; - - Main.logError(data); - message = $.el('div', { - textContent: data.message - }); - error = $.el('div', { - textContent: data.error - }); - return [message, error]; - }, - errors: [], - logError: function(data) { - c.error(data.message, data.error.stack); - return Main.errors.push(data); - }, - isThisPageLegit: function() { - var _ref; - - if (!('thisPageIsLegit' in Main)) { - Main.thisPageIsLegit = location.hostname === 'boards.4chan.org' && !$('link[href*="favicon-status.ico"]', d.head) && ((_ref = d.title) !== '4chan - Temporarily Offline' && _ref !== '4chan - Error' && _ref !== '504 Gateway Time-out'); - } - return Main.thisPageIsLegit; - }, - css: "/*! * Font Awesome 3.2.1 * the iconic font designed for Bootstrap * ------------------------------------------------------------------------------ * The full suite of pictographic icons, examples, and documentation can be * found at http://fontawesome.io. Stay up to date on Twitter at * http://twitter.com/fontawesome. * * License * ------------------------------------------------------------------------------ * - The Font Awesome font is licensed under SIL OFL 1.1 - * http://scripts.sil.org/OFL * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - * http://opensource.org/licenses/mit-license.html * - Font Awesome documentation licensed under CC BY 3.0 - * http://creativecommons.org/licenses/by/3.0/ * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: * \"Font Awesome by Dave Gandy - http://fontawesome.io\" * * Author - Dave Gandy * ------------------------------------------------------------------------------ * Email: dave@fontawesome.io * Twitter: http://twitter.com/davegandy * Work: Lead Product Designer @ Kyruus - http://kyruus.com */ @font-face { font-family: 'FontAwesome'; src: url('data:application/font-woff;base64,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') format('woff'); font-weight: normal; font-style: normal; } .fourchanx-icon::before { font-family: FontAwesome; font-weight: normal; font-style: normal; text-decoration: inherit; -webkit-font-smoothing: antialiased; *margin-right: .3em; text-decoration: inherit; display: none; speak: none; } :root.shortcut-icons .fourchanx-icon::before { display: inline-block; font-size: 13px; visibility: visible; } :root.shortcut-icons #shortcuts .fourchanx-icon::before { font-size: 15px !important; margin-top: -3px !important; position: relative; top: 1px; } :root.shortcut-icons .fourchanx-icon { font-size: 0; visibility: hidden; } :root.shortcut-icons .shortcut.brackets-wrap::before, :root.shortcut-icons .shortcut.brackets-wrap::after { display: none; } /* makes sure icons active on rollover in links */ :root.shortcut-icons a .fourchanx-icon { display: inline; } /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen readers do not read off random characters that represent icons */ .icon-glass::before { content: \"\\f000\"; } .icon-music::before { content: \"\\f001\"; } .icon-search::before { content: \"\\f002\"; } .icon-envelope-alt::before { content: \"\\f003\"; } .icon-heart::before { content: \"\\f004\"; } .icon-star::before { content: \"\\f005\"; } .icon-star-empty::before { content: \"\\f006\"; } .icon-user::before { content: \"\\f007\"; } .icon-film::before { content: \"\\f008\"; } .icon-th-large::before { content: \"\\f009\"; } .icon-th::before { content: \"\\f00a\"; } .icon-th-list::before { content: \"\\f00b\"; } .icon-ok::before { content: \"\\f00c\"; } .icon-remove::before { content: \"\\f00d\"; } .icon-zoom-in::before { content: \"\\f00e\"; } .icon-zoom-out::before { content: \"\\f010\"; } .icon-power-off:before, .icon-off::before { content: \"\\f011\"; } .icon-signal::before { content: \"\\f012\"; } .icon-gear:before, .icon-cog::before { content: \"\\f013\"; } .icon-trash::before { content: \"\\f014\"; } .icon-home::before { content: \"\\f015\"; } .icon-file-alt::before { content: \"\\f016\"; } .icon-time::before { content: \"\\f017\"; } .icon-road::before { content: \"\\f018\"; } .icon-download-alt::before { content: \"\\f019\"; } .icon-download::before { content: \"\\f01a\"; } .icon-upload::before { content: \"\\f01b\"; } .icon-inbox::before { content: \"\\f01c\"; } .icon-play-circle::before { content: \"\\f01d\"; } .icon-rotate-right:before, .icon-repeat::before { content: \"\\f01e\"; } .icon-refresh::before { content: \"\\f021\"; } .icon-list-alt::before { content: \"\\f022\"; } .icon-lock::before { content: \"\\f023\"; } .icon-flag::before { content: \"\\f024\"; } .icon-headphones::before { content: \"\\f025\"; } .icon-volume-off::before { content: \"\\f026\"; } .icon-volume-down::before { content: \"\\f027\"; } .icon-volume-up::before { content: \"\\f028\"; } .icon-qrcode::before { content: \"\\f029\"; } .icon-barcode::before { content: \"\\f02a\"; } .icon-tag::before { content: \"\\f02b\"; } .icon-tags::before { content: \"\\f02c\"; } .icon-book::before { content: \"\\f02d\"; } .icon-bookmark::before { content: \"\\f02e\"; } .icon-print::before { content: \"\\f02f\"; } .icon-camera::before { content: \"\\f030\"; } .icon-font::before { content: \"\\f031\"; } .icon-bold::before { content: \"\\f032\"; } .icon-italic::before { content: \"\\f033\"; } .icon-text-height::before { content: \"\\f034\"; } .icon-text-width::before { content: \"\\f035\"; } .icon-align-left::before { content: \"\\f036\"; } .icon-align-center::before { content: \"\\f037\"; } .icon-align-right::before { content: \"\\f038\"; } .icon-align-justify::before { content: \"\\f039\"; } .icon-list::before { content: \"\\f03a\"; } .icon-indent-left::before { content: \"\\f03b\"; } .icon-indent-right::before { content: \"\\f03c\"; } .icon-facetime-video::before { content: \"\\f03d\"; } .icon-picture::before { content: \"\\f03e\"; } .icon-pencil::before { content: \"\\f040\"; } .icon-map-marker::before { content: \"\\f041\"; } .icon-adjust::before { content: \"\\f042\"; } .icon-tint::before { content: \"\\f043\"; } .icon-edit::before { content: \"\\f044\"; } .icon-share::before { content: \"\\f045\"; } .icon-check::before { content: \"\\f046\"; } .icon-move::before { content: \"\\f047\"; } .icon-step-backward::before { content: \"\\f048\"; } .icon-fast-backward::before { content: \"\\f049\"; } .icon-backward::before { content: \"\\f04a\"; } .icon-play::before { content: \"\\f04b\"; } .icon-pause::before { content: \"\\f04c\"; } .icon-stop::before { content: \"\\f04d\"; } .icon-forward::before { content: \"\\f04e\"; } .icon-fast-forward::before { content: \"\\f050\"; } .icon-step-forward::before { content: \"\\f051\"; } .icon-eject::before { content: \"\\f052\"; } .icon-chevron-left::before { content: \"\\f053\"; } .icon-chevron-right::before { content: \"\\f054\"; } .icon-plus-sign::before { content: \"\\f055\"; } .icon-minus-sign::before { content: \"\\f056\"; } .icon-remove-sign::before { content: \"\\f057\"; } .icon-ok-sign::before { content: \"\\f058\"; } .icon-question-sign::before { content: \"\\f059\"; } .icon-info-sign::before { content: \"\\f05a\"; } .icon-screenshot::before { content: \"\\f05b\"; } .icon-remove-circle::before { content: \"\\f05c\"; } .icon-ok-circle::before { content: \"\\f05d\"; } .icon-ban-circle::before { content: \"\\f05e\"; } .icon-arrow-left::before { content: \"\\f060\"; } .icon-arrow-right::before { content: \"\\f061\"; } .icon-arrow-up::before { content: \"\\f062\"; } .icon-arrow-down::before { content: \"\\f063\"; } .icon-mail-forward:before, .icon-share-alt::before { content: \"\\f064\"; } .icon-resize-full::before { content: \"\\f065\"; } .icon-resize-small::before { content: \"\\f066\"; } .icon-plus::before { content: \"\\f067\"; } .icon-minus::before { content: \"\\f068\"; } .icon-asterisk::before { content: \"\\f069\"; } .icon-exclamation-sign::before { content: \"\\f06a\"; } .icon-gift::before { content: \"\\f06b\"; } .icon-leaf::before { content: \"\\f06c\"; } .icon-fire::before { content: \"\\f06d\"; } .icon-eye-open::before { content: \"\\f06e\"; } .icon-eye-close::before { content: \"\\f070\"; } .icon-warning-sign::before { content: \"\\f071\"; } .icon-plane::before { content: \"\\f072\"; } .icon-calendar::before { content: \"\\f073\"; } .icon-random::before { content: \"\\f074\"; } .icon-comment::before { content: \"\\f075\"; } .icon-magnet::before { content: \"\\f076\"; } .icon-chevron-up::before { content: \"\\f077\"; } .icon-chevron-down::before { content: \"\\f078\"; } .icon-retweet::before { content: \"\\f079\"; } .icon-shopping-cart::before { content: \"\\f07a\"; } .icon-folder-close::before { content: \"\\f07b\"; } .icon-folder-open::before { content: \"\\f07c\"; } .icon-resize-vertical::before { content: \"\\f07d\"; } .icon-resize-horizontal::before { content: \"\\f07e\"; } .icon-bar-chart::before { content: \"\\f080\"; } .icon-twitter-sign::before { content: \"\\f081\"; } .icon-facebook-sign::before { content: \"\\f082\"; } .icon-camera-retro::before { content: \"\\f083\"; } .icon-key::before { content: \"\\f084\"; } .icon-gears:before, .icon-cogs::before { content: \"\\f085\"; } .icon-comments::before { content: \"\\f086\"; } .icon-thumbs-up-alt::before { content: \"\\f087\"; } .icon-thumbs-down-alt::before { content: \"\\f088\"; } .icon-star-half::before { content: \"\\f089\"; } .icon-heart-empty::before { content: \"\\f08a\"; } .icon-signout::before { content: \"\\f08b\"; } .icon-linkedin-sign::before { content: \"\\f08c\"; } .icon-pushpin::before { content: \"\\f08d\"; } .icon-external-link::before { content: \"\\f08e\"; } .icon-signin::before { content: \"\\f090\"; } .icon-trophy::before { content: \"\\f091\"; } .icon-github-sign::before { content: \"\\f092\"; } .icon-upload-alt::before { content: \"\\f093\"; } .icon-lemon::before { content: \"\\f094\"; } .icon-phone::before { content: \"\\f095\"; } .icon-unchecked:before, .icon-check-empty::before { content: \"\\f096\"; } .icon-bookmark-empty::before { content: \"\\f097\"; } .icon-phone-sign::before { content: \"\\f098\"; } .icon-twitter::before { content: \"\\f099\"; } .icon-facebook::before { content: \"\\f09a\"; } .icon-github::before { content: \"\\f09b\"; } .icon-unlock::before { content: \"\\f09c\"; } .icon-credit-card::before { content: \"\\f09d\"; } .icon-rss::before { content: \"\\f09e\"; } .icon-hdd::before { content: \"\\f0a0\"; } .icon-bullhorn::before { content: \"\\f0a1\"; } .icon-bell::before { content: \"\\f0a2\"; } .icon-certificate::before { content: \"\\f0a3\"; } .icon-hand-right::before { content: \"\\f0a4\"; } .icon-hand-left::before { content: \"\\f0a5\"; } .icon-hand-up::before { content: \"\\f0a6\"; } .icon-hand-down::before { content: \"\\f0a7\"; } .icon-circle-arrow-left::before { content: \"\\f0a8\"; } .icon-circle-arrow-right::before { content: \"\\f0a9\"; } .icon-circle-arrow-up::before { content: \"\\f0aa\"; } .icon-circle-arrow-down::before { content: \"\\f0ab\"; } .icon-globe::before { content: \"\\f0ac\"; } .icon-wrench::before { content: \"\\f0ad\"; } .icon-tasks::before { content: \"\\f0ae\"; } .icon-filter::before { content: \"\\f0b0\"; } .icon-briefcase::before { content: \"\\f0b1\"; } .icon-fullscreen::before { content: \"\\f0b2\"; } .icon-group::before { content: \"\\f0c0\"; } .icon-link::before { content: \"\\f0c1\"; } .icon-cloud::before { content: \"\\f0c2\"; } .icon-beaker::before { content: \"\\f0c3\"; } .icon-cut::before { content: \"\\f0c4\"; } .icon-copy::before { content: \"\\f0c5\"; } .icon-paperclip:before, .icon-paper-clip::before { content: \"\\f0c6\"; } .icon-save::before { content: \"\\f0c7\"; } .icon-sign-blank::before { content: \"\\f0c8\"; } .icon-reorder::before { content: \"\\f0c9\"; } .icon-list-ul::before { content: \"\\f0ca\"; } .icon-list-ol::before { content: \"\\f0cb\"; } .icon-strikethrough::before { content: \"\\f0cc\"; } .icon-underline::before { content: \"\\f0cd\"; } .icon-table::before { content: \"\\f0ce\"; } .icon-magic::before { content: \"\\f0d0\"; } .icon-truck::before { content: \"\\f0d1\"; } .icon-pinterest::before { content: \"\\f0d2\"; } .icon-pinterest-sign::before { content: \"\\f0d3\"; } .icon-google-plus-sign::before { content: \"\\f0d4\"; } .icon-google-plus::before { content: \"\\f0d5\"; } .icon-money::before { content: \"\\f0d6\"; } .icon-caret-down::before { content: \"\\f0d7\"; } .icon-caret-up::before { content: \"\\f0d8\"; } .icon-caret-left::before { content: \"\\f0d9\"; } .icon-caret-right::before { content: \"\\f0da\"; } .icon-columns::before { content: \"\\f0db\"; } .icon-sort::before { content: \"\\f0dc\"; } .icon-sort-down::before { content: \"\\f0dd\"; } .icon-sort-up::before { content: \"\\f0de\"; } .icon-envelope::before { content: \"\\f0e0\"; } .icon-linkedin::before { content: \"\\f0e1\"; } .icon-rotate-left:before, .icon-undo::before { content: \"\\f0e2\"; } .icon-legal::before { content: \"\\f0e3\"; } .icon-dashboard::before { content: \"\\f0e4\"; } .icon-comment-alt::before { content: \"\\f0e5\"; } .icon-comments-alt::before { content: \"\\f0e6\"; } .icon-bolt::before { content: \"\\f0e7\"; } .icon-sitemap::before { content: \"\\f0e8\"; } .icon-umbrella::before { content: \"\\f0e9\"; } .icon-paste::before { content: \"\\f0ea\"; } .icon-lightbulb::before { content: \"\\f0eb\"; } .icon-exchange::before { content: \"\\f0ec\"; } .icon-cloud-download::before { content: \"\\f0ed\"; } .icon-cloud-upload::before { content: \"\\f0ee\"; } .icon-user-md::before { content: \"\\f0f0\"; } .icon-stethoscope::before { content: \"\\f0f1\"; } .icon-suitcase::before { content: \"\\f0f2\"; } .icon-bell-alt::before { content: \"\\f0f3\"; } .icon-coffee::before { content: \"\\f0f4\"; } .icon-food::before { content: \"\\f0f5\"; } .icon-file-text-alt::before { content: \"\\f0f6\"; } .icon-building::before { content: \"\\f0f7\"; } .icon-hospital::before { content: \"\\f0f8\"; } .icon-ambulance::before { content: \"\\f0f9\"; } .icon-medkit::before { content: \"\\f0fa\"; } .icon-fighter-jet::before { content: \"\\f0fb\"; } .icon-beer::before { content: \"\\f0fc\"; } .icon-h-sign::before { content: \"\\f0fd\"; } .icon-plus-sign-alt::before { content: \"\\f0fe\"; } .icon-double-angle-left::before { content: \"\\f100\"; } .icon-double-angle-right::before { content: \"\\f101\"; } .icon-double-angle-up::before { content: \"\\f102\"; } .icon-double-angle-down::before { content: \"\\f103\"; } .icon-angle-left::before { content: \"\\f104\"; } .icon-angle-right::before { content: \"\\f105\"; } .icon-angle-up::before { content: \"\\f106\"; } .icon-angle-down::before { content: \"\\f107\"; } .icon-desktop::before { content: \"\\f108\"; } .icon-laptop::before { content: \"\\f109\"; } .icon-tablet::before { content: \"\\f10a\"; } .icon-mobile-phone::before { content: \"\\f10b\"; } .icon-circle-blank::before { content: \"\\f10c\"; } .icon-quote-left::before { content: \"\\f10d\"; } .icon-quote-right::before { content: \"\\f10e\"; } .icon-spinner::before { content: \"\\f110\"; } .icon-circle::before { content: \"\\f111\"; } .icon-mail-reply:before, .icon-reply::before { content: \"\\f112\"; } .icon-github-alt::before { content: \"\\f113\"; } .icon-folder-close-alt::before { content: \"\\f114\"; } .icon-folder-open-alt::before { content: \"\\f115\"; } .icon-expand-alt::before { content: \"\\f116\"; } .icon-collapse-alt::before { content: \"\\f117\"; } .icon-smile::before { content: \"\\f118\"; } .icon-frown::before { content: \"\\f119\"; } .icon-meh::before { content: \"\\f11a\"; } .icon-gamepad::before { content: \"\\f11b\"; } .icon-keyboard::before { content: \"\\f11c\"; } .icon-flag-alt::before { content: \"\\f11d\"; } .icon-flag-checkered::before { content: \"\\f11e\"; } .icon-terminal::before { content: \"\\f120\"; } .icon-code::before { content: \"\\f121\"; } .icon-reply-all::before { content: \"\\f122\"; } .icon-mail-reply-all::before { content: \"\\f122\"; } .icon-star-half-full:before, .icon-star-half-empty::before { content: \"\\f123\"; } .icon-location-arrow::before { content: \"\\f124\"; } .icon-crop::before { content: \"\\f125\"; } .icon-code-fork::before { content: \"\\f126\"; } .icon-unlink::before { content: \"\\f127\"; } .icon-question::before { content: \"\\f128\"; } .icon-info::before { content: \"\\f129\"; } .icon-exclamation::before { content: \"\\f12a\"; } .icon-superscript::before { content: \"\\f12b\"; } .icon-subscript::before { content: \"\\f12c\"; } .icon-eraser::before { content: \"\\f12d\"; } .icon-puzzle-piece::before { content: \"\\f12e\"; } .icon-microphone::before { content: \"\\f130\"; } .icon-microphone-off::before { content: \"\\f131\"; } .icon-shield::before { content: \"\\f132\"; } .icon-calendar-empty::before { content: \"\\f133\"; } .icon-fire-extinguisher::before { content: \"\\f134\"; } .icon-rocket::before { content: \"\\f135\"; } .icon-maxcdn::before { content: \"\\f136\"; } .icon-chevron-sign-left::before { content: \"\\f137\"; } .icon-chevron-sign-right::before { content: \"\\f138\"; } .icon-chevron-sign-up::before { content: \"\\f139\"; } .icon-chevron-sign-down::before { content: \"\\f13a\"; } .icon-html5::before { content: \"\\f13b\"; } .icon-css3::before { content: \"\\f13c\"; } .icon-anchor::before { content: \"\\f13d\"; } .icon-unlock-alt::before { content: \"\\f13e\"; } .icon-bullseye::before { content: \"\\f140\"; } .icon-ellipsis-horizontal::before { content: \"\\f141\"; } .icon-ellipsis-vertical::before { content: \"\\f142\"; } .icon-rss-sign::before { content: \"\\f143\"; } .icon-play-sign::before { content: \"\\f144\"; } .icon-ticket::before { content: \"\\f145\"; } .icon-minus-sign-alt::before { content: \"\\f146\"; } .icon-check-minus::before { content: \"\\f147\"; } .icon-level-up::before { content: \"\\f148\"; } .icon-level-down::before { content: \"\\f149\"; } .icon-check-sign::before { content: \"\\f14a\"; } .icon-edit-sign::before { content: \"\\f14b\"; } .icon-external-link-sign::before { content: \"\\f14c\"; } .icon-share-sign::before { content: \"\\f14d\"; } .icon-compass::before { content: \"\\f14e\"; } .icon-collapse::before { content: \"\\f150\"; } .icon-collapse-top::before { content: \"\\f151\"; } .icon-expand::before { content: \"\\f152\"; } .icon-euro:before, .icon-eur::before { content: \"\\f153\"; } .icon-gbp::before { content: \"\\f154\"; } .icon-dollar:before, .icon-usd::before { content: \"\\f155\"; } .icon-rupee:before, .icon-inr::before { content: \"\\f156\"; } .icon-yen:before, .icon-jpy::before { content: \"\\f157\"; } .icon-renminbi:before, .icon-cny::before { content: \"\\f158\"; } .icon-won:before, .icon-krw::before { content: \"\\f159\"; } .icon-bitcoin:before, .icon-btc::before { content: \"\\f15a\"; } .icon-file::before { content: \"\\f15b\"; } .icon-file-text::before { content: \"\\f15c\"; } .icon-sort-by-alphabet::before { content: \"\\f15d\"; } .icon-sort-by-alphabet-alt::before { content: \"\\f15e\"; } .icon-sort-by-attributes::before { content: \"\\f160\"; } .icon-sort-by-attributes-alt::before { content: \"\\f161\"; } .icon-sort-by-order::before { content: \"\\f162\"; } .icon-sort-by-order-alt::before { content: \"\\f163\"; } .icon-thumbs-up::before { content: \"\\f164\"; } .icon-thumbs-down::before { content: \"\\f165\"; } .icon-youtube-sign::before { content: \"\\f166\"; } .icon-youtube::before { content: \"\\f167\"; } .icon-xing::before { content: \"\\f168\"; } .icon-xing-sign::before { content: \"\\f169\"; } .icon-youtube-play::before { content: \"\\f16a\"; } .icon-dropbox::before { content: \"\\f16b\"; } .icon-stackexchange::before { content: \"\\f16c\"; } .icon-instagram::before { content: \"\\f16d\"; } .icon-flickr::before { content: \"\\f16e\"; } .icon-adn::before { content: \"\\f170\"; } .icon-bitbucket::before { content: \"\\f171\"; } .icon-bitbucket-sign::before { content: \"\\f172\"; } .icon-tumblr::before { content: \"\\f173\"; } .icon-tumblr-sign::before { content: \"\\f174\"; } .icon-long-arrow-down::before { content: \"\\f175\"; } .icon-long-arrow-up::before { content: \"\\f176\"; } .icon-long-arrow-left::before { content: \"\\f177\"; } .icon-long-arrow-right::before { content: \"\\f178\"; } .icon-apple::before { content: \"\\f179\"; } .icon-windows::before { content: \"\\f17a\"; } .icon-android::before { content: \"\\f17b\"; } .icon-linux::before { content: \"\\f17c\"; } .icon-dribbble::before { content: \"\\f17d\"; } .icon-skype::before { content: \"\\f17e\"; } .icon-foursquare::before { content: \"\\f180\"; } .icon-trello::before { content: \"\\f181\"; } .icon-female::before { content: \"\\f182\"; } .icon-male::before { content: \"\\f183\"; } .icon-gittip::before { content: \"\\f184\"; } .icon-sun::before { content: \"\\f185\"; } .icon-moon::before { content: \"\\f186\"; } .icon-archive::before { content: \"\\f187\"; } .icon-bug::before { content: \"\\f188\"; } .icon-vk::before { content: \"\\f189\"; } .icon-weibo::before { content: \"\\f18a\"; } .icon-renren::before { content: \"\\f18b\"; }\n/* General */ .dialog { box-shadow: 0 1px 2px rgba(0, 0, 0, .15); border: 1px solid; display: block; padding: 0; } .captcha-img, .field { background-color: #FFF; border: 1px solid #CCC; -moz-box-sizing: border-box; box-sizing: border-box; color: #333; font: 13px sans-serif; outline: none; transition: color .25s, border-color .25s; transition: color .25s, border-color .25s; } .field::-moz-placeholder, .field:hover::-moz-placeholder { color: #AAA !important; font-size: 13px !important; opacity: 1.0 !important; } .captch-img:hover, .field:hover { border-color: #999; } .field:hover, .field:focus { color: #000; } .field[disabled] { background-color: #F2F2F2; color: #888; } .move { cursor: move; overflow: hidden; } label, .watch-thread-link { cursor: pointer; } a[href=\"javascript:;\"] { text-decoration: none; } .warning { color: red; } #boardNavDesktop { display: none !important; } a { outline: none !important; } .painted { border-radius: 3px; padding: 0px 2px; } /* 4chan style fixes */ .opContainer, .op { display: block !important; overflow: visible !important; } [hidden] { display: none !important; } /* fixed, z-index */ #overlay, #fourchanx-settings, #qp, #ihover, #navlinks, .fixed #header-bar, :root.float #updater, :root.float #thread-stats, #qr { position: fixed; } #fourchanx-settings { z-index: 999; } #overlay { z-index: 900; } #notifications { z-index: 70; } #qp, #ihover { z-index: 60; } #menu { z-index: 50; } #navlinks, #updater, #thread-stats { z-index: 40; } .fixed #header-bar.autohide { z-index: 35; } #qr { z-index: 30; } #thread-watcher { z-index: 8; } :root.fixed-watcher #thread-watcher { z-index: 20; } .fixed #header-bar { z-index: 10; } /* Header */ .fixed.top body { padding-top: 2em; } .fixed.bottom body { padding-bottom: 2em; } .fixed #header-bar { right: 0; left: 0; padding: 3px 4px 4px; } .fixed.top #header-bar { top: 0; } .fixed.bottom #header-bar { bottom: 0; } #header-bar { border-width: 0; transition: all .1s .05s ease-in-out; } :root.centered-links #shortcuts { width: 300px; text-align: right; } :root.centered-links #header-bar { text-align: center; } :root.centered-links #custom-board-list { position: relative; left: 150px; } .fixed.top #header-bar { border-bottom-width: 1px; } .fixed.bottom #header-bar { box-shadow: 0 -1px 2px rgba(0, 0, 0, .15); border-top-width: 1px; } .fixed.bottom #header-bar .menu-button i { border-top: none; border-bottom: 6px solid; } #board-list { text-align: center; } .fixed #header-bar.autohide:not(:hover) { box-shadow: none; transition: all .8s .6s cubic-bezier(.55, .055, .675, .19); } .fixed.top #header-bar.autohide:not(:hover) { margin-bottom: -1em; -webkit-transform: translateY(-100%); transform: translateY(-100%); } .fixed.bottom #header-bar.autohide:not(:hover) { -webkit-transform: translateY(100%); transform: translateY(100%); } #scroll-marker { left: 0; right: 0; height: 10px; position: absolute; } :root:not(.autohide) #scroll-marker { pointer-events: none; } #header-bar #scroll-marker { display: none; } .fixed #header-bar #scroll-marker { display: block; } .fixed.top #header-bar #scroll-marker { top: 100%; } .fixed.bottom #header-bar #scroll-marker { bottom: 100%; } #header-bar a:not(.entry):not(.close) { text-decoration: none; padding: 1px; } #header-bar input { margin: 0; vertical-align: bottom; } #shortcuts:empty { display: none; } .brackets-wrap::before { content: \"\\00a0[\"; } .brackets-wrap::after { content: \"]\\00a0\"; } .dead-thread, .disabled { opacity: .45; } #shortcuts { float: right; } .shortcut { margin-left: 3px; } #navbotright, #navtopright { display: none; } #toggleMsgBtn { display: none !important; } .current { font-weight: bold; } /* 4chan X link brackets */ .brackets-wrap::after { content: \"]\"; } .brackets-wrap::before { content: \"[\"; } /* Notifications */ #notifications { position: fixed; top: 0; height: 0; text-align: center; right: 0; left: 0; transition: all .8s .6s cubic-bezier(.55, .055, .675, .19); } .fixed.top #header-bar #notifications { position: absolute; top: 100%; } .notification { color: #FFF; font-weight: 700; text-shadow: 0 1px 2px rgba(0, 0, 0, .5); box-shadow: 0 1px 2px rgba(0, 0, 0, .15); border-radius: 2px; margin: 1px auto; width: 500px; max-width: 100%; position: relative; transition: all .25s ease-in-out; } .notification.error { background-color: hsla(0, 100%, 38%, .9); } .notification.warning { background-color: hsla(36, 100%, 38%, .9); } .notification.info { background-color: hsla(200, 100%, 38%, .9); } .notification.success { background-color: hsla(104, 100%, 38%, .9); } .notification a { color: white; } .notification > .close { padding: 6px; top: 0; right: 5px; position: absolute; } .message { -moz-box-sizing: border-box; box-sizing: border-box; padding: 6px 20px; max-height: 200px; width: 100%; overflow: auto; } /* Settings */ :root.fourchan-x body { -moz-box-sizing: border-box; box-sizing: border-box; } #overlay { background-color: rgba(0, 0, 0, .5); top: 0; left: 0; height: 100%; width: 100%; } #fourchanx-settings { -moz-box-sizing: border-box; box-sizing: border-box; box-shadow: 0 0 15px rgba(0, 0, 0, .15); height: 600px; max-height: 100%; width: 900px; max-width: 100%; margin: auto; padding: 3px; top: 50%; left: 50%; -moz-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } #fourchanx-settings > nav { padding: 2px 2px 0; height: 15px; } #fourchanx-settings > nav a { text-decoration: underline; } #fourchanx-settings > nav a.close { text-decoration: none; padding: 2px; } .section-container { overflow: auto; position: absolute; top: 2.1em; right: 5px; bottom: 5px; left: 5px; padding-right: 5px; } .sections-list { padding: 0 3px; float: left; } .credits { float: right; } .tab-selected { font-weight: 700; } .section-sauce ul, .section-advanced ul { list-style: none; margin: 0; } .section-sauce ul { padding: 8px; } .section-advanced ul { padding: 0px; } .section-sauce li, .section-advanced li { padding-left: 4px; } .section-main label { text-decoration: underline; } .section-filter ul { padding: 0; } .section-filter li { margin: 10px 40px; } .section-filter textarea { height: 500px; } .section-sauce textarea { height: 350px; } .section-advanced .field[name=\"boardnav\"] { width: 100%; } .section-advanced textarea { height: 150px; } .section-advanced .archive-cell { min-width: 160px; text-align: center; } .section-advanced #archive-board-select { position: absolute; } .section-advanced .note { font-size: 0.8em; font-style: italic; margin-left: 10px; } .section-advanced .note code { font-style: normal; font-size: 11px; } .section-keybinds .field { font-family: monospace; } #fourchanx-settings fieldset { border: 1px solid; border-radius: 3px; } #fourchanx-settings legend { font-weight: 700; } #fourchanx-settings textarea { font-family: monospace; min-width: 100%; max-width: 100%; } #fourchanx-settings code { color: #000; background-color: #FFF; padding: 0 2px; } .unscroll { overflow: hidden; } /* Announcement Hiding */ :root.hide-announcement #globalMessage { display: none; } a.hide-announcement { float: left; } /* Unread */ #unread-line { margin: 0; border-color: rgb(255,0,0); } /* Thread Updater */ #updater { background: none; border: none; box-shadow: none; } #updater > .move { padding: 5px 3px 0px; margin-bottom: -3px; } #updater > div:last-child { text-align: center; } #updater input[type=number] { width: 4em; } :root.float #updater { padding: 0px 3px; } .new { color: limegreen; } #update-status.new { margin-right: 5px; } #update-timer { cursor: pointer; } /* Thread Watcher */ #thread-watcher { position: absolute; } #thread-watcher { padding-bottom: 3px; padding-left: 3px; overflow: hidden; white-space: nowrap; min-width: 136px; max-height: 92%; overflow-y: auto; } #thread-watcher .menu-button { bottom: 1px; } :root.fixed-watcher #thread-watcher { position: fixed; } :root:not(.fixed-watcher) #thread-watcher:not(:hover) { max-height: 210px; overflow-y: hidden; } #thread-watcher > .move { padding-top: 3px; } #watched-threads > div { max-width: 250px; overflow: hidden; padding-left: 3px; padding-right: 3px; text-overflow: ellipsis; } #thread-watcher a { text-decoration: none; } #thread-watcher .move>.close { position: absolute; right: 0px; top: 0px; padding: 0px 4px; } .watch-thread-link { padding-top: 18px; width: 18px; height: 0px; display: inline-block; background-repeat: no-repeat; opacity: 0.2; position: relative; top: 1px; } .watch-thread-link.watched { opacity: 1; } /* Thread Stats */ #thread-stats { background: none; border: none; box-shadow: none; } :root.float #post-count, :root.float #file-count { pointer-events: none; } :root.float #thread-stats { padding: 0px 3px; } /* Quote */ .deadlink { text-decoration: none !important; } .backlink.deadlink:not(.forwardlink), .quotelink.deadlink:not(.forwardlink) { text-decoration: underline !important; } .inlined { opacity: .5; } #qp input, .forwarded { display: none; } .quotelink.forwardlink, .backlink.forwardlink { text-decoration: none; border-bottom: 1px dashed; } .filtered { text-decoration: underline line-through; } :root.hide-backlinks .backlink.filtered { display: none; } .inline { border: 1px solid; display: table; margin: 2px 0; } .inline .post { border: 0 !important; background-color: transparent !important; display: table !important; margin: 0 !important; padding: 1px 2px !important; } #qp > .opContainer::after { content: ''; clear: both; display: table; } #qp .post { border: none; margin: 0; padding: 2px 2px 5px; } #qp img { max-height: 80vh; max-width: 50vw; } .qphl { outline: 2px solid rgba(216, 94, 49, .7); } :root.highlight-own .yourPost > .reply, :root.highlight-you .quotesYou > .reply { border-left: 2px solid rgba(221,0,0,.5); } /* Quote Threading */ .threadContainer { margin-left: 20px; border-left: 1px solid rgba(128,128,128,.3); } .threadOP { clear: both; } /* File */ .fileText:hover .fntrunc, .fileText:not(:hover) .fnfull, .expanded-image > .post > .file > .fileThumb > img[data-md5], :not(.expanded-image) > .post > .file > .fileThumb > .full-image { display: none; } .expanding { opacity: .5; } :root.fit-height .full-image { max-height: 100vh; } :root.fit-width .full-image { max-width: 100%; } :root.gecko.fit-width .full-image { width: 100%; } #ihover { -moz-box-sizing: border-box; box-sizing: border-box; max-height: 100%; max-width: 75%; padding-bottom: 16px; } .fappeTyme .thread > .noFile, .fappeTyme .threadContainer > .noFile { display: none; } /* Index/Reply Navigation */ #navlinks { font-size: 16px; top: 25px; right: 10px; } /* Filter */ .opContainer.filter-highlight { box-shadow: inset 5px 0 rgba(255, 0, 0, .5); } .filter-highlight > .reply { box-shadow: -5px 0 rgba(255, 0, 0, .5); } /* Spoiler text */ :root.reveal-spoilers s { color: white !important; } /* Thread & Reply Hiding */ .hide-thread-button, .hide-reply-button { float: left; margin-right: 2px; } .stub ~ * { display: none !important; } .stub input { display: inline-block; } /* QR */ :root.hide-original-post-form #postForm, :root.hide-original-post-form .postingMode, :root.hide-original-post-form #togglePostForm, #qr.autohide:not(.has-focus):not(:hover) > form, .postingMode ~ #qr select, #file-n-submit:not(.has-file) #qr-filerm { display: none; } #qr select, #dump-button, .remove, .captcha-img { cursor: pointer; } #qr { z-index: 20; position: fixed; padding: 1px; border: 1px solid transparent; min-width: 300px; border-radius: 3px 3px 0 0; } #qrtab { border-radius: 3px 3px 0 0; } #qrtab { margin-bottom: 1px; } #qr .close { float: right; padding: 0 3px; } #qr .warning { min-height: 1.6em; vertical-align: middle; padding: 0 1px; border-width: 1px; border-style: solid; } .qr-link-container { text-align: center; } .persona { width: 248px; max-width: 100%; min-width: 100%; } #dump-button { width: 10%; margin: 0; margin-right: 4px; font: 13px sans-serif; padding: 1px 0px 2px; opacity: 0.6; } .persona .field:not(#dump) { width: 95px; min-width: 33.3%; max-width: 33.3%; } #qr textarea.field { height: 14.8em; min-height: 9em; } #qr.has-captcha textarea.field { height: 9em; } input.field.tripped:not(:hover):not(:focus) { color: transparent !important; text-shadow: none !important; } #qr textarea { resize: both; } .captcha-img { margin: 0px; text-align: center; background-image: #fff; font-size: 0px; min-height: 59px; min-width: 302px; } .captcha-input { width: 100%; margin: 1px 0 0; } .captcha-input.error:focus { border-color: rgb(255,0,0) !important; } .field { -moz-box-sizing: border-box; margin: 0px; padding: 2px 4px 3px; } #qr textarea { min-width: 100%; } #qr [type='submit'] { width: 25%; vertical-align: top; } :root.webkit #qr [type='submit'] { height: 24px; } /* Fake File Input */ input#qr-filename { border: none !important; width: 80%; padding: 0px 4px; position: relative; bottom: 1px; background: none !important; } input#qr-filename:not(.edit) { pointer-events: none; } #qr-filename, #qr-filesize, .has-file #qr-no-file { display: none; } #qr-no-file, .has-file #qr-filename, .has-file #qr-filesize { display: inline-block; margin: 0 0 2px; overflow: hidden; text-overflow: ellipsis; vertical-align: top; } #qr-no-file { color: #AAA; padding: 1px 4px; } #qr-filename-container { -moz-box-sizing: border-box; display: inline-block; position: relative; width: 100px; min-width: 74.6%; max-width: 74.6%; margin-right: 0.4%; margin-top: 1px; overflow: hidden; padding: 2px 1px 0; height: 22px; } #qr-filename-container:hover { cursor: text; } #qr-extras-container { position: absolute; right: 0px; } #qr-filerm { margin-right: 2px; z-index: 2; } #file-n-submit { height: 23px; } #qr input[type=file] { visibility: hidden; position: absolute; } /* Thread Select / Spoiler Label */ #qr select { float: right; } #qr.has-spoiler .has-file #qr-spoiler-label { width: 6.7%; min-width: 6.7%; max-width: 6.7%; display: inline-block; text-align: center; vertical-align: top; } #qr.has-spoiler #file-n-submit:not(.has-file) #qr-spoiler-label { display: none; } #qr.has-spoiler .has-file #qr-filename-container { max-width: 67.9%; min-width: 67.9%; } #qr-spoiler-label input { position: relative; top: 3px; } /* Dumping UI */ .dump #dump-list-container { display: block; } #dump-list-container { display: none; position: relative; overflow-y: hidden; margin-top: 1px; } #dump-list { overflow-x: auto; overflow-y: hidden; white-space: nowrap; width: 248px; max-width: 100%; min-width: 100%; } #dump-list:hover { overflow-x: auto; } .qr-preview { -moz-box-sizing: border-box; counter-increment: thumbnails; cursor: move; display: inline-block; height: 90px; width: 90px; padding: 2px; opacity: .5; overflow: hidden; position: relative; text-shadow: 0 1px 1px #000; -moz-transition: opacity .25s ease-in-out; vertical-align: top; background-size: cover; } .qr-preview:hover, .qr-preview:focus { opacity: .9; } .qr-preview::before { content: counter(thumbnails); color: #fff; position: absolute; top: 3px; right: 3px; text-shadow: 0 0 3px #000, 0 0 8px #000; } .qr-preview#selected { opacity: 1; } .qr-preview.drag { box-shadow: 0 0 10px rgba(0,0,0,.5); } .qr-preview.over { border-color: #fff; } .qr-preview > span { color: #fff; } .remove { background: none; color: #e00; font-weight: 700; padding: 3px; } a:only-of-type > .remove { display: none; } .remove:hover::after { content: \" Remove\"; } .qr-preview > label { background: rgba(0,0,0,.5); color: #fff; right: 0; bottom: 0; left: 0; position: absolute; text-align: center; } .qr-preview > label > input { margin: 0; } #add-post { cursor: pointer; font-size: 2em; position: absolute; top: 50%; right: 10px; -moz-transform: translateY(-50%); } .textarea { position: relative; } :root.webkit .textarea { margin-bottom: -2px; } #char-count { color: #000; background: hsla(0, 0%, 100%, .5); font-size: 8pt; position: absolute; bottom: 1px; right: 1px; pointer-events: none; } /* Menu */ .menu-button { display: inline-block; position: relative; cursor: pointer; } .menu-button i { border-top: 6px solid; border-right: 4px solid transparent; border-left: 4px solid transparent; display: inline-block; margin: 2px; vertical-align: middle; } #menu { position: fixed; outline: none; } .entry { border-bottom: 1px solid rgba(0,0,0,.25); cursor: pointer; display: block; outline: none; padding: 3px 7px; position: relative; text-decoration: none; white-space: nowrap; } .left>.entry.has-submenu { padding-right: 17px !important; } .entry:last-child { border-bottom: 0; } .has-submenu::after { content: \"\"; border-left: .5em solid; border-top: .3em solid transparent; border-bottom: .3em solid transparent; display: inline-block; margin: .3em; position: absolute; right: 3px; } .left .has-submenu::after { border-left: 0; border-right: .5em solid; } .submenu { display: none; position: absolute; left: 100%; top: -1px; } .focused .submenu { display: block; } .imp-exp-result { position: absolute; text-align: center; margin: auto; right: 0px; left: 0px; width: 200px; } .export, .import { cursor: pointer; text-decoration: none !important; } /* Custom Board Titles */ .boardTitle[contenteditable=\"true\"], .boardSubtitle[contenteditable=\"true\"] { cursor: text !important; } /* Link Title Favicons */ .linkify.YouTube { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=') center left no-repeat!important; padding-left: 18px; } .linkify.Vimeo { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAASJJREFUOE9jYAAC7ln7/pODQXrBmq333PvPu/YaSRikB6QXbACpmmHqsRoAMll7+20UQ0H8tmuv/pdffPFfZtNNuByGASBFIPDh5x+4IV6HHoDFYGDJgw+YBoBMBUkgA5BtIKduuvvy//svX+FSB+88wTTAc+/t/83bj/0HScLA5BPXwc7lKJ36f+L6XXDxhUfOYxrAPWUnWKFp9UQUm3iWQxSDXAEDSX3zcIcB96wD/x+8eA1XDNKMHAYg20GW4Y0FkCIYAAUqzEBQOIBciRzlWKMxZelOlMCEcVxq+jHSC1YDJPs3YBgA8jey0/F6ARRwsFAHORukmat9NdbUijMpg/wKcrJodDFOzSBXwA3Alh9AToZFI7a8Asu98BxJbnYGAJb5vYLDANzSAAAAAElFTkSuQmCC') center left no-repeat!important; padding-left: 18px; } .linkify.SoundCloud { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII=') center left no-repeat!important; padding-left: 18px; } .linkify.audio { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAitJREFUOE9jYCAWKJWwavr0KyXWb/FIbDtUFFyzJx6nVofE2Xo5nXsj0rqPNSR0nVkR2Hjmgmfd+U9Otdf+m5Vf/6+SfeU/R9ChVVgNYDRtlfJuuPA/rPfe/4QpD/6nznj0P27Kw/9unff/69Xf+69c/+C/SO7N/0z+OAxgMmmRCe++/r9i3ev/KWvf/vdY8PK/bt/9/wrNV3/IN5y/IVt1YqNg4pGTTP4HsbuA2bhZ2qvpyn+xjIObxAp3VwqlrgngLFyryVy5nhPmZJHANS2cwYexG8BmVC/pWn3hP4NZlzWuQDJI3dIiFnUUuwEsQAOcq87jNcC7fHeLUtJxHF4AGmBWeAavAWH1+1rUUk7giAWjOknllON4DXAs2NEiG4/DBQxAF/CFHfrPYI4jDFSLuJVjNrUJhB/B7gIGo1pJRt99GAZYJK7wLJ1z7Xzl4vu/7aqv/GRBj0bjqAX2qb0nJ7mXH17C4HcUxQA+hymWtSue/C5a9up/9Ozn/7Vr7v1nRY7GqMb91T3b3v6vWvPmf/S0p/9ZQk+DDLCBRSOz06Jqk+o7/21nvfqvsebDf7kZL/5zBaxphkezd+OFn7HzXvz3Wvjmv9a8N//5Ek//ZTBpVYUrMG2X5wjcdl68+uI/wa5Lr3hSNjczGFeywOVZ/bbcVGp//F9izfv/Ql03f3P4LC/HSEQquYwMFnUCDJ7dzBhyjGZNQpye89M5gpfnMvtNUyE2h4PUAQBovvT7lyNljwAAAABJRU5ErkJggg==') center left no-repeat!important; padding-left: 18px; } .linkify.LiveLeak { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAydJREFUOE9Nk1tIk2EYx79NyUNqTk0o6KYrnZeChodLDxfeZpCbJk4RXU5Nm7tYRYhiYXbQlaeGutyW2gxtpB1RIyKDEjKwA6Ti2dR5KNDn+fq/S6TBj/f93r3P732e53s/qfnkSdej4GB2SBLbwf+jmB+gUMgOheLg/z7EdCUnO6Ref392SpK8Hyh3I+gBwBo7lUp2xcbyQEoKD6alyQOpqd754/h4FjJXZCRJTl9ftmEzoK5/wdQJxPgkLY2WV1dpc2uLtnZ2eHNnhza3t2nd46GhjAzuValY6jx0iIfS03msoIDuQ9COQCtoUSjohU5HuwgaN5loeXycd3d3aW9vzwvW2K5SkdTi58fvzGb+3tdHFggA3QONEAzn59PvjQ1yqNX0zenkvX0B4ffWaGRraChJd/385JGqKvlzTw/fRqOaIGkEd1DjU52O/3g83BkTw5MOh7yJuUCUM2o0yi2hoSw1IIOhykr+YLNRHYKu4XQvyKA/N5c8yMCCDD7Z7bz26xcJ1rH2rKKCG0UJdRAMlJbyG6uVrkJQjWAB5tSbk0Nr2HwDgvcQiIYur6zQyvo6ucvLueHIEZKuQPBQr+dXra1kRuqXEOwFArtWSytra1QdFUVjNhvPLS3R3OIiLUDUD0F1WBhJJtwDW2Ehu5uaqBICI4IFlRB0QLCEzaboaHrd0cHzCBYsIIuesjK+LAQXkEFrXh676uupGCWcR6AeghLQptGQONUAwfOuLp6Zn6eZuTmaXVig7pISrhI90ENgQbdHhoep32JhFzLpu3WLio8epUYIfs7OUjF6UKJW88XERLqYkEBNej11oG8XhCAvMFAuOn5cNiclsTkhQTbhmpri4lgbEMANWi1DwC/xit3t7bK7rY0Fo4OD3G4wyEURESzloAdnceezlErK8vH5N4KzPj50PTOTfkxP0+THj/RlYoInJyZI8HVqim5qNFwQHk7SucBAPo2PKRMNPLM/4pnFszYkhJsNBu6uqWFHba1sr61lQSveQFZQkFx07BhJmhMnrLn4NLMPH/aSExR0QDbmWhwgyEapwDvXoDxdWBiXnjrV/Bdm2kYUxLwmEgAAAABJRU5ErkJggg==') center left no-repeat!important; padding-left: 18px; } .linkify.Vocaroo { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAw9JREFUOE9jYMABuMwYmCyTJKUCGlSnFSy02TTzeOyCiQcDViX26qVz2TAyYtWmEMwuoZ3M7V40LcB79pHkc0svpvzY8jD//87nxf+3Pyn8v/ZO8v+VNyP/2mZJumI1QCWSI8232Hjumitlfw5+qPp/9l8TCt76JP//xkdx/wsXWCzjtWFkwTCkbWFe9plPk/+ga4Txz/xt/D/hkN//gMXif21a+NbyWjIwoRiy6GDT5rP/mlFsPfyp5n/NpOj/22+0gMUXXIz/H7hC/L/bFKFbPDZMrHAD5H35OPt2J9zacDv/f3V7xv9FhwrBGubsT/1//Pjx/1GJ/mD+/nfl/1v3Ovy3KRJNQbHdOlXCvOO03/+pm1P/v3v37n90hhtYw9HPtf8Xb2v937cmHswHeWPRxYj/LvkK3igGKARwicTO07118H3V/5kbi/4vPZMJtK3s/6YH2f+Pfq1B8VbjWrdnMu5s4nAD9CNFhKwz5DTUvLl419zKvAcLtG1P84BRl/b/5M/6/6f/NPzf/qzo84yj0Uus0xUU4Zor54bm9+4OfZG02OCuoAMTb9ZkC9ull1Nvrr2Z+XvRpaRfc65H/68F+jl9svEhzyLFWoccWVc+eyTHq/twydjlKRln7jX9bNMkMJnbhoFRL1xCqmKx6/yi2fYXa/c5/e846PV/5fW0/7OPx/yfcjzop34ulxdGGvDuU8mMXaX507lBuiN6ueadmQeT/p/93vf/1O+G//sP5fw/eL3o/5JLif8zVxs+Tlir9S26UyeFQQvJGBE7FvaFZ9LfN+1y+WjbItSb3GmXvXd15v8zroH/HxgE/D+aGPx/18vi/z07PeZNPRKxe/Kh0Ae8toxscCO4zBkYXArk9C1SxJUYjBkYPPIVtbbuTftz3cz//2O9wP/75iSAXdO72/dt2HL5F6YlfBW4MiJYXMiBiW3t7azHBx+V/t89N+H/8a+1//e9K/9attDp5LQjYX8SuvVL8RoAkmxa65299Erq1FnHo0qrl7t4BddriIs4MrM3rfWcFd+pGwVSAwBZ0bKP8yrZPAAAAABJRU5ErkJggg==') center left no-repeat!important; padding-left: 18px; } .linkify.pastebin { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAtZJREFUOE+NU91LWmEc7sJtQew/2MUY7INg7CLY3W5GMHazyzEQo9UmfYxZTbAiVlgRqLMSZ+XnDC3z2+Y0+8JGakKZTtR0Tl2wtgtLLQh29cz3ZZ3h3Q68vOc95zzP73l+z+/U1f292O09DRxubxOH23P//1bvtQts3dPnry7LZnXJhcUl5Avf8dHtwY+fv2AyW5DOfIXFakMm+w0G4wISyRRm55TQG0y/Wzv6mikJ52Xf9TmVBoFAAD6fDwqFAqFQCJubmzCbzZiensbp6SmkUikikQi0Wi0kEgm6ewVaStDCfXPDandifn6egoaGhrCzswO1Wg2Hw4HBwUGk02kIBAL4/X4IhUJMTk6ii8dfYggy2RwymQzOz88Rj8dRLpexv7+PSqWCYDCIQqGAra0tJBIJrK2t0XdVAjNDEIl+wfj4OEqlEq2wt7dHrchkMmrBYDCAz+fTIjweD7FYrJbgIJOlgLOzM8jlcip1eXmZ2rFarVAqlRCLxcjlchCJRFRljYJYPAG32418Pg+n04lsNouVlRUcHh7C4/FQIOlHNBqlezgcJgQWxkIgGMbExASVNjY2hvX1dVo9mUzS5wREFLhcLrqTcw2B//M2RkdHodPp4PV6oVKpqH+SCom3v7+fNnF4eJiJusbCJ6+PviSyScakiaR5RIHRaKQpmEwmbAdCeD8zB6vdhebHT8SMhcUlC83bbrdTJRsbG3RwiCVCRNJJpDIoVeNNJJJQzKryV+rrmxiCtyNCCmaz2VhdXQWXy6XDpNfrodFoYLXZUTw+pk222Z3lW3ca26rgSwzBwqIZAwMDlITMAVEwNTVFR5fEJpK8Qyp1AJvDVbrTeLenCmxgfiZ22+urCtWHyu7uLp2wVCpFKx0dHaFYLOLk5KT6Y9kgk89kb95ubK0BX7A8a+1qannRLeW0daj/rU51S3tn9dypfvDw0QiLxbpX/Z7FVK7e/AEj4Wf24/2f5AAAAABJRU5ErkJggg==') center left no-repeat!important; padding-left: 18px; } .linkify.gist { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAk1JREFUeNqUkzuIE1EUhv955MnsbB6r4kYQLUQQFncV3SnCIqJsoWGDYOGjsIiCtY2Kla1sjLBIsFFcXJC1kaSwENQmXUQSRSUSjCQSTCbkbR4z47lXEgtBNwcu3DNzvvO8R8jlcj7LshKmaWqYQERRTAmCcEru9/sJr9er0QF92BJMAVGr1TQ6CeZAc7lcGAwGkyQAxpTLZU0eDoc8crfbRTgcRjAYRCQSYSmi1WpxY7fbjU6ng1gshmaziXg8zhnGIpVKWbquW9ls1mLZsaMoiqWq6lgnBxY55He/328Vi0XOMFZmqVMD4fF4QBAajcY48khY9JE4HA4enTGMFVkaTHmy+ZzD/5NSqYSNB484w1h55ODO3TVu4FXcWDywl24Cmp0e1WBhyuWELAtIf/qKUrWOONmev3Lpt4NRCXq1gplpBS/v3cDc0nGg9h1o1ZkfwO4Atu1B8cM7HLt8k37V/y5B2b4bJxf2Y+7oEbyJrkMvUjki0YYJ03LidfQxAt4dOHdCw5RdGZcgGobBlQtnV/BDr1GfDai7ZiHZZRi9PoY/e5SCCTUwC9gk1GmMh5YWOcNYkR4Sv1y9uAJbYB82N57h4OnDmN7phjQ0qUkWRJuB+TMaPn/5iFfvv+Ha7eucYey4iWw8q6tRJJNJ3Fp7ClUawEkViBTfkCR0YUNTVHD/4Tpm/P4/U2CeKpUKfD4fJDIMhUKEhP45St50XedZyLQY6Xw+v8AUemVb2oNqtYpCocCWKi2TLLfb7ReZTGZ+kmUi7i2VvfxLgAEAZChMriPcl+IAAAAASUVORK5CYII=') center left no-repeat!important; padding-left: 18px; } .linkify.image { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAs5JREFUOE+lk/tvi1EYx98/xT8gW4REIpGFMEQWl2FiM9ZMZhm2xRAyOsmujFFmdFRHu0tWm87UypxStr69zPauN5e5rHVp3IYhbOvHy+wHEQlxkm+ek+d8nm9OznkeSfrfldmgJC7QyUlTymsJTfuTZ25z4HdWYwyLreYhtpgekGPw0+kKvo1Eo+IXRSIiEhkWZuc9tqnsJD9EqTUopCxjSGTpB0iueczSo1HyW8cpsExQ1DbxI2pt45j9cXpexul4FEd79RnZphAa/SD7WvuFtO6UItbU9LC+YQxNI2w0wwYT5LRAdhOU3oBTIXC9gXP3oUSGgz2vST3gYHejR0jptT1C332f8yrUEYHrz8CgxDnpm6DKCUfc0KnmXa/AEVPPwnDcD0cvetA2uYRk67Ive/lpjO7YBO1PPuF8Df3vwf4cbNE4tqdw7YVq8HYyHx6FvhE1hkMEg8HDUqvFkjT4aIjMqkqyqkswDSrcfBfH+Q561YLAZ/B+BLda6FXlU/cPv0AoEPhuoP1h4Av7Wbh9E/Py15NWWUjeSR3nZDfeN+N0DY9hG/7K1eGP3P0S5/EYRFUF/IOTBrUXHPm9fT6mr1xEwupkZqxbzLyiDJYUZ5NSnkdqdSHpxyrYdFpPgdmAsdfJwPMI/Yr65bf7tZLGGBQ7DNdJWFtIYvoOZmbuZE7OXpIKKli86zAr9p9gTVktWTVnKTI2U95uRWe3U2IJUDbVB5p6hVm5x5m9Vc/cnedZUNzC8lILaQesZBy6hEZ3maKzgvJWFzVWD9XtXvVGQbSWASFtMATVRlJIKbOTWtlJXaeXepuPM1f6MNp9GLt8mLvvYLmp0OhQ2Fwvk6m7xaqDTvY0eYWUVtcnllXfYlGpnfklVuraHHg8HjxuN+6fktUHlWWZPaZeUo/ILK0UKttBcbNbSB9GP0yLxWJJUxoZGUn80zD9C/vXQ/4NHY10h3M1zmQAAAAASUVORK5CYII=') center left no-repeat!important; padding-left: 18px; } .linkify.InstallGentoo { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAklJREFUOE9jYEAAASBTCorZkcSRmTjVCDLziCwG4hfM3EIvGNm44oC6WNEM4WXi5FsEkmfhFX3BxMmfAJSHW9Qr55Px3aZp3X/btq3/hQydPzKysMcCFbBBDeFj4uBdqBJR/gskb1W34j+PmulLoJwbzBJJoMm7dNO7/ntMP/XfpW/v//SKvk+7tl7fvXfTpx5pCdWVSiHFv1wnHQbLi9sE/Wdk5SwBauaCGQB3gUPb5v+7Lr/8/+fvr/9fv/z+f+Pyr/9bV735l9Wy/79Dx/b/Nk0bsLoAHgbeAVHv/v77/f8f0IB7N7+cu3DuecK54z9+7lzz639e9pK/7HwSWMMA5BJwCJeXtOm/fvVj1fcfv369f//92cN7X6ZcPvf9x6Htv//vXP3r/+T245UEYgpskPTNq08LgN749/PH7/93rv/6f/rw7//nj//4f+bU0zQcUQwWBkdVbGz62y+fv3wHeeXrlz//H9798//qpY//M3KqfzGxc8djiWKwZnBUuWQ2/fr46fv/P39+///x/ff/d69//z97+s7fyMb5/+y7d2GLYriDZikFF/1qXXXj/4Pbv/8/f/jn/5MH316/eP6jVlBAaIt6VO1/jxmn/zv27P7Pp2HxEajLD90ra9Sj6/979O37X73w0n+vqOL/0lJyMVBFq0EGgDSD0oKAlu1/oHg4ugGzVCKqfouYuL1Xj676Iajr8AnJFricGqYc3Bw+Zi6BVUxsXLHAdL6QiYMPFNrwpIxHDsUhgtAMAopKDjQn4pPDF7P45QC4hSmc1eX8WgAAAABJRU5ErkJggg==') center left no-repeat!important; padding-left: 18px; } /* Gallery */ #a-gallery { position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: 30; display: flex; flex-direction: row; background: rgba(0,0,0,0.7); } .gal-viewport { display: flex; align-items: stretch; flex-direction: row; flex: 1 1 auto; } .gal-thumbnails { flex: 0 0 150px; overflow-y: auto; display: flex; flex-direction: column; align-items: stretch; text-align: center; background: rgba(0,0,0,.5); } .hide-thumbnails .gal-thumbnails { display: none; } .gal-thumb img { max-width: 125px; max-height: 125px; height: auto; width: auto; } .gal-thumb { flex: 0 0 auto; padding: 3px; line-height: 0; transition: background .2s linear; } .gal-highlight { background: rgba(0, 190, 255,.8); } .gal-prev { order: 0; border-right: 1px solid #222; } .gal-next { order: 2; border-left: 1px solid #222; } .gal-prev, .gal-next { flex: 0 0 20px; position: relative; cursor: pointer; opacity: 0.7; background-color: rgba(0, 0, 0, 0.3); } .gal-prev:hover, .gal-next:hover { opacity: 1; } .gal-prev::after, .gal-next::after { position: absolute; top: 48.6%; transform: translateY(-50%) display: inline-block; border-top: 11px solid transparent; border-bottom: 11px solid transparent; content: \"\"; } .gal-prev::after { border-right: 12px solid #fff; right: 5px; } .gal-next::after { border-left: 12px solid #fff; right: 3px; } .gal-image { order: 1; flex: 1 0 auto; display: flex; align-items: flex-start; justify-content: space-around; overflow: auto; /* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */ width: 1%; } .gal-image a { margin: auto; line-height: 0; } .fit-width .gal-image img { max-width: 100%; } .fit-height .gal-image img { max-height: calc(100vh - 25px); } .gal-buttons { font-size: 2em; margin-right: 10px; top: 5px; color: #ffffff; text-shadow: 0px 0px 1px #000000; } .gal-buttons i { vertical-align: baseline; border-top-width: .5em; border-right-width: .3em; border-left-width: .3em; } .gal-buttons, .gal-name, .gal-count { position: fixed; right: 178px; } .hide-thumbnails .gal-buttons, .hide-thumbnails .gal-count, .hide-thumbnails .gal-name { right: 28px; } .gal-name { bottom: 5px; background: rgba(0,0,0,0.6) !important; border-radius: 3px; padding: 1px 5px 2px 5px; text-decoration: none !important; color: white !important; } .gal-name:hover, .gal-close:hover { color: rgb(95, 95, 101) !important; } .gal-count { bottom: 26px; background: rgba(0,0,0,0.6) !important; border-radius: 3px; padding: 1px 5px 2px 5px; color: #ffffff !important; }\n/* General */ :root.yotsuba .dialog { background-color: #F0E0D6; border-color: #D9BFB7; } :root.yotsuba .field:focus { border-color: #EA8; } /* Header */ :root.yotsuba #header-bar, :root.yotsuba #notifications { font-size: 9pt; color: #B86; } :root.yotsuba #header-bar a, :root.yotsuba #notifications a { color: #800000; } /* Settings */ :root.yotsuba #fourchanx-settings fieldset { border-color: #D9BFB7; } /* Quote */ :root.yotsuba .backlink.deadlink { color: #00E !important; } :root.yotsuba .inline { border-color: #D9BFB7; background-color: rgba(255, 255, 255, .14); } /* QR */ .yotsuba #dump-list::-webkit-scrollbar-thumb { background-color: #F0E0D6; border-color: #D9BFB7; } :root.yotsuba .qr-preview { background-color: rgba(0, 0, 0, .15); } /* Menu */ :root.yotsuba #menu { color: #800000; } :root.yotsuba .entry { border-bottom: 1px solid #D9BFB7; font-size: 10pt; } :root.yotsuba .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.yotsuba .watch-thread-link { background-image: url(\"data:image/svg+xml,\"); }\n/* General */ :root.yotsuba-b .dialog { background-color: #D6DAF0; border-color: #B7C5D9; } :root.yotsuba-b .field:focus { border-color: #98E; } /* Header */ :root.yotsuba-b #header-bar, :root.yotsuba-b #notifications { font-size: 9pt; color: #89A; } :root.yotsuba-b #header-bar a, :root.yotsuba-b #notifications a { color: #34345C; } /* Settings */ :root.yotsuba-b #fourchanx-settings fieldset { border-color: #B7C5D9; } /* Quote */ :root.yotsuba-b .backlink.deadlink { color: #34345C !important; } :root.yotsuba-b .inline { border-color: #B7C5D9; background-color: rgba(255, 255, 255, .14); } /* QR */ .yotsuba-b #dump-list::-webkit-scrollbar-thumb { background-color: #D6DAF0; border-color: #B7C5D9; } :root.yotsuba-b .qr-preview { background-color: rgba(0, 0, 0, .15); } /* Menu */ :root.yotsuba-b #menu { color: #000; } :root.yotsuba-b .entry { border-bottom: 1px solid #B7C5D9; font-size: 10pt; } :root.yotsuba-b .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.yotsuba-b .watch-thread-link { background-image: url(\"data:image/svg+xml,\"); }\n/* General */ :root.futaba .dialog { background-color: #F0E0D6; border-color: #D9BFB7; } :root.futaba .field:focus { border-color: #EA8; } /* Header */ :root.futaba #header-bar, :root.futaba #notifications { font-size: 11pt; color: #B86; } :root.futaba #header-bar a, :root.futaba #notifications a { color: #800000; } /* Settings */ :root.futaba #fourchanx-settings fieldset { border-color: #D9BFB7; } /* Quote */ :root.futaba .backlink.deadlink { color: #00E !important; } :root.futaba .inline { border-color: #D9BFB7; background-color: rgba(255, 255, 255, .14); } /* QR */ .futaba #dump-list::-webkit-scrollbar-thumb { background-color: #F0E0D6; border-color: #D9BFB7; } :root.futaba .qr-preview { background-color: rgba(0, 0, 0, .15); } /* Menu */ :root.futaba #menu { color: #800000; } :root.futaba .entry { border-bottom: 1px solid #D9BFB7; font-size: 12pt; } :root.futaba .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.futaba .watch-thread-link { background-image: url(\"data:image/svg+xml,\"); }\n/* General */ :root.burichan .dialog { background-color: #D6DAF0; border-color: #B7C5D9; } :root.burichan .field:focus { border-color: #98E; } /* Header */ :root.burichan #header-bar, :root.burichan #header-bar #notifications { font-size: 11pt; color: #89A; } :root.burichan #header-bar a, :root.burichan #header-bar #notifications a { color: #34345C; } /* Settings */ :root.burichan #fourchanx-settings fieldset { border-color: #B7C5D9; } /* Quote */ :root.burichan .backlink.deadlink { color: #34345C !important; } :root.burichan .inline { border-color: #B7C5D9; background-color: rgba(255, 255, 255, .14); } /* QR */ .burichan #dump-list::-webkit-scrollbar-thumb { background-color: #D6DAF0; border-color: #B7C5D9; } :root.burichan .qr-preview { background-color: rgba(0, 0, 0, .15); } /* Menu */ :root.burichan #menu { color: #000000; } :root.burichan .entry { border-bottom: 1px solid #B7C5D9; font-size: 12pt; } :root.burichan .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.burichan .watch-thread-link { background-image: url(\"data:image/svg+xml,\"); }\n/* General */ :root.tomorrow .dialog { background-color: #282A2E; border-color: #111; } /* Header */ :root.tomorrow #header-bar, :root.tomorrow #notifications { font-size: 9pt; color: #C5C8C6; } :root.tomorrow #header-bar a, :root.tomorrow #notifications a { color: #81A2BE; } /* Settings */ :root.tomorrow #fourchanx-settings fieldset { border-color: #111; } /* Quote */ :root.tomorrow .backlink.deadlink { color: #81A2BE !important; } :root.tomorrow .inline { border-color: #111; background-color: rgba(0, 0, 0, .14); } /* QR */ .tomorrow #dump-list::-webkit-scrollbar-thumb { background-color: #282A2E; border-color: #111; } :root.tomorrow .qr-preview { background-color: rgba(255, 255, 255, .15); } :root.tomorrow #qr .field { background-color: rgb(26, 27, 29); color: rgb(197,200,198); border-color: rgb(40, 41, 42); } :root.tomorrow #qr .field:focus { border-color: rgb(129, 162, 190) !important; background-color: rgb(30,32,36); } /* Menu */ :root.tomorrow #menu { color: #C5C8C6; } :root.tomorrow .entry { border-bottom: 1px solid #111; font-size: 10pt; } :root.tomorrow .focused.entry { background: rgba(0, 0, 0, .33); } /* Watcher Favicon */ :root.tomorrow .watch-thread-link { background-image: url(\"data:image/svg+xml,\"); }\n/* General */ :root.photon .dialog { background-color: #DDD; border-color: #CCC; } :root.photon .field:focus { border-color: #EA8; } /* Header */ :root.photon #header-bar, :root.photon #notifications { font-size: 9pt; color: #333; } :root.photon #header-bar a, :root.photon #notifications a { color: #FF6600; } /* Settings */ :root.photon #fourchanx-settings fieldset { border-color: #CCC; } /* Quote */ :root.photon .backlink.deadlink { color: #F60 !important; } :root.photon .inline { border-color: #CCC; background-color: rgba(255, 255, 255, .14); } /* QR */ .photon #dump-list::-webkit-scrollbar-thumb { background-color: #DDD; border-color: #CCC; } :root.photon .qr-preview { background-color: rgba(0, 0, 0, .15); } /* Menu */ :root.photon #menu { color: #333; } :root.photon .entry { border-bottom: 1px solid #CCC; font-size: 10pt; } :root.photon .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.photon .watch-thread-link { background-image: url(\"data:image/svg+xml,\"); }" - }; - - Main.init(); - -}).call(this); diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index ddbe5d8e7..5a0ea1594 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -8937,7 +8937,7 @@ $.add(d.body, dialog); nodes.thumbs.scrollTop = 0; nodes.current.parentElement.scrollTop = 0; - Gallery.cb.open.call(image ? $("[href='" + (image.href.replace(/https?:/, '')) + "']", Gallery.thumbs) : Gallery.images[0]); + Gallery.cb.open.call(image ? $("[href='" + (image.href.replace(/https?:/, '')) + "']", nodes.thumbs) : Gallery.images[0]); d.body.style.overflow = 'hidden'; return nodes.total.textContent = --i; },