// Generated by CoffeeScript // ==UserScript== // @name 4chan X // @version 1.11.17.9 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X // @description Cross-browser userscript for maximum lurking on 4chan. // @license MIT; https://github.com/ccd0/4chan-x/blob/master/LICENSE // @include http://boards.4chan.org/* // @include https://boards.4chan.org/* // @include http://sys.4chan.org/* // @include https://sys.4chan.org/* // @include http://i.4cdn.org/* // @include https://i.4cdn.org/* // @include http://www.4chan.org/banned // @include https://www.4chan.org/banned // @include http://www.4chan.org/feedback // @include https://www.4chan.org/feedback // @include https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc* // @include https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc* // @include http://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc* // @include https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_addValueChangeListener // @grant GM_openInTab // @grant GM_xmlhttpRequest // @run-at document-start // @updateURL https://noupdate.invalid/ // @downloadURL https://noupdate.invalid/ // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII= // ==/UserScript== /* * 4chan X * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE * * Appchan X Copyright © 2013-2015 Zixaphir * http://zixaphir.github.io/appchan-x/ * 4chan x Copyright © 2009-2011 James Campos * https://github.com/aeosynth/4chan-x * 4chan x Copyright © 2012-2014 Nicolas Stepien * https://4chan-x.just-believe.in/ * 4chan x Copyright © 2013-2014 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 * * Font Awesome by Dave Gandy (http://fontawesome.io) * license: http://fontawesome.io/license/ */ 'use strict'; (function() { var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadLinks, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g, slice = [].slice, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, extend = 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; }, hasProp = {}.hasOwnProperty, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Config = { main: { 'Miscellaneous': { 'JSON Navigation': [true, 'Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode.'], 'Use 4chan X Catalog': [true, 'Link to 4chan X\'s catalog instead of the native 4chan one.', 1], 'Index Refresh Notifications': [false, 'Show a notice at the top of the page when the index is refreshed.', 1], 'Open Threads in New Tab': [false, 'Make links to threads in the index / 4chan X catalog open in a new tab.'], 'External Catalog': [false, 'Link to external catalog instead of the internal one.'], 'Catalog Links': [false, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'], 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'], 'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'], '404 Redirect': [true, 'Redirect dead threads and images to the archives.'], 'Archive Report': [true, 'Enable reporting posts to supported archives.'], 'Exempt Archives from Encryption': [false, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'], '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.'], 'Relative Date Title': [true, 'Show Relative Post Date only when hovering over dates.', 1], 'Comment Expansion': [true, 'Expand comments that are too long to display on the index. Not applicable with JSON Navigation.'], 'File Info Formatting': [true, 'Reformat the file information.'], '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.'], 'Custom Board Titles': [true, 'Allow editing of the board title and subtitle by ctrl/\u2318+clicking them.'], 'Persistent Custom Board Titles': [false, 'Force custom board titles to be persistent, even if the board titles are updated.', 1], 'Show Updated Notifications': [true, 'Show notifications when 4chan X is successfully updated.'], 'Color User IDs': [true, '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.'], 'Show Support Message': [true, 'Warn if your browser or configuration is unsupported and may cause 4chan X to not operate correctly.'], 'Normalize URL': [true, 'Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/.'], 'Disable Autoplaying Sounds': [false, 'Prevent sounds on the page from autoplaying.'], 'Disable Native Extension': [true, '4chan X is NOT designed to work with the native extension.'], 'Enable Native Flash Embedding': [true, 'Activate the native extension\'s Flash embedding if the native extension is disabled.'] }, 'Linkification': { 'Linkify': [true, 'Convert text into links where applicable.'], 'Link Title': [true, 'Replace the link of a supported site with its actual title. Currently supported: YouTube, Vimeo, SoundCloud, and Github gists.', 1], 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] }, 'Filtering': { 'Anonymize': [false, 'Make everyone Anonymous.'], 'Filter': [true, 'Self-moderation placebo.'], 'Filtered Backlinks': [false, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.', 1], 'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'], 'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'], 'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'], 'Stubs': [true, 'Show stubs of hidden threads / replies.'] }, 'Images and Videos': { 'Image Expansion': [true, 'Expand images / videos.'], 'Image Hover': [true, 'Show full image / video on mouseover.'], 'Image Hover in Catalog': [false, 'Show full image / video on mouseover in 4chan X catalog.'], 'Gallery': [true, 'Adds a simple and cute image gallery.'], 'Fullscreen Gallery': [false, 'Open gallery in fullscreen mode.', 1], 'PDF in Gallery': [false, 'Show PDF files in gallery.', 1], 'Oekaki Links': [true, 'Add links to edit images in Tegaki, /i/\'s painting program.'], 'Sauce': [true, 'Add sauce links to images.'], 'WEBM Metadata': [true, 'Add link to fetch title metadata from webm videos.'], 'Reveal Spoiler Thumbnails': [false, 'Replace spoiler thumbnails with the original image.'], 'Replace GIF': [false, 'Replace gif thumbnails with the actual image.'], 'Replace JPG': [false, 'Replace jpg thumbnails with the actual image.'], 'Replace PNG': [false, 'Replace png thumbnails with the actual image.'], 'Replace WEBM': [false, 'Replace webm thumbnails with the actual webm video. Probably will degrade browser performance ;)'], 'Image Prefetching': [false, 'Add link in header menu to turn on image preloading.'], 'Fappe Tyme': [true, 'Hide posts without images when header menu item is checked. *hint* *hint*'], 'Werk Tyme': [true, 'Hide all post images when header menu item is checked.'], 'Autoplay': [true, 'Videos begin playing immediately when opened.'], 'Restart when Opened': [true, 'Restart GIFs and WebMs when you hover over or expand them.'], 'Show Controls': [true, 'Show controls on videos expanded inline.'], 'Click Passthrough': [false, 'Clicks on videos trigger your browser\'s default behavior. Videos can be contracted with button / dragging to the left.', 1], 'Allow Sound': [true, 'Open videos with the sound unmuted.'], 'Mouse Wheel Volume': [true, 'Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery.'], 'Loop in New Tab': [true, 'Loop videos opened in their own tabs.'], 'Volume in New Tab': [true, 'Apply 4chan X mute and volume settings to videos opened in their own tabs.'] }, 'Menu': { 'Menu': [true, 'Add a drop-down menu to posts.'], 'Report Link': [true, 'Add a report link to the menu.', 1], 'Thread Hiding Link': [true, 'Add a link to hide entire threads.', 1], 'Reply Hiding Link': [true, 'Add a link to hide single replies.', 1], 'Delete Link': [true, 'Add post and image deletion links to the menu.', 1], 'Download Link': [true, 'Add a download with original filename link to the menu.', 1], 'Archive Link': [true, 'Add an archive link to the menu.', 1] }, 'Monitoring': { 'Thread Updater': [true, 'Fetch and insert new replies. Has more options in the header menu and the "Advanced" tab.'], 'Unread Count': [true, 'Show the unread posts count in the tab title.'], 'Quoted Title': [false, 'Change the page title to reflect you\'ve been quoted.', 1], 'Hide Unread Count at (0)': [false, 'Hide the unread posts count in the tab title when it reaches 0.', 1], '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 for threads in /f/.'], 'Remove Thread Excerpt': [false, 'Replace the excerpt of the thread in the tab title with the board title.'], 'Thread Stats': [true, 'Display reply and image count.'], 'IP Count in Stats': [true, 'Display the unique IP count in the thread stats.', 1], 'Page Count in Stats': [true, 'Display the page count in the thread stats.', 1], '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.'], 'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1], 'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher and hides the watcher by default.', 1], 'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'] }, 'Posting and Captchas': { 'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'], 'QR Shortcut': [true, 'Add a shortcut to the header to toggle the QR.', 1], 'Persistent QR': [false, 'The Quick reply won\'t disappear after posting.', 1], 'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.', 1], 'Open Post in New Tab': [true, 'Open new threads or replies to a thread from the index in a new tab.', 1], 'Remember QR Size': [false, 'Remember the size of the Quick reply.', 1], 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting.', 1], 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], 'Show New Thread Option in Threads': [false, 'Show the option to post a new / different thread from inside a thread.', 1], 'Show Name and Subject': [false, 'Show the classic name, email, and subject fields in the QR, even when 4chan doesn\'t use them all.', 1], 'Hide Original Post Form': [true, 'Hide the normal post form.', 1], 'Cooldown': [true, 'Indicate the remaining time before posting again.', 1], 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1], 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled (Recaptcha v2 only).', 1], 'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1], 'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1], 'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1], 'Captcha Fixes': [true, 'Make captcha easier to use, especially with the keyboard.'], 'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.'], 'Use Recaptcha v2 in Reports': [false, 'Use the image selection captcha in the report window.'], 'Pass Link': [true, 'Add a 4chan Pass login link to the bottom of the page.'] }, 'Quote Links': { 'Quote Backlinks': [true, 'Add quote backlinks.'], 'OP Backlinks': [true, 'Add backlinks to the OP.', 1], 'Quote Inlining': [true, 'Inline quoted post on click.'], 'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1], 'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1], 'Quote Previewing': [true, 'Show quoted post on hover.'], 'Quote Highlighting': [true, 'Highlight the previewed post.', 1], 'Resurrect Quotes': [true, 'Link dead quotes to the archives.'], 'Mark Quotes of You': [true, 'Add \'(You)\' to quotes linking to your posts.'], 'Highlight Posts Quoting You': [true, 'Highlights any posts that contain a quote to your post.', 1], 'Highlight Own Posts': [true, 'Highlights own posts if Mark Quotes of You is enabled.', 1], 'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'], 'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'], 'Quote Threading': [false, 'Thread conversations'] } }, imageExpansion: { 'Fit width': [true, ''], 'Fit height': [false, ''], 'Scroll into view': [true, 'Scroll down when expanding images to bring the full image into view.'], 'Expand spoilers': [true, 'Expand all images along with spoilers.'], 'Expand videos': [true, 'Expand all images also expands videos.'], '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], 'Fit Width': [true], 'Fit Height': [true], 'Stretch to Fit': [false], 'Scroll to Post': [true], 'Slide Delay': [6.0] }, 'Default Volume': 1.0, threadWatcher: { 'Current Board': [false, 'Only show watched threads from the current board.'], 'Auto Update Thread Watcher': [true, 'Periodically check status of watched threads.'], 'Auto Watch': [false, 'Automatically watch threads you start.'], 'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'], 'Auto Prune': [false, 'Automatically remove dead threads.'], 'Show Unread Count': [true, 'Show number of unread posts in watched threads.'] }, filter: { postID: "# Highlight dubs on [s4s]:\n#/(\\d)\\1$/;highlight;top:no;boards:s4s", 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 admins:\n#/Admin$/;highlight:admin;op:yes", 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\n# Filter posts with 20 or more quote links:\n#/(?:>>\\d(?:(?!>>\\d)[^])*){20}/\n# Filter posts like T H I S / H / I / S:\n#/^>?\\s?\\w\\s?(\\w)\\s?(\\w)\\s?(\\w).*$[\\s>]+\\1[\\s>]+\\2[\\s>]+\\3/im", 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=%IMG\n//iqdb.org/?url=%IMG\nhttp://eye.swfchan.com/search/?q=%name;types:swf;sandbox\n#//tineye.com/search?url=%IMG\n#https://www.yandex.com/images/search?rpt=imageview&img_url=%IMG\n#//saucenao.com/search.php?url=%IMG\n#http://3d.iqdb.org/?url=%IMG\n# tools:\n#http://regex.info/exif.cgi?imgurl=%URL\n#//imgops.com/%URL;types:gif,jpg,png\n# uploaders:\n#//imgur.com/upload?url=%URL;types:gif,jpg,png,pdf;text:Upload to imgur\n# \"View Same\" in archives:\n#https://archive.4plebs.org/_/search/image/%MD5/;text:View same on 4plebs\n#https://archive.4plebs.org/%board/search/image/%MD5/;text:View same on 4plebs /%board/;boards:adv,f,hr,o,pol,s4s,sp,tg,trv,tv,x\n#https://rbt.asia/%board/?task=search2&search_media_hash=%MD5;text:View same on RBT /%board/;boards:cgl,g,mu,qa,w", FappeT: { werk: false }, 'Custom CSS': true, Index: { 'Index Mode': 'paged', 'Previous Index Mode': 'paged', 'Index Sort': 'bump', 'Index Size': 'small', 'Show Replies': true, 'Pin Watched Threads': false, 'Anchor Hidden Threads': true, 'Refreshed Navigation': false }, Header: { 'Fixed Header': true, 'Header auto-hide': false, 'Header auto-hide on scroll': false, 'Bottom Header': false, 'Centered links': false, 'Header catalog links': false, 'Bottom Board List': true, 'Shortcut Icons': true, '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\n[external-text:\"FAQ\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]", QR: { 'QR.personas': "#options:\"sage\";boards:jp;always", sjisPreview: false }, captchaLanguage: '', time: '%m/%d/%y(%a)%H:%M:%S', backlink: '>>%id', fileInfo: '%l (%p%s, %r%g)', favicon: 'ferongr', usercss: "/* Board title rice */\n" + "div.boardTitle {\n" + " font-weight: 400 !important;\n" + "}\n" + ":root.yotsuba div.boardTitle {\n" + " font-family: sans-serif !important;\n" + " text-shadow: 1px 1px 1px rgba(100,0,0,0.6);\n" + "}\n" + ":root.yotsuba-b div.boardTitle {\n" + " font-family: sans-serif !important;\n" + " text-shadow: 1px 1px 1px rgba(105,10,15,0.6);\n" + "}\n" + ":root.photon div.boardTitle {\n" + " font-family: sans-serif !important;\n" + " text-shadow: 1px 1px 1px rgba(0,74,153,0.6);\n" + "}\n" + ":root.tomorrow div.boardTitle {\n" + " font-family: sans-serif !important;\n" + " text-shadow: 1px 1px 1px rgba(167,170,168,0.6);\n" + "}", 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': ['q', 'Open QR without post number inserted.'], 'Open QR': ['Shift+q', 'Open QR with post number inserted.'], 'Open settings': ['Alt+o', 'Open Settings.'], 'Close': ['Esc', 'Close dialogs or notifications.'], '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.'], 'SJIS tags': ['Alt+a', 'Insert SJIS tags.'], 'Toggle sage': ['Alt+s', 'Toggle sage in options field.'], 'Submit QR': ['Ctrl+Enter', 'Submit post.'], 'Watch': ['w', 'Watch thread.'], 'Update': ['r', 'Update the thread / refresh the index.'], 'Expand image': ['Shift+e', 'Expand selected image.'], 'Expand images': ['e', 'Expand all images.'], 'Open Gallery': ['g', 'Opens the gallery.'], 'Pause': ['p', 'Pause/play videos in the gallery.'], 'Slideshow': ['Ctrl+Right', 'Toggle the gallery slideshow mode.'], 'fappeTyme': ['f', 'Toggle Fappe Tyme.'], 'werkTyme': ['Shift+w', 'Toggle Werk Tyme.'], 'Front page': ['1', 'Jump to front page.'], 'Open front page': ['Shift+1', 'Open front page in a new tab.'], 'Next page': ['Ctrl+Right', 'Jump to the next page.'], 'Previous page': ['Ctrl+Left', 'Jump to the previous page.'], 'Paged mode': ['Alt+1', 'Open the index in paged mode.'], 'Infinite scrolling mode': ['Alt+2', 'Open the index in infinite scrolling mode.'], 'All pages mode': ['Alt+3', 'Open the index in all threads mode.'], 'Open catalog': ['Shift+c', 'Open the catalog of the current board.'], 'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'], 'Cycle sort type': ['Alt+x', 'Cycle through index sort types.'], 'Next thread': ['Ctrl+Down', 'See next thread.'], 'Previous thread': ['Ctrl+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 }, customCooldown: 0, customCooldownEnabled: true }; Conf = {}; c = console; d = document; doc = d.documentElement; g = { VERSION: '1.11.17.9', NAMESPACE: '4chan X.', boards: {} }; E = (function() { var fn, r, regex, str; str = { '&': '&', "'": ''', '"': '"', '<': '<', '>': '>' }; r = String.prototype.replace; regex = /[&"'<>]/g; fn = function(x) { return str[x]; }; return function(text) { return r.call(text, regex, fn); }; })(); E.cat = function(templates) { var html, k, len1, x; html = ''; for (k = 0, len1 = templates.length; k < len1; k++) { x = templates[k]; html += x.innerHTML; } return html; }; E.url = function(content) { return "data:text/html;charset=utf-8," + (encodeURIComponent(content.innerHTML)); }; $ = function(selector, root) { if (root == null) { root = d.body; } return root.querySelector(selector); }; $.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 blockedError, blockedURLs, lastModified; lastModified = {}; blockedURLs = {}; blockedError = function(url) { var message; if (blockedURLs[url]) { return; } blockedURLs[url] = true; message = $.el('div', { innerHTML: "4chan X was blocked from loading the following URL:

[More info]" }); $('span', message).textContent = (/^\/\//.test(url) ? location.protocol : '') + url; return new Notice('error', message, 30, function() { return delete blockedURLs[url]; }); }; return function(url, options, extra) { var err, form, r, ref, type, upCallbacks, whenModified; if (options == null) { options = {}; } if (extra == null) { extra = {}; } type = extra.type, whenModified = extra.whenModified, upCallbacks = extra.upCallbacks, form = extra.form; r = new XMLHttpRequest(); type || (type = form && 'post' || 'get'); try { r.open(type, url, true); } catch (_error) { err = _error; blockedError(url); if (typeof options.onerror === "function") { options.onerror(); } return; } if (whenModified) { if (((ref = lastModified[whenModified]) != null ? ref[url] : void 0) != null) { r.setRequestHeader('If-Modified-Since', lastModified[whenModified][url]); } $.on(r, 'load', function() { return (lastModified[whenModified] || (lastModified[whenModified] = {}))[url] = r.getResponseHeader('Last-Modified'); }); } if (/\.json$/.test(url)) { if (options.responseType == null) { options.responseType = 'json'; } } $.extend(r, options); if (options.responseType === 'json' && r.responseType !== 'json' && delete r.response) { Object.defineProperty(r, 'response', { configurable: true, enumerable: true, get: function() { return JSON.parse(r.responseText); } }); } $.extend(r.upload, upCallbacks); r.send(form); return r; }; })(); (function() { var reqs; reqs = {}; $.cache = function(url, cb, options) { var err, req, rm; if (req = reqs[url]) { if (req.readyState === 4) { $.queueTask(function() { return cb.call(req, req.evt); }); } else { req.callbacks.push(cb); } return req; } rm = function() { return delete reqs[url]; }; try { if (!(req = $.ajax(url, options))) { return; } } catch (_error) { err = _error; return; } $.on(req, 'load', function(e) { var k, len1, ref; ref = this.callbacks; for (k = 0, len1 = ref.length; k < len1; k++) { cb = ref[k]; cb.call(this, e); } this.evt = e; this.cached = true; return delete this.callbacks; }); $.on(req, 'abort error', rm); req.callbacks = [cb]; return reqs[url] = req; }; return $.cleanCache = function(testf) { var url; for (url in reqs) { if (testf(url)) { delete reqs[url]; } } }; })(); $.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); } }; $.onExists = function(root, selector, subtree, cb) { var el, observer; if (el = $(selector, root)) { return cb(el); } if ($.engine === 'edge' && d.readyState === 'loading') { $.asap((function() { return d.readyState !== 'loading' || $(selector, root); }), function() { return $.onExists(root, selector, subtree, cb); }); return; } observer = new MutationObserver(function() { if (el = $(selector, root)) { observer.disconnect(); return cb(el); } }); return observer.observe(root, { childList: true, subtree: subtree }); }; $.addStyle = function(css, id, test) { var style; style = $.el('style', { textContent: css }); if (id != null) { style.id = id; } $.asap((function() { return d.head && ((test == null) || test()); }), 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() { var className, classNames, el, k, len1; el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; for (k = 0, len1 = classNames.length; k < len1; k++) { className = classNames[k]; el.classList.add(className); } }; $.rmClass = function() { var className, classNames, el, k, len1; el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; for (k = 0, len1 = classNames.length; k < len1; k++) { className = classNames[k]; el.classList.remove(className); } }; $.toggleClass = function(el, className) { return el.classList.toggle(className); }; $.hasClass = function(el, className) { return indexOf.call(el.classList, className) >= 0; }; $.rm = function(el) { return el != null ? el.remove() : void 0; }; $.rmAll = function(root) { return root.textContent = null; }; $.tn = function(s) { return d.createTextNode(s); }; $.frag = function() { return d.createDocumentFragment(); }; $.nodes = function(nodes) { var frag, k, len1, node; if (!(nodes instanceof Array)) { return nodes; } frag = $.frag(); for (k = 0, len1 = nodes.length; k < len1; k++) { node = nodes[k]; 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, k, len1, ref; ref = events.split(' '); for (k = 0, len1 = ref.length; k < len1; k++) { event = ref[k]; el.addEventListener(event, handler, false); } }; $.off = function(el, events, handler) { var event, k, len1, ref; ref = events.split(' '); for (k = 0, len1 = ref.length; k < len1; k++) { event = ref[k]; el.removeEventListener(event, handler, false); } }; $.one = function(el, events, handler) { var cb; cb = function(e) { $.off(el, events, cb); return handler.call(this, e); }; return $.on(el, events, cb); }; $.event = function(event, detail, root) { if (root == null) { root = d; } if ((detail != null) && typeof cloneInto === 'function') { detail = cloneInto(detail, d.defaultView); } return root.dispatchEvent(new CustomEvent(event, { bubbles: true, detail: detail })); }; (function() { var clone, err, ref, unsafeConstructors; if (!(/PaleMoon\//.test(navigator.userAgent) && +(typeof GM_info !== "undefined" && GM_info !== null ? (ref = GM_info.version) != null ? ref.split('.')[0] : void 0 : void 0) >= 2 && typeof cloneInto === 'undefined')) { return; } try { return new CustomEvent('x', { detail: {} }); } catch (_error) { err = _error; unsafeConstructors = { Object: unsafeWindow.Object, Array: unsafeWindow.Array }; clone = function(obj) { var constructor, key, obj2, val; if ((obj != null) && typeof obj === 'object' && (constructor = unsafeConstructors[obj.constructor.name])) { obj2 = new constructor(); for (key in obj) { val = obj[key]; obj2[key] = clone(val); } return obj2; } else { return obj; } }; return $.event = function(event, detail, root) { if (root == null) { root = d; } return root.dispatchEvent(new CustomEvent(event, { bubbles: true, detail: clone(detail) })); }; } })(); $.open = typeof GM_openInTab !== "undefined" && GM_openInTab !== null ? GM_openInTab : function(url) { return window.open(url, '_blank'); }; $.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); }; $.global = function(fn) { return $.globalEval("(" + fn + ")();"); }; $.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); }; $.hasAudio = function(video) { return video.mozHasAudio || !!video.webkitAudioDecodedByteCount; }; $.engine = (function() { if (/Edge\//.test(navigator.userAgent)) { return 'edge'; } if (/Chrome\//.test(navigator.userAgent)) { return 'blink'; } if (/WebKit\//.test(navigator.userAgent)) { return 'webkit'; } if (/Gecko\/|Goanna/.test(navigator.userAgent)) { return 'gecko'; } })(); try { localStorage.getItem('x'); $.hasStorage = true; } catch (_error) { $.hasStorage = false; } $.item = function(key, val) { var item; item = {}; item[key] = val; return item; }; $.syncing = {}; if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { $.getValue = GM_getValue; $.listValues = function() { return GM_listValues(); }; } else if ($.hasStorage) { $.getValue = function(key) { return localStorage[key]; }; $.listValues = function() { var key, results; results = []; for (key in localStorage) { if (key.slice(0, g.NAMESPACE.length) === g.NAMESPACE) { results.push(key); } } return results; }; } else { $.getValue = function() {}; $.listValues = function() { return []; }; } if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { $.setValue = GM_setValue; $.deleteValue = GM_deleteValue; } else if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { $.oldValue = {}; $.setValue = function(key, val) { GM_setValue(key, val); if (key in $.syncing) { $.oldValue[key] = val; if ($.hasStorage) { return localStorage[key] = val; } } }; $.deleteValue = function(key) { GM_deleteValue(key); if (key in $.syncing) { delete $.oldValue[key]; if ($.hasStorage) { return delete localStorage[key]; } } }; if (!$.hasStorage) { $.cantSync = true; } } else if ($.hasStorage) { $.oldValue = {}; $.setValue = function(key, val) { if (key in $.syncing) { $.oldValue[key] = val; } return localStorage[key] = val; }; $.deleteValue = function(key) { if (key in $.syncing) { delete $.oldValue[key]; } return delete localStorage[key]; }; } else { $.setValue = function() {}; $.deleteValue = function() {}; $.cantSync = $.cantSet = true; } if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { $.sync = function(key, cb) { return $.syncing[key] = GM_addValueChangeListener(g.NAMESPACE + key, function(key2, oldValue, newValue, remote) { if (remote) { if (newValue !== void 0) { newValue = JSON.parse(newValue); } return cb(newValue, key); } }); }; $.forceSync = function() {}; } else if ($.hasStorage) { $.sync = function(key, cb) { key = g.NAMESPACE + key; $.syncing[key] = cb; return $.oldValue[key] = $.getValue(key); }; (function() { var onChange; onChange = function(key) { var cb, newValue; if (!(cb = $.syncing[key])) { return; } newValue = $.getValue(key); if (newValue === $.oldValue[key]) { return; } if (newValue != null) { $.oldValue[key] = newValue; return cb(JSON.parse(newValue), key.slice(g.NAMESPACE.length)); } else { delete $.oldValue[key]; return cb(void 0, key.slice(g.NAMESPACE.length)); } }; $.on(window, 'storage', function(arg) { var key; key = arg.key; return onChange(key); }); return $.forceSync = function(key) { return onChange(g.NAMESPACE + key); }; })(); } else { $.sync = function() {}; $.forceSync = function() {}; } $["delete"] = function(keys) { var k, key, len1; if (!(keys instanceof Array)) { keys = [keys]; } for (k = 0, len1 = keys.length; k < len1; k++) { key = keys[k]; $.deleteValue(g.NAMESPACE + 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 = $.getValue(g.NAMESPACE + key)) { items[key] = JSON.parse(val); } } return cb(items); }); }; $.set = function(keys, val, cb) { var key, value; if (typeof keys === 'string') { $.setValue(g.NAMESPACE + keys, JSON.stringify(val)); } else { for (key in keys) { value = keys[key]; $.setValue(g.NAMESPACE + key, JSON.stringify(value)); } cb = val; } return typeof cb === "function" ? cb() : void 0; }; $.clear = function(cb) { var id; $["delete"](Object.keys(Conf)); $["delete"](['previousversion', 'AutoWatch', 'QR Size', 'captchas', 'QR.persona', 'hiddenPSA']); $["delete"]((function() { var k, len1, ref, results; ref = ['embedding', 'updater', 'thread-stats', 'thread-watcher', 'qr']; results = []; for (k = 0, len1 = ref.length; k < len1; k++) { id = ref[k]; results.push(id + ".position"); } return results; })()); try { $["delete"]($.listValues().map(function(key) { return key.replace(g.NAMESPACE, ''); })); } catch (_error) {} return typeof cb === "function" ? cb() : void 0; }; $$ = function(selector, root) { if (root == null) { root = d.body; } return slice.call(root.querySelectorAll(selector)); }; Callbacks = (function() { function Callbacks(type1) { this.type = type1; this.keys = []; } Callbacks.prototype.push = function(arg) { var cb, name; name = arg.name, cb = arg.cb; if (!this[name]) { this.keys.push(name); } return this[name] = cb; }; Callbacks.prototype.execute = function(node, keys) { var err, errors, k, len1, name, ref; if (keys == null) { keys = this.keys; } for (k = 0, len1 = keys.length; k < len1; k++) { name = keys[k]; try { if ((ref = this[name]) != null) { ref.call(node); } } catch (_error) { err = _error; if (!errors) { errors = []; } errors.push({ message: ['"', name, '" crashed on node ', this.type, ' No.', node.ID, ' (', node.board, ').'].join(''), error: err }); } } if (errors) { return Main.handleErrors(errors); } }; return Callbacks; })(); Board = (function() { Board.prototype.toString = function() { return this.ID; }; function Board(ID1) { this.ID = ID1; this.threads = new SimpleDict(); this.posts = new SimpleDict(); g.boards[this] = this; } return Board; })(); Thread = (function() { Thread.callbacks = new Callbacks('Thread'); Thread.prototype.toString = function() { return this.ID; }; function Thread(ID1, board1) { this.ID = ID1; this.board = board1; this.fullID = this.board + "." + this.ID; this.posts = new SimpleDict(); this.isDead = false; this.isHidden = false; this.isOnTop = false; this.isSticky = false; this.isClosed = false; this.isArchived = false; this.postLimit = false; this.fileLimit = false; this.ipCount = void 0; this.OP = null; this.catalogView = null; this.board.threads.push(this.ID, this); g.threads.push(this.fullID, this); } Thread.prototype.setPage = function(pageNum) { var icon, info, quote, ref; ref = this.OP.nodes, info = ref.info, quote = ref.quote; if (!(icon = $('.page-num', info))) { icon = $.el('span', { className: 'page-num' }); $.after(quote, [$.tn(' '), icon]); } icon.title = "This thread is on page " + pageNum + " in the original index."; icon.textContent = "[" + pageNum + "]"; if (this.catalogView) { return this.catalogView.nodes.pageCount.textContent = pageNum; } }; Thread.prototype.setCount = function(type, count, reachedLimit) { var el; if (!this.catalogView) { return; } el = this.catalogView.nodes[type + "Count"]; el.textContent = count; return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning'); }; Thread.prototype.setStatus = function(type, status) { var name; name = "is" + type; if (this[name] === status) { return; } this[name] = status; if (!this.OP) { return; } this.setIcon('Sticky', this.isSticky); this.setIcon('Closed', this.isClosed && !this.isArchived); return this.setIcon('Archived', this.isArchived); }; Thread.prototype.setIcon = function(type, status) { var icon, root, typeLC; typeLC = type.toLowerCase(); icon = $("." + typeLC + "Icon", this.OP.nodes.info); if (!!icon === status) { return; } if (!status) { $.rm(icon.previousSibling); $.rm(icon); if (this.catalogView) { $.rm($("." + typeLC + "Icon", this.catalogView.nodes.icons)); } return; } icon = $.el('img', { src: "" + Build.staticPath + typeLC + Build.gifIcon, alt: type, title: type, className: typeLC + "Icon retina" }); root = type !== 'Sticky' && this.isSticky ? $('.stickyIcon', this.OP.nodes.info) : $('.page-num', this.OP.nodes.info) || this.OP.nodes.quote; $.after(root, [$.tn(' '), icon]); if (!this.catalogView) { return; } return (type === 'Sticky' && this.isClosed ? $.prepend : $.add)(this.catalogView.nodes.icons, icon.cloneNode()); }; Thread.prototype.kill = function() { return this.isDead = true; }; Thread.prototype.collect = function() { this.posts.forEach(function(post) { return post.collect(); }); g.threads.rm(this.fullID); return this.board.threads.rm(this); }; return Thread; })(); CatalogThread = (function() { CatalogThread.callbacks = new Callbacks('Catalog Thread'); CatalogThread.prototype.toString = function() { return this.ID; }; function CatalogThread(root, thread1) { this.thread = thread1; this.ID = this.thread.ID; this.board = this.thread.board; this.nodes = { root: root, thumb: $('.catalog-thumb', root), icons: $('.catalog-icons', root), postCount: $('.post-count', root), fileCount: $('.file-count', root), pageCount: $('.page-count', root), comment: $('.comment', root) }; this.thread.catalogView = this; } return CatalogThread; })(); Post = (function() { Post.callbacks = new Callbacks('Post'); Post.prototype.toString = function() { return this.ID; }; function Post(root, thread1, board1) { var capcode, clone, date, email, flag, info, k, len1, name, post, ref, subject, tripcode, uniqueID; this.thread = thread1; this.board = board1; 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, nameBlock: $('.nameBlock', info), quote: $('.postNum > a:nth-of-type(2)', info), comment: $('.postMessage', post), links: [], quotelinks: [] }; if ($.engine === 'edge') { Object.defineProperty(this.nodes, 'backlinks', { configurable: true, enumerable: true, get: function() { return info.getElementsByClassName('backlink'); } }); } else { this.nodes.backlinks = info.getElementsByClassName('backlink'); } if (!(this.isReply = $.hasClass(post, 'reply'))) { this.thread.OP = this; this.thread.isArchived = !!$('.archivedIcon', info); this.thread.isSticky = !!$('.stickyIcon', info); this.thread.isClosed = this.thread.isArchived || !!$('.closedIcon', info); if (this.thread.isArchived) { this.thread.kill(); } } this.info = {}; this.info.nameBlock = Conf['Anonymize'] ? 'Anonymous' : this.nodes.nameBlock.textContent.trim(); if (subject = $('.subject', info)) { this.nodes.subject = subject; this.info.subject = subject.textContent || void 0; } 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); } this.parseComment(); this.parseQuotes(); this.parseFile(); this.isDead = false; this.isHidden = false; this.clones = []; if (g.posts[this.fullID]) { this.isRebuilt = true; this.clones = g.posts[this.fullID].clones; ref = this.clones; for (k = 0, len1 = ref.length; k < len1; k++) { clone = ref[k]; clone.origin = this; } } this.board.posts.push(this.ID, this); this.thread.posts.push(this.ID, this); g.posts.push(this.fullID, this); } Post.prototype.parseComment = function() { var abbr, bq, commentDisplay, k, len1, len2, node, q, ref, spoilers; this.nodes.comment.normalize(); bq = this.nodes.comment.cloneNode(true); ref = $$('.abbr + br, .exif, b, .fortune', bq); for (k = 0, len1 = ref.length; k < len1; k++) { node = ref[k]; $.rm(node); } if (abbr = $('.abbr', bq)) { $.rm(abbr); } this.info.comment = this.nodesToText(bq); if (abbr) { this.info.comment = this.info.comment.replace(/\n\n$/, ''); } commentDisplay = this.info.comment; if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { spoilers = $$('s', bq); if (spoilers.length) { for (q = 0, len2 = spoilers.length; q < len2; q++) { node = spoilers[q]; $.replace(node, $.tn('[spoiler]')); } commentDisplay = this.nodesToText(bq); } } return this.info.commentDisplay = commentDisplay.trim().replace(/\s+$/gm, ''); }; Post.prototype.nodesToText = function(bq) { var i, node, nodes, text; text = ""; nodes = $.X('.//br|.//text()', bq); i = 0; while (node = nodes.snapshotItem(i++)) { text += node.data || '\n'; } return text; }; Post.prototype.parseQuotes = function() { var k, len1, quotelink, ref; this.quotes = []; ref = $$(':not(pre) > .quotelink', this.nodes.comment); for (k = 0, len1 = ref.length; k < len1; k++) { quotelink = ref[k]; this.parseQuote(quotelink); } }; Post.prototype.parseQuote = function(quotelink) { var fullID, match; if (!(match = quotelink.href.match(/^https?:\/\/boards\.4chan\.org\/+([^\/]+)\/+(?:res|thread)\/+\d+(?:\/[^#]*)?#p(\d+)$/))) { return; } this.nodes.quotelinks.push(quotelink); if (this.isClone) { return; } fullID = match[1] + "." + match[2]; if (indexOf.call(this.quotes, fullID) < 0) { return this.quotes.push(fullID); } }; Post.prototype.parseFile = function() { var fileEl, fileText, info, link, m, ref, ref1, ref2, size, thumb, unit; if (!(fileEl = $('.file', this.nodes.post))) { return; } if (!(link = $('.fileText > a, .fileText-original > a', fileEl))) { return; } if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { return; } fileText = fileEl.firstElementChild; this.file = { text: fileText, link: link, url: link.href, name: fileText.title || link.title || link.textContent, size: info[1], isImage: /(jpg|png|gif)$/i.test(link.href), isVideo: /webm$/i.test(link.href), dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, tag: (ref2 = info[0].match(/,[^,]*, ([a-z]+)\)/i)) != null ? ref2[1] : void 0 }; 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; if ((thumb = $('.fileThumb > [data-md5]', fileEl))) { return $.extend(this.file, { thumb: thumb, thumbURL: (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//i.4cdn.org/" + this.board + "/" + m[0] + "s.jpg" : void 0, MD5: thumb.dataset.md5, isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') }); } }; Post.prototype.kill = function(file) { var clone, k, len1, len2, q, quotelink, ref, ref1, strong; if (file) { if (this.file.isDead) { return; } this.file.isDead = true; $.addClass(this.nodes.root, 'deleted-file'); } else { if (this.isDead) { return; } this.isDead = true; $.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 (k = 0, len1 = ref.length; k < len1; k++) { clone = ref[k]; clone.kill(file); } if (file) { return; } ref1 = Get.allQuotelinksLinkingTo(this); for (q = 0, len2 = ref1.length; q < len2; q++) { quotelink = ref1[q]; if (!(!$.hasClass(quotelink, 'deadlink'))) { continue; } quotelink.textContent = quotelink.textContent + '\u00A0(Dead)'; $.addClass(quotelink, 'deadlink'); } }; Post.prototype.resurrect = function() { var clone, k, len1, len2, q, quotelink, ref, ref1, strong; this.isDead = false; $.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 (k = 0, len1 = ref.length; k < len1; k++) { clone = ref[k]; clone.resurrect(); } ref1 = Get.allQuotelinksLinkingTo(this); for (q = 0, len2 = ref1.length; q < len2; q++) { quotelink = ref1[q]; if (!($.hasClass(quotelink, 'deadlink'))) { continue; } quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', ''); $.rmClass(quotelink, 'deadlink'); } }; Post.prototype.collect = function() { g.posts.rm(this.fullID); this.thread.posts.rm(this); return this.board.posts.rm(this); }; Post.prototype.addClone = function(context, contractThumb) { return new Clone(this, context, contractThumb); }; Post.prototype.rmClone = function(index) { var clone, k, len1, ref; this.clones.splice(index, 1); ref = this.clones.slice(index); for (k = 0, len1 = ref.length; k < len1; k++) { clone = ref[k]; clone.nodes.root.dataset.clone = index++; } }; return Post; })(); Clone = (function(superClass) { extend(Clone, superClass); function Clone(origin1, context1, contractThumb) { var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, ref4, root, u, val; this.origin = origin1; this.context = context1; ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; for (k = 0, len1 = ref.length; k < len1; k++) { key = ref[k]; this[key] = this.origin[key]; } nodes = this.origin.nodes; root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true); post = $('.post', root); info = $('.postInfo', post); this.nodes = { root: root, post: post, info: info, nameBlock: $('.nameBlock', info), quote: $('.postNum > a:nth-of-type(2)', info), comment: $('.postMessage', post), quotelinks: [] }; if ($.engine === 'edge') { Object.defineProperty(this.nodes, 'backlinks', { configurable: true, enumerable: true, get: function() { return info.getElementsByClassName('backlink'); } }); } else { this.nodes.backlinks = info.getElementsByClassName('backlink'); } ref1 = $$('.inline', post); for (q = 0, len2 = ref1.length; q < len2; q++) { inline = ref1[q]; $.rm(inline); } ref2 = $$('.inlined', post); for (u = 0, len3 = ref2.length; u < len3; u++) { inlined = ref2[u]; $.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.hand', info); } if (nodes.flag) { this.nodes.flag = $('.flag, .countryFlag', info); } if (nodes.date) { this.nodes.date = $('.dateTime', info); } this.parseQuotes(); if (this.origin.file) { this.file = {}; ref3 = this.origin.file; for (key in ref3) { val = ref3[key]; this.file[key] = val; } file = $('.file', post); this.file.text = file.firstElementChild; this.file.link = $('.fileText > a, .fileText-original', file); this.file.thumb = $('.fileThumb > [data-md5]', file); this.file.fullImage = $('.full-image', file); this.file.videoControls = $('.video-controls', this.file.text); if (this.file.videoThumb) { this.file.thumb.muted = true; } if ((ref4 = this.file.thumb) != null ? ref4.dataset.src : void 0) { this.file.thumb.src = this.file.thumb.dataset.src; this.file.thumb.removeAttribute('data-src'); } if (this.file.thumb && contractThumb) { ImageExpand.contract(this); } } if (this.origin.isDead) { this.isDead = true; } this.isClone = true; root.dataset.clone = this.origin.clones.push(this) - 1; } Clone.prototype.cloneWithoutVideo = function(node) { var child, clone, k, len1, ref; if (node.tagName === 'VIDEO' && !node.dataset.md5) { return []; } else if (node.nodeType === Node.ELEMENT_NODE && $('video', node)) { clone = node.cloneNode(false); ref = node.childNodes; for (k = 0, len1 = ref.length; k < len1; k++) { child = ref[k]; $.add(clone, this.cloneWithoutVideo(child)); } return clone; } else { return node.cloneNode(true); } }; return Clone; })(Post); DataBoard = (function() { DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'customTitles']; function DataBoard(key1, sync, dontClean) { var init; this.key = key1; this.onSync = bind(this.onSync, this); this.data = Conf[this.key]; $.sync(this.key, this.onSync); if (!dontClean) { this.clean(); } if (!sync) { return; } init = (function(_this) { return function() { $.off(d, '4chanXInitFinished', init); return _this.sync = sync; }; })(this); $.on(d, '4chanXInitFinished', init); } DataBoard.prototype.save = function(cb) { return $.set(this.key, this.data, cb); }; DataBoard.prototype["delete"] = function(arg) { var boardID, postID, ref, threadID; boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; $.forceSync(this.key); if (postID) { if (!((ref = this.data.boards[boardID]) != null ? ref[threadID] : void 0)) { return; } delete this.data.boards[boardID][threadID][postID]; this.deleteIfEmpty({ boardID: boardID, threadID: threadID }); } else if (threadID) { if (!this.data.boards[boardID]) { return; } 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; $.forceSync(this.key); 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, cb) { var base1, base2, base3, boardID, postID, threadID, val; boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; $.forceSync(this.key); if (postID !== void 0) { ((base1 = ((base2 = this.data.boards)[boardID] || (base2[boardID] = {})))[threadID] || (base1[threadID] = {}))[postID] = val; } else if (threadID !== void 0) { ((base3 = this.data.boards)[boardID] || (base3[boardID] = {}))[threadID] = val; } else { this.data.boards[boardID] = val; } return this.save(cb); }; DataBoard.prototype.get = function(arg) { var ID, board, boardID, defaultValue, k, len1, postID, thread, threadID, val; boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, defaultValue = arg.defaultValue; if (board = this.data.boards[boardID]) { if (threadID == null) { if (postID != null) { for (thread = k = 0, len1 = board.length; k < len1; thread = ++k) { ID = board[thread]; if (postID in thread) { val = thread[postID]; break; } } } else { val = board; } } else if (thread = board[threadID]) { val = postID != null ? thread[postID] : thread; } } return val || defaultValue; }; DataBoard.prototype.forceSync = function() { return $.forceSync(this.key); }; DataBoard.prototype.clean = function() { var boardID, now, ref, val; $.forceSync(this.key); 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); } } }; DataBoard.prototype.ajaxClean = function(boardID) { return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) { return function(e1) { var ref; if ((ref = e1.target.status) !== 200 && ref !== 404) { return; } return $.cache("//a.4cdn.org/" + boardID + "/archive.json", function(e2) { var ref1; if ((ref1 = e2.target.status) !== 200 && ref1 !== 404) { return; } return _this.ajaxCleanParse(boardID, e1.target.response, e2.target.response); }); }; })(this)); }; DataBoard.prototype.ajaxCleanParse = function(boardID, response1, response2) { var ID, board, k, len1, len2, len3, page, q, ref, thread, threads, u; board = this.data.boards[boardID]; threads = {}; if (response1) { for (k = 0, len1 = response1.length; k < len1; k++) { page = response1[k]; ref = page.threads; for (q = 0, len2 = ref.length; q < len2; q++) { thread = ref[q]; ID = thread.no; if (ID in board) { threads[ID] = board[ID]; } } } } if (response2) { for (u = 0, len3 = response2.length; u < len3; u++) { ID = response2[u]; if (ID in board) { threads[ID] = board[ID]; } } } 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, timeout1, onclose) { this.timeout = timeout1; this.onclose = onclose; 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(Header.noticesRoot, 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); $.rm(this.el); return typeof this.onclose === "function" ? this.onclose() : void 0; }; return Notice; })(); RandomAccessList = (function() { function RandomAccessList(items) { var item, k, len1; this.length = 0; if (items) { for (k = 0, len1 = items.length; k < len1; k++) { item = items[k]; this.push(item); } } } RandomAccessList.prototype.push = function(data) { var ID, item, last; ID = data.ID; ID || (ID = data.id); if (this[ID]) { return; } last = this.last; this[ID] = item = { prev: last, next: null, data: data, ID: ID }; item.prev = last; this.last = last ? last.next = item : this.first = item; return this.length++; }; RandomAccessList.prototype.before = function(root, item) { var prev; if (item.next === root || item === root) { return; } this.rmi(item); prev = root.prev; root.prev = item; item.next = root; item.prev = prev; if (prev) { return prev.next = item; } else { return this.first = item; } }; RandomAccessList.prototype.after = function(root, item) { var next; if (item.prev === root || item === root) { return; } this.rmi(item); next = root.next; root.next = item; item.prev = root; item.next = next; if (next) { return next.prev = item; } else { return this.last = item; } }; RandomAccessList.prototype.prepend = function(item) { var first; first = this.first; if (item === first || !this[item.ID]) { return; } this.rmi(item); item.next = first; if (first) { first.prev = item; } else { this.last = item; } this.first = item; return delete item.prev; }; RandomAccessList.prototype.shift = function() { return this.rm(this.first.ID); }; RandomAccessList.prototype.order = function() { var item, order; order = [item = this.first]; while (item = item.next) { order.push(item); } return order; }; RandomAccessList.prototype.rm = function(ID) { var item; item = this[ID]; if (!item) { return; } delete this[ID]; this.length--; this.rmi(item); delete item.next; return delete item.prev; }; RandomAccessList.prototype.rmi = function(item) { var next, prev; prev = item.prev, next = item.next; if (prev) { prev.next = next; } else { this.first = next; } if (next) { return next.prev = prev; } else { return this.last = prev; } }; return RandomAccessList; })(); SimpleDict = (function() { function SimpleDict() { this.keys = []; } SimpleDict.prototype.push = function(key, data) { key = "" + key; if (!this[key]) { this.keys.push(key); } return this[key] = data; }; SimpleDict.prototype.rm = function(key) { var i; key = "" + key; if ((i = this.keys.indexOf(key)) !== -1) { this.keys.splice(i, 1); return delete this[key]; } }; SimpleDict.prototype.forEach = function(fn) { var k, key, len1, ref; ref = slice.call(this.keys); for (k = 0, len1 = ref.length; k < len1; k++) { key = ref[k]; fn(this[key]); } }; return SimpleDict; })(); ShimSet = (function() { function ShimSet() { this.elements = {}; this.size = 0; } ShimSet.prototype.has = function(value) { return value in this.elements; }; ShimSet.prototype.add = function(value) { if (this.elements[value]) { return; } this.elements[value] = true; return this.size++; }; ShimSet.prototype["delete"] = function(value) { if (!this.elements[value]) { return; } delete this.elements[value]; return this.size--; }; return ShimSet; })(); if (!('Set' in window)) { window.Set = ShimSet; } Connection = (function() { function Connection(target1, origin1, cb1) { this.target = target1; this.origin = origin1; this.cb = cb1 != null ? cb1 : {}; this.onMessage = bind(this.onMessage, this); this.send = bind(this.send, this); $.on(window, 'message', this.onMessage); } Connection.prototype.targetWindow = function() { if (this.target instanceof window.HTMLIFrameElement) { return this.target.contentWindow; } else { return this.target; } }; Connection.prototype.send = function(data) { return this.targetWindow().postMessage("" + g.NAMESPACE + (JSON.stringify(data)), this.origin); }; Connection.prototype.onMessage = function(e) { var base1, data, type, value; if (!(e.source === this.targetWindow() && e.origin === this.origin && typeof e.data === 'string' && e.data.slice(0, g.NAMESPACE.length) === g.NAMESPACE)) { return; } data = JSON.parse(e.data.slice(g.NAMESPACE.length)); for (type in data) { value = data[type]; if (typeof (base1 = this.cb)[type] === "function") { base1[type](value); } } }; return Connection; })(); Fetcher = (function() { function Fetcher(boardID1, threadID1, postID1, root1, context1) { var post; this.boardID = boardID1; this.threadID = threadID1; this.postID = postID1; this.root = root1; this.context = context1; if (post = g.posts[this.boardID + "." + this.postID]) { this.insert(post); return; } this.root.textContent = "Loading post No." + this.postID + "..."; if (this.threadID) { $.cache("//a.4cdn.org/" + this.boardID + "/thread/" + this.threadID + ".json", (function(_this) { return function(e) { return _this.fetchedPost(e.target); }; })(this)); } else { this.archivedPost(); } } Fetcher.prototype.insert = function(post) { var clone, nodes; if (!this.root.parentNode) { return; } clone = post.addClone(this.context, $.hasClass(this.root, 'dialog')); Main.callbackNodes(Clone, [clone]); nodes = clone.nodes; $.rmAll(nodes.root); $.add(nodes.root, nodes.post); $.rmAll(this.root); $.add(this.root, nodes.root); return $.event('PostsInserted'); }; Fetcher.prototype.fetchedPost = function(req) { var api, board, k, len1, post, posts, status, thread; if (post = g.posts[this.boardID + "." + this.postID]) { this.insert(post); return; } status = req.status; if (status !== 200 && status !== 304) { if (this.archivedPost()) { return; } $.addClass(this.root, 'warning'); this.root.textContent = status === 404 ? "Thread No." + this.threadID + " 404'd." : "Error " + req.statusText + " (" + req.status + ")."; return; } posts = req.response.posts; Build.spoilerRange[this.boardID] = posts[0].custom_spoiler; for (k = 0, len1 = posts.length; k < len1; k++) { post = posts[k]; if (post.no === this.postID) { break; } } if (post.no !== this.postID) { if (req.cached) { api = "//a.4cdn.org/" + this.boardID + "/thread/" + this.threadID + ".json"; $.cleanCache(function(url) { return url === api; }); $.cache(api, (function(_this) { return function(e) { return _this.fetchedPost(e.target); }; })(this)); return; } if (this.archivedPost()) { return; } $.addClass(this.root, 'warning'); this.root.textContent = "Post No." + this.postID + " was not found."; return; } board = g.boards[this.boardID] || new Board(this.boardID); thread = g.threads[this.boardID + "." + this.threadID] || new Thread(this.threadID, board); post = new Post(Build.postFromObject(post, this.boardID), thread, board); post.isFetchedQuote = true; Main.callbackNodes(Post, [post]); return this.insert(post); }; Fetcher.prototype.archivedPost = function() { var archive, url; if (!Conf['Resurrect Quotes']) { return false; } if (!(url = Redirect.to('post', { boardID: this.boardID, postID: this.postID }))) { return false; } archive = Redirect.data.post[this.boardID]; if (/^https:\/\//.test(url) || location.protocol === 'http:') { $.cache(url, (function(_this) { return function(e) { return _this.parseArchivedPost(e.target.response, url); }; })(this), { responseType: 'json', withCredentials: archive.withCredentials }); return true; } else if (Conf['Exempt Archives from Encryption']) { CrossOrigin.json(url, (function(_this) { return function(response) { var key, media, ref; media = response.media; if (media) { for (key in media) { if (/_link$/.test(key)) { if (!((ref = media[key]) != null ? ref.match(/^http:\/\//) : void 0)) { delete media[key]; } } } } return _this.parseArchivedPost(response, url); }; })(this)); return true; } return false; }; Fetcher.prototype.parseArchivedPost = function(data, url) { var board, comment, greentext, i, j, key, o, post, ref, ref1, text, text2, thread, val; if (post = g.posts[this.boardID + "." + this.postID]) { this.insert(post); return; } if (data.error) { $.addClass(this.root, 'warning'); this.root.textContent = data.error; return; } comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned)\])/); comment = (function() { var k, len1, results; results = []; for (i = k = 0, len1 = comment.length; k < len1; i = ++k) { text = comment[i]; if (i % 2 === 1) { results.push(this.archiveTags[text]); } else { greentext = text[0] === '>'; text = text.replace(/(\[\/?[a-z]+):lit(\])/, '$1$2'); text = (function() { var len2, q, ref, results1; ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g); results1 = []; for (j = q = 0, len2 = ref.length; q < len2; j = ++q) { text2 = ref[j]; results1.push({ innerHTML: (j % 2 ? "" + E(text2) + "" : E(text2)) }); } return results1; })(); text = { innerHTML: (greentext ? "" + E.cat(text) + "" : E.cat(text)) }; results.push(text); } } return results; }).call(this); comment = { innerHTML: E.cat(comment) }; this.threadID = +data.thread_num; o = { postID: this.postID, threadID: this.threadID, boardID: this.boardID, isReply: this.postID !== this.threadID }; o.info = { subject: data.title, email: data.email, name: data.name || '', tripcode: data.trip, capcode: (function() { switch (data.capcode) { case 'M': return 'Mod'; case 'A': return 'Admin'; case 'D': return 'Developer'; } })(), uniqueID: data.poster_hash, flagCode: data.poster_country, flag: data.poster_country_name, dateUTC: data.timestamp, dateText: data.fourchan_date, commentHTML: comment }; if (o.info.capcode) { delete o.info.uniqueID; } if ((ref = data.media) != null ? ref.media_filename : void 0) { ref1 = data.media; for (key in ref1) { val = ref1[key]; if (/_link$/.test(key) && (val != null ? val[0] : void 0) === '/') { data.media[key] = url.split('/', 3).join('/') + val; } } o.file = { name: data.media.media_filename, url: data.media.media_link || data.media.remote_media_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), height: data.media.media_h, width: data.media.media_w, MD5: data.media.media_hash, size: $.bytesToString(data.media.media_size), thumbURL: data.media.thumb_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), theight: data.media.preview_h, twidth: data.media.preview_w, isSpoiler: data.media.spoiler === '1' }; if (!/\.pdf$/.test(o.file.url)) { o.file.dimensions = o.file.width + "x" + o.file.height; } if (this.boardID === 'f' && data.media.exif) { o.file.tag = JSON.parse(data.media.exif).Tag; } } board = g.boards[this.boardID] || new Board(this.boardID); thread = g.threads[this.boardID + "." + this.threadID] || new Thread(this.threadID, board); post = new Post(Build.post(o), thread, board); post.kill(); if (post.file) { post.file.thumbURL = o.file.thumbURL; } post.isFetchedQuote = true; Main.callbackNodes(Post, [post]); return this.insert(post); }; Fetcher.prototype.archiveTags = { '\n': { innerHTML: "
" }, '[b]': { innerHTML: "" }, '[/b]': { innerHTML: "" }, '[spoiler]': { innerHTML: "" }, '[/spoiler]': { innerHTML: "" }, '[code]': { innerHTML: "
"
      },
      '[/code]': {
        innerHTML: "
" }, '[moot]': { innerHTML: "
" }, '[/moot]': { innerHTML: "
" }, '[banned]': { innerHTML: "" }, '[/banned]': { innerHTML: "" } }; return Fetcher; })(); Polyfill = { init: function() { return this.toBlob(); }, toBlob: function() { if (HTMLCanvasElement.prototype.toBlob) { return; } HTMLCanvasElement.prototype.toBlob = function(cb, type, encoderOptions) { var data, i, k, l, ref, ui8a, url; if (type == null) { type = 'image/png'; } url = this.toDataURL(type, encoderOptions); data = atob(url.slice(url.indexOf(',') + 1)); l = data.length; ui8a = new Uint8Array(l); for (i = k = 0, ref = l; k < ref; i = k += 1) { ui8a[i] = data.charCodeAt(i); } return cb(new Blob([ui8a], { type: type })); }; return $.globalEval("HTMLCanvasElement.prototype.toBlob = (" + HTMLCanvasElement.prototype.toBlob + ");"); } }; Header = { init: function() { var barFixedToggler, barPositionToggler, box, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, scrollHeaderToggler, shortcutToggler; this.menu = new UI.Menu('header'); menuButton = $.el('span', { className: 'menu-button' }); $.extend(menuButton, { innerHTML: "" }); box = UI.checkbox; barFixedToggler = box('Fixed Header', 'Fixed Header'); headerToggler = box('Header auto-hide', 'Auto-hide header'); scrollHeaderToggler = box('Header auto-hide on scroll', 'Auto-hide header on scroll'); barPositionToggler = box('Bottom Header', 'Bottom header'); linkJustifyToggler = box('Centered links', 'Centered links'); customNavToggler = box('Custom Board Navigation', 'Custom board navigation'); footerToggler = box('Bottom Board List', 'Hide bottom board list'); shortcutToggler = box('Shortcut Icons', 'Shortcut Icons'); editCustomNav = $.el('a', { textContent: 'Edit custom board navigation', href: 'javascript:;' }); this.barFixedToggler = barFixedToggler.firstElementChild; this.scrollHeaderToggler = scrollHeaderToggler.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.headerToggler, 'change', this.toggleBarVisibility); $.on(this.barFixedToggler, 'change', this.toggleBarFixed); $.on(this.barPositionToggler, 'change', this.toggleBarPosition); $.on(this.scrollHeaderToggler, 'change', this.toggleHideBarOnScroll); $.on(this.linkJustifyToggler, 'change', this.toggleLinkJustify); $.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.setHideBarOnScroll(Conf['Header auto-hide on scroll']); this.setBarVisibility(Conf['Header auto-hide']); this.setLinkJustify(Conf['Centered links']); this.setShortcutIcons(Conf['Shortcut Icons']); this.setFooterVisibility(Conf['Bottom Board List']); $.sync('Fixed Header', this.setBarFixed); $.sync('Header auto-hide on scroll', this.setHideBarOnScroll); $.sync('Bottom Header', this.setBarPosition); $.sync('Shortcut Icons', this.setShortcutIcons); $.sync('Header auto-hide', this.setBarVisibility); $.sync('Centered links', this.setLinkJustify); $.sync('Bottom Board List', this.setFooterVisibility); this.addShortcut(menuButton); this.menu.addEntry({ el: $.el('span', { textContent: 'Header' }), order: 107, subEntries: [ { el: barFixedToggler }, { el: headerToggler }, { el: scrollHeaderToggler }, { 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(_this) { return function() { if (!Main.isThisPageLegit()) { return; } $.asap((function() { return $.id('boardNavMobile') || d.readyState !== 'loading'; }), function() { var a, footer; footer = $.id('boardNavDesktop').cloneNode(true); footer.id = 'boardNavDesktopFoot'; $('#navtopright', footer).id = 'navbotright'; $('#settingsWindowLink', footer).id = 'settingsWindowLinkBot'; Header.bottomBoardList = $('.boardList', footer); if (a = $("a[href*='/" + g.BOARD + "/']", footer)) { a.className = 'current'; } Main.ready(function() { var oldFooter; if (oldFooter = $.id('boardNavDesktopFoot')) { return $.replace($('.boardList', oldFooter), Header.bottomBoardList); } else { $.before($.id('absbot'), footer); return $.globalEval('window.cloneTopNav = function() {};'); } }); return Header.setBoardList(); }); $.prepend(d.body, _this.bar); $.add(d.body, Header.hover); _this.setBarPosition(Conf['Bottom Header']); return _this; }; })(this)); Main.ready((function(_this) { return function() { var cs; if (g.VIEW === 'catalog' || !Conf['Disable Native Extension']) { cs = $.el('a', { href: 'javascript:;' }); if (g.VIEW === 'catalog') { cs.title = cs.textContent = 'Catalog Settings'; cs.className = 'fa fa-book'; } else { cs.title = cs.textContent = '4chan Settings'; cs.className = 'fa fa-leaf'; } $.on(cs, 'click', function() { return $.id('settingsWindowLink').click(); }); return _this.addShortcut(cs); } }; })(this)); return this.enableDesktopNotifications(); }, bar: $.el('div', { id: 'header-bar' }), noticesRoot: $.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, chr, k, len1, len2, node, nodes, q, ref, ref1, spacer, span; Header.boardList = boardList = $.el('span', { id: 'board-list' }); $.extend(boardList, { innerHTML: "" }); btn = $('.hide-board-list-button', boardList); $.on(btn, 'click', Header.toggleBoardList); nodes = []; spacer = function() { return $.el('span', { className: 'spacer' }); }; ref = $('#boardNavDesktop > .boardList').childNodes; for (k = 0, len1 = ref.length; k < len1; k++) { node = ref[k]; switch (node.nodeName) { case '#text': ref1 = node.nodeValue; for (q = 0, len2 = ref1.length; q < len2; q++) { chr = ref1[q]; span = $.el('span', { textContent: chr }); if (chr === ' ') { span.className = 'space'; } if (chr === ']') { nodes.push(spacer()); } nodes.push(span); if (chr === '[') { nodes.push(spacer()); } } break; case 'A': a = node.cloneNode(true); if (a.pathname.split('/')[1] === g.BOARD.ID) { a.className = 'current'; } nodes.push(a); } } $.add($('.boardList', boardList), nodes); $.add(Header.bar, [Header.boardList, Header.shortcuts, Header.noticesRoot, Header.toggle]); Header.setCustomNav(Conf['Custom Board Navigation']); Header.generateBoardList(Conf['boardnav']); $.sync('Custom Board Navigation', Header.setCustomNav); return $.sync('boardnav', Header.generateBoardList); }, generateBoardList: function(boardnav) { var as, list, nodes, re, t; list = $('#custom-board-list', Header.boardList); $.rmAll(list); if (!boardnav) { return; } boardnav = boardnav.replace(/(\r\n|\n|\r)/g, ' '); as = $$('#full-board-list a[title]', Header.boardList); re = /[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|text:"[^"]+"(,"[^"]+")?))*|[^\w@]+/g; nodes = (function() { var k, len1, ref, results; ref = boardnav.match(re); results = []; for (k = 0, len1 = ref.length; k < len1; k++) { t = ref[k]; results.push(Header.mapCustomNavigation(t, as)); } return results; })(); $.add(list, nodes); return $.ready(CatalogLinks.initBoardList); }, mapCustomNavigation: function(t, as) { var a, boardID, href, m, text, url; if (/^[^\w@]/.test(t)) { return $.tn(t); } text = url = null; t = t.replace(/-text:"([^"]+)"(?:,"([^"]+)")?/g, function(m0, m1, m2) { text = m1; url = m2; return ''; }); if (/^toggle-all/.test(t)) { a = $.el('a', { className: 'show-board-list-button', textContent: text || '+', href: 'javascript:;' }); $.on(a, 'click', Header.toggleBoardList); return a; } if (/^external/.test(t)) { a = $.el('a', { href: url || 'javascript:;', textContent: text || '+', className: 'external' }); return a; } boardID = t.split('-')[0]; if (boardID === 'current') { boardID = g.BOARD.ID; } a = (function() { var k, len1, ref; if (boardID === '@') { return $.el('a', { href: 'https://twitter.com/4chan', title: '4chan Twitter', textContent: '@' }); } for (k = 0, len1 = as.length; k < len1; k++) { a = as[k]; if (a.textContent === boardID) { return a.cloneNode(true); } } a = $.el('a', { href: "/" + boardID + "/", textContent: boardID }); if ((ref = g.VIEW) === 'catalog' || ref === 'archive') { a.href += g.VIEW; } if (boardID === g.BOARD.ID) { a.className = 'current'; } return a; })(); a.textContent = /-title/.test(t) || /-replace/.test(t) && boardID === g.BOARD.ID ? a.title || a.textContent : /-full/.test(t) ? ("/" + boardID + "/") + (a.title ? " - " + a.title : '') : text || boardID; if (m = t.match(/-(index|catalog)/)) { if (!(boardID === 'f' && m[1] === 'catalog')) { a.dataset.only = m[1]; a.href = CatalogLinks[m[1]](boardID); if (m[1] === 'catalog') { $.addClass(a, 'catalog'); } } else { return a.firstChild; } } if (/-archive/.test(t)) { if (href = Redirect.to('board', { boardID: boardID })) { a.href = href; } else { return a.firstChild; } } if (/-expired/.test(t)) { if (boardID !== 'b' && boardID !== 'f' && boardID !== 'trash') { a.href = "/" + boardID + "/archive"; } else { return a.firstChild; } } if (boardID === '@') { $.addClass(a, 'navSmall'); } return a; }, 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; }, setLinkJustify: function(centered) { Header.linkJustifyToggler.checked = centered; if (centered) { return $.addClass(doc, 'centered-links'); } else { return $.rmClass(doc, 'centered-links'); } }, 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'); Conf['Header auto-hide'] = hide; $.set('Header auto-hide', hide); Header.setBarVisibility(hide); message = "The header bar will " + (hide ? 'automatically hide itself.' : 'remain visible.'); return new Notice('info', message, 2); }, setHideBarOnScroll: function(hide) { Header.scrollHeaderToggler.checked = hide; if (hide) { $.on(window, 'scroll', Header.hideBarOnScroll); return; } $.off(window, 'scroll', Header.hideBarOnScroll); $.rmClass(Header.bar, 'scroll'); if (!Conf['Header auto-hide']) { return $.rmClass(Header.bar, 'autohide'); } }, toggleHideBarOnScroll: function() { var hide; hide = this.checked; $.cb.checked.call(this); return Header.setHideBarOnScroll(hide); }, hideBarOnScroll: function() { var offsetY; offsetY = window.pageYOffset; if (offsetY > (Header.previousOffset || 0)) { $.addClass(Header.bar, 'autohide', 'scroll'); } else { $.rmClass(Header.bar, 'autohide', 'scroll'); } return Header.previousOffset = offsetY; }, setBarPosition: function(bottom) { var args; Header.barPositionToggler.checked = bottom; $.event('CloseMenu'); args = bottom ? ['bottom-header', 'top-header', 'after'] : ['top-header', 'bottom-header', 'add']; $.addClass(doc, args[0]); $.rmClass(doc, args[1]); return $[args[2]](Header.bar, Header.noticesRoot); }, toggleBarPosition: function() { $.cb.checked.call(this); return Header.setBarPosition(this.checked); }, setFooterVisibility: function(hide) { Header.footerToggler.checked = hide; return doc.classList.toggle('hide-bottom-board-list', hide); }, toggleFooterVisibility: function() { var hide, message; $.event('CloseMenu'); hide = this.nodeName === 'INPUT' ? this.checked : $.hasClass(doc, 'hide-bottom-board-list'); 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-container', full); return ref = show ? [false, true, false] : [true, false, true], cust.hidden = ref[0], full.hidden = ref[1], btn.hidden = ref[2], ref; }, toggleCustomNav: function() { $.cb.checked.call(this); return Header.setCustomNav(this.checked); }, editCustomNav: function() { var settings; Settings.open('Advanced'); settings = $.id('fourchanx-settings'); return $('[name=boardnav]', settings).focus(); }, hashScroll: function() { var hash, post; hash = this.location.hash.slice(1); if (!(/^p\d+$/.test(hash) && (post = $.id(hash)))) { return; } if ((Get.postFromRoot(post)).isHidden) { return; } return Header.scrollTo(post); }, scrollTo: function(root, down, needed) { var height, x; if (down) { x = Header.getBottomOf(root); if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && Conf['Bottom header']) { height = Header.bar.getBoundingClientRect().height; if (x <= 0) { if (!Header.isHidden()) { x += height; } } else { if (Header.isHidden()) { x -= height; } } } if (!(needed && x >= 0)) { return window.scrollBy(0, -x); } } else { x = Header.getTopOf(root); if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && !Conf['Bottom header']) { height = Header.bar.getBoundingClientRect().height; if (x >= 0) { if (!Header.isHidden()) { x += height; } } else { if (Header.isHidden()) { x -= height; } } } if (!(needed && x >= 0)) { return window.scrollBy(0, x); } } }, scrollToIfNeeded: function(root, down) { return Header.scrollTo(root, down, true); }, getTopOf: function(root) { var headRect, top; top = root.getBoundingClientRect().top; if (Conf['Fixed Header'] && !Conf['Bottom Header']) { headRect = Header.toggle.getBoundingClientRect(); top -= headRect.top + headRect.height; } return top; }, getBottomOf: function(root) { var bottom, clientHeight, headRect; clientHeight = doc.clientHeight; bottom = clientHeight - root.getBoundingClientRect().bottom; if (Conf['Fixed Header'] && Conf['Bottom Header']) { headRect = Header.toggle.getBoundingClientRect(); bottom -= clientHeight - headRect.bottom + headRect.height; } return bottom; }, isNodeVisible: function(node) { var height; if (d.hidden || !doc.contains(node)) { return false; } height = node.getBoundingClientRect().height; return Header.getTopOf(node) + height >= 0 && Header.getBottomOf(node) + height >= 0; }, isHidden: function() { var top; top = Header.bar.getBoundingClientRect().top; if (Conf['Bottom header']) { return top === doc.clientHeight; } else { return top < 0; } }, addShortcut: function(el) { var shortcut; shortcut = $.el('span', { className: 'shortcut brackets-wrap' }); $.add(shortcut, el); return $.prepend(Header.shortcuts, shortcut); }, rmShortcut: function(el) { return $.rm(el.parentElement); }, menuToggle: function(e) { return Header.menu.toggle(e, this, g); }, createNotification: function(e) { var content, lifetime, notice, ref, type; ref = e.detail, type = ref.type, content = ref.content, lifetime = ref.lifetime; return notice = new Notice(type, content, lifetime); }, 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: "4chan X needs your permission to show desktop notifications. [FAQ]
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); } }; Index = { showHiddenThreads: false, init: function() { var anchorEntry, input, k, label, len1, len2, name, pinEntry, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, refNavEntry, repliesEntry, select; if (g.BOARD.ID === 'f' || !Conf['JSON Navigation'] || g.VIEW !== 'index') { return; } this.board = "" + g.BOARD; CatalogThread.callbacks.push({ name: 'Catalog Features', cb: this.catalogNode }); this.search = ((ref = history.state) != null ? ref.searched : void 0) || ''; if ((ref1 = history.state) != null ? ref1.mode : void 0) { Conf['Index Mode'] = (ref2 = history.state) != null ? ref2.mode : void 0; } this.currentPage = this.getCurrentPage(); this.pushState({ command: (ref3 = location.href.match(/#(.*)/)) != null ? ref3[1] : void 0, replace: true }); this.button = $.el('a', { className: 'index-refresh-shortcut fa fa-refresh', title: 'Refresh', href: 'javascript:;', textContent: 'Refresh Index' }); $.on(this.button, 'click', function() { return Index.update(); }); Header.addShortcut(this.button, 1); repliesEntry = { el: UI.checkbox('Show Replies', 'Show replies') }; pinEntry = { el: UI.checkbox('Pin Watched Threads', 'Pin watched threads') }; anchorEntry = { el: UI.checkbox('Anchor Hidden Threads', 'Anchor hidden threads') }; refNavEntry = { el: UI.checkbox('Refreshed Navigation', 'Refreshed navigation') }; pinEntry.el.title = 'Move watched threads to the start of the index.'; anchorEntry.el.title = 'Move hidden threads to the end of the index.'; refNavEntry.el.title = 'Refresh index when navigating through pages.'; ref4 = [repliesEntry, pinEntry, anchorEntry, refNavEntry]; for (k = 0, len1 = ref4.length; k < len1; k++) { label = ref4[k]; input = label.el.firstChild; name = input.name; $.on(input, 'change', $.cb.checked); switch (name) { case 'Show Replies': $.on(input, 'change', this.cb.replies); break; case 'Pin Watched Threads': case 'Anchor Hidden Threads': $.on(input, 'change', this.cb.sort); } } Header.menu.addEntry({ el: $.el('span', { textContent: 'Index Navigation' }), order: 100, subEntries: [repliesEntry, pinEntry, anchorEntry, refNavEntry] }); $.addClass(doc, 'index-loading', (Conf['Index Mode'].replace(/\ /g, '-')) + "-mode"); this.root = $.el('div', { className: 'board' }); this.cb.size(); this.pagelist = $.el('div', { className: 'pagelist' }); $.extend(this.pagelist, { innerHTML: "
" }); $('.cataloglink a', this.pagelist).href = CatalogLinks.catalog(); this.navLinks = $.el('div', { className: 'navLinks' }); $.extend(this.navLinks, { innerHTML: "Index Catalog Archive Bottom ×" }); $('.cataloglink a', this.navLinks).href = CatalogLinks.catalog(); if ((ref5 = g.BOARD.ID) === 'b' || ref5 === 'trash') { $('.archlistlink', this.navLinks).hidden = true; } this.searchInput = $('#index-search', this.navLinks); this.setupSearch(); this.hideLabel = $('#hidden-label', this.navLinks); this.selectMode = $('#index-mode', this.navLinks); this.selectSort = $('#index-sort', this.navLinks); this.selectSize = $('#index-size', this.navLinks); $.on(window, 'popstate', this.cb.popstate); $.on(d, 'scroll', Index.scroll); $.on(this.pagelist, 'click', this.cb.pageNav); $.on(this.searchInput, 'input', this.onSearchInput); $.on($('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront); $.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch); $.on($('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads); $.on(this.selectMode, 'change', this.cb.mode); ref6 = [this.selectMode, this.selectSort, this.selectSize]; for (q = 0, len2 = ref6.length; q < len2; q++) { select = ref6[q]; select.value = Conf[select.name]; $.on(select, 'change', $.cb.value); } $.on(this.selectSort, 'change', this.cb.sort); $.on(this.selectSize, 'change', this.cb.size); this.update(); $.asap((function() { return $('title + *', doc) || d.readyState !== 'loading'; }), function() { return d.title = d.title.replace(/\ -\ Page\ \d+/, ''); }); $.asap((function() { return $('.board > .thread > .postContainer', doc) || d.readyState !== 'loading'; }), function() { var board, el, len3, len4, ref7, ref8, threadRoot, topNavPos, u, v; if (!Main.isThisPageLegit()) { return; } Index.hat = $('.board > .thread > img:first-child'); if (Index.hat) { if (Index.nodes) { ref7 = Index.nodes; for (u = 0, len3 = ref7.length; u < len3; u++) { threadRoot = ref7[u]; $.prepend(threadRoot, Index.hat.cloneNode(false)); } } $.addClass(doc, 'hats-enabled'); $.addStyle(".catalog-thread::after {background-image: url(" + Index.hat.src + ");}"); } board = $('.board'); $.replace(board, Index.root); $.event('PostsInserted'); d.implementation.createDocument(null, null, null).appendChild(board); ref8 = $$('.navLinks'); for (v = 0, len4 = ref8.length; v < len4; v++) { el = ref8[v]; $.rm(el); } $.rm($.id('ctrl-top')); topNavPos = $.id('delform').previousElementSibling; $.before(topNavPos, $.el('hr')); return $.before(topNavPos, Index.navLinks); }); return $.asap((function() { return $('.pagelist', doc) || d.readyState !== 'loading'; }), function() { var pagelist; if (!Main.isThisPageLegit()) { return; } if (pagelist = $('.pagelist')) { $.replace(pagelist, Index.pagelist); } else { $.after($.id('delform'), Index.pagelist); } return $.rmClass(doc, 'index-loading'); }); }, scroll: function() { var nodes, pageNum; if (Index.req || Conf['Index Mode'] !== 'infinite' || (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight))) { return; } if (Index.pageNum == null) { Index.pageNum = Index.getCurrentPage(); } pageNum = ++Index.pageNum; if (pageNum > Index.pagesNum) { return Index.endNotice(); } nodes = Index.buildSinglePage(pageNum); if (Conf['Show Replies']) { Index.buildReplies(nodes); } return Index.buildStructure(nodes); }, endNotice: (function() { var notify, reset; notify = false; reset = function() { return notify = false; }; return function() { if (notify) { return; } notify = true; new Notice('info', "Last page reached.", 2); return setTimeout(reset, 3 * $.SECOND); }; })(), menu: { init: function() { if (g.VIEW !== 'index' || !Conf['JSON Navigation'] || !Conf['Menu'] || !Conf['Thread Hiding Link'] || g.BOARD.ID === 'f') { return; } return Menu.menu.addEntry({ el: $.el('a', { href: 'javascript:;' }), order: 20, open: function(arg) { var thread; thread = arg.thread; if (Conf['Index Mode'] !== 'catalog') { return false; } this.el.textContent = thread.isHidden ? 'Unhide thread' : 'Hide thread'; if (this.cb) { $.off(this.el, 'click', this.cb); } this.cb = function() { $.event('CloseMenu'); return Index.toggleHide(thread); }; $.on(this.el, 'click', this.cb); return true; } }); } }, catalogNode: function() { return $.on(this.nodes.thumb.parentNode, 'click', Index.onClick); }, onClick: function(e) { var thread; if (e.button !== 0) { return; } thread = g.threads[this.parentNode.dataset.fullID]; if (e.shiftKey) { Index.toggleHide(thread); } else { return; } return e.preventDefault(); }, toggleHide: function(thread) { $.rm(thread.catalogView.nodes.root); if (Index.showHiddenThreads) { ThreadHiding.show(thread); if (!ThreadHiding.db.get({ boardID: thread.board.ID, threadID: thread.ID })) { return; } } else { ThreadHiding.hide(thread); } return ThreadHiding.saveHiddenState(thread); }, cycleSortType: function() { var i, k, len1, type, types; types = slice.call(Index.selectSort.options).filter(function(option) { return !option.disabled; }); for (i = k = 0, len1 = types.length; k < len1; i = ++k) { type = types[i]; if (type.selected) { break; } } types[(i + 1) % types.length].selected = true; return $.event('change', null, Index.selectSort); }, cb: { toggleHiddenThreads: function() { $('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ? 'Hide' : 'Show'; Index.sort(); return Index.buildIndex(); }, mode: function() { var mode; mode = this.value; if (mode !== 'catalog') { Conf['Previous Index Mode'] = mode; $.set('Previous Index Mode', mode); } return Index.pageLoad(Index.pushState({ mode: mode })); }, sort: function() { Index.sort(); return Index.buildIndex(); }, size: function(e) { if (Conf['Index Mode'] !== 'catalog') { $.rmClass(Index.root, 'catalog-small'); $.rmClass(Index.root, 'catalog-large'); } else if (Conf['Index Size'] === 'small') { $.addClass(Index.root, 'catalog-small'); $.rmClass(Index.root, 'catalog-large'); } else { $.addClass(Index.root, 'catalog-large'); $.rmClass(Index.root, 'catalog-small'); } if (e) { return Index.buildIndex(); } }, replies: function() { Index.buildThreads(); Index.sort(); return Index.buildIndex(); }, popstate: function(e) { var mode, page, ref, ref1, searched, state; if (e != null ? e.state : void 0) { ref = e.state, searched = ref.searched, mode = ref.mode; state = {}; if (Index.search !== searched) { state.search = Index.search = searched; } if (Conf['Index Mode'] !== mode) { state.mode = mode; Index.saveMode(mode); } page = Index.getCurrentPage(); if (Index.currentPage !== page) { state.page = Index.currentPage = page; } if ((state.search != null) || (state.mode != null) || (state.page != null)) { return Index.pageLoad(state); } } else { state = Index.pushState({ command: (ref1 = location.href.match(/#(.*)/)) != null ? ref1[1] : void 0, replace: true, scroll: true }); if (state.command) { return Index[Conf['Refreshed Navigation'] ? 'update' : 'pageLoad'](state); } } }, pageNav: function(e) { var a; if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } switch (e.target.nodeName) { case 'BUTTON': e.target.blur(); a = e.target.parentNode; break; case 'A': a = e.target; break; default: return; } if (a.textContent === 'Catalog') { return; } e.preventDefault(); return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); }, refreshFront: function() { return Index.update(Index.pushState({ page: 1, scroll: true })); } }, scrollToIndex: function() { return Header.scrollToIfNeeded(Index.navLinks); }, getCurrentPage: function() { var ref; if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { return 1; } else { return +window.location.pathname.split(/\/+/)[2] || 1; } }, userPageNav: function(page) { var state; state = Index.pushState({ page: page, scroll: true }); if (Conf['Refreshed Navigation']) { return Index.update(state); } else { if (state.page) { return Index.pageLoad(state); } } }, pushState: function(state) { var command, hash, mode, page, pageBeforeSearch, pathname, ref, search; pathname = location.pathname, hash = location.hash; pageBeforeSearch = (ref = history.state) != null ? ref.oldpage : void 0; if (state.command != null) { command = state.command; if (command === 'paged' || command === 'infinite' || command === 'all-pages' || command === 'catalog') { state.mode = command.replace(/-/g, ' '); } else if (command === 'index') { state.mode = Conf['Previous Index Mode']; state.page = 1; } else if (/^s=/.test(command)) { state.search = decodeURIComponent(command.slice(2)).replace(/\+/g, ' ').trim(); hash = ''; } else { delete state.command; } } if (state.search != null) { search = state.search; state.page = search ? 1 : pageBeforeSearch || 1; if (!search) { pageBeforeSearch = void 0; } else if (!Index.search) { pageBeforeSearch = Index.currentPage; } Index.search = search; } if (state.mode != null) { mode = state.mode; if (mode === Conf['Index Mode']) { delete state.mode; } Index.saveMode(mode); if (mode === 'all pages' || mode === 'catalog') { state.page = 1; } hash = ''; } if (state.page != null) { page = state.page; if (page === Index.currentPage) { delete state.page; } Index.currentPage = page; pathname = page === 1 ? "/" + g.BOARD + "/" : "/" + g.BOARD + "/" + page; hash = ''; } history[state.replace ? 'replaceState' : 'pushState']({ mode: Conf['Index Mode'], searched: Index.search, oldpage: pageBeforeSearch }, '', location.protocol + "//" + location.host + pathname + hash); return state; }, saveMode: function(mode) { if (Conf['Index Mode'] !== mode) { Conf['Index Mode'] = mode; $.set('Index Mode', mode); } if (!(mode === 'catalog' || Conf['Previous Index Mode'] === mode)) { Conf['Previous Index Mode'] = mode; return $.set('Previous Index Mode', mode); } }, pageLoad: function(arg) { var mode, scroll, search, sort; sort = arg.sort, search = arg.search, mode = arg.mode, scroll = arg.scroll; if (sort || (search != null)) { Index.sort(); Index.buildPagelist(); } if (search != null) { Index.setupSearch(); } if (mode != null) { Index.applyMode(); } Index.buildIndex(); Index.setPage(); if (scroll) { return Index.scrollToIndex(); } }, applyMode: function() { var k, len1, mode, ref; ref = ['paged', 'infinite', 'all pages', 'catalog']; for (k = 0, len1 = ref.length; k < len1; k++) { mode = ref[k]; $[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc, (mode.replace(/\ /g, '-')) + "-mode"); } Index.selectMode.value = Conf['Index Mode']; Index.cb.size(); Index.showHiddenThreads = false; return $('#hidden-toggle a', Index.navLinks).textContent = 'Show'; }, getPagesNum: function() { if (Index.search) { return Math.ceil(Index.sortedNodes.length / Index.threadsNumPerPage); } else { return Index.pagesNum; } }, getMaxPageNum: function() { return Math.max(1, Index.getPagesNum()); }, buildPagelist: function() { var a, i, k, maxPageNum, nodes, pagesRoot, ref; pagesRoot = $('.pages', Index.pagelist); maxPageNum = Index.getMaxPageNum(); if (pagesRoot.childElementCount !== maxPageNum) { nodes = []; for (i = k = 1, ref = maxPageNum; k <= ref; i = k += 1) { a = $.el('a', { textContent: i, href: i === 1 ? './' : i }); nodes.push($.tn('['), a, $.tn('] ')); } $.rmAll(pagesRoot); return $.add(pagesRoot, nodes); } }, setPage: function() { var a, href, maxPageNum, next, pageNum, pagesRoot, prev, strong; pageNum = Index.getCurrentPage(); maxPageNum = Index.getMaxPageNum(); pagesRoot = $('.pages', Index.pagelist); prev = pagesRoot.previousSibling.firstChild; next = pagesRoot.nextSibling.firstChild; href = Math.max(pageNum - 1, 1); prev.href = href === 1 ? './' : href; prev.firstChild.disabled = href === pageNum; href = Math.min(pageNum + 1, maxPageNum); next.href = href === 1 ? './' : href; next.firstChild.disabled = href === pageNum; if (strong = $('strong', pagesRoot)) { if (+strong.textContent === pageNum) { return; } $.replace(strong, strong.firstChild); } else { strong = $.el('strong'); } a = pagesRoot.children[pageNum - 1]; $.before(a, strong); return $.add(strong, a); }, updateHideLabel: function() { var hiddenCount, ref, ref1, thread, threadID; hiddenCount = 0; ref = g.BOARD.threads; for (threadID in ref) { thread = ref[threadID]; if (thread.isHidden) { if (ref1 = thread.ID, indexOf.call(Index.liveThreadIDs, ref1) >= 0) { hiddenCount++; } } } if (!hiddenCount) { Index.hideLabel.hidden = true; if (Index.showHiddenThreads) { Index.cb.toggleHiddenThreads(); } return; } Index.hideLabel.hidden = false; return $('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ? '1 hidden thread' : hiddenCount + " hidden threads"; }, update: function(state) { var now, ref, ref1; if ((ref = Index.req) != null) { ref.abort(); } if ((ref1 = Index.notice) != null) { ref1.close(); } if (Conf['Index Refresh Notifications'] && d.readyState !== 'loading') { Index.notice = new Notice('info', 'Refreshing index...'); } else { now = Date.now(); $.ready(function() { return Index.nTimeout = setTimeout((function() { if (Index.req && !Index.notice) { return Index.notice = new Notice('info', 'Refreshing index...'); } }), 3 * $.SECOND - (Date.now() - now)); }); } Index.req = $.ajax("//a.4cdn.org/" + g.BOARD + "/catalog.json", { onloadend: function(e) { return Index.load(e, state); } }, { whenModified: 'Index' }); return $.addClass(Index.button, 'fa-spin'); }, load: function(e, state) { var err, nTimeout, notice, ref, req, timeEl; $.rmClass(Index.button, 'fa-spin'); req = Index.req, notice = Index.notice, nTimeout = Index.nTimeout; if (nTimeout) { clearTimeout(nTimeout); } delete Index.nTimeout; delete Index.req; delete Index.notice; if (e.type === 'abort') { req.onloadend = null; notice.close(); return; } if ((ref = req.status) !== 200 && ref !== 304) { err = "Index refresh failed. Error " + req.statusText + " (" + req.status + ")"; if (notice) { notice.setType('warning'); notice.el.lastElementChild.textContent = err; setTimeout(notice.close, $.SECOND); } else { new Notice('warning', err, 1); } return; } try { if (req.status === 200) { Index.parse(req.response, state); } else if (req.status === 304 && (state != null)) { Index.pageLoad(state); } } catch (_error) { err = _error; c.error("Index failure: " + err.message, err.stack); if (notice) { notice.setType('error'); notice.el.lastElementChild.textContent = 'Index refresh failed.'; setTimeout(notice.close, $.SECOND); } else { new Notice('error', 'Index refresh failed.', 1); } return; } if (notice) { if (Conf['Index Refresh Notifications']) { notice.setType('success'); notice.el.lastElementChild.textContent = 'Index refreshed!'; setTimeout(notice.close, $.SECOND); } else { notice.close(); } } timeEl = $('#index-last-refresh time', Index.navLinks); timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified')); RelativeDates.update(timeEl); return Index.scrollToIndex(); }, parse: function(pages, state) { $.cleanCache(function(url) { return /^\/\/a\.4cdn\.org\//.test(url); }); Index.parseThreadList(pages); Index.buildThreads(); state || (state = {}); state.sort = true; return Index.pageLoad(state); }, parseThreadList: function(pages) { Index.pagesNum = pages.length; Index.threadsNumPerPage = pages[0].threads.length; Index.liveThreadData = pages.reduce((function(arr, next) { return arr.concat(next.threads); }), []); Index.liveThreadIDs = Index.liveThreadData.map(function(data) { return data.no; }); g.BOARD.threads.forEach(function(thread) { var ref; if (ref = thread.ID, indexOf.call(Index.liveThreadIDs, ref) < 0) { return thread.collect(); } }); }, buildThreads: function() { var err, errors, i, k, len1, posts, ref, thread, threadData, threadRoot, threads; Index.nodes = []; threads = []; posts = []; ref = Index.liveThreadData; for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { threadData = ref[i]; try { threadRoot = Build.thread(g.BOARD, threadData); if (Index.hat) { $.prepend(threadRoot, Index.hat.cloneNode(false)); } if (thread = g.BOARD.threads[threadData.no]) { thread.setCount('post', threadData.replies + 1, threadData.bumplimit); thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit); thread.setStatus('Sticky', !!threadData.sticky); thread.setStatus('Closed', !!threadData.closed); } else { thread = new Thread(threadData.no, g.BOARD); threads.push(thread); } Index.nodes.push(threadRoot); if (!(thread.OP && !thread.OP.isFetchedQuote)) { posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD)); } thread.setPage(Math.floor(i / Index.threadsNumPerPage) + 1); } catch (_error) { err = _error; if (!errors) { errors = []; } errors.push({ message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.", error: err }); } } if (errors) { Main.handleErrors(errors); } $.nodes(Index.nodes); Main.callbackNodes(Thread, threads); Main.callbackNodes(Post, posts); Index.updateHideLabel(); return $.event('IndexRefresh'); }, buildReplies: function(threadRoots) { var data, err, errors, i, k, lastReplies, len1, len2, node, nodes, post, posts, q, thread, threadRoot; posts = []; for (k = 0, len1 = threadRoots.length; k < len1; k++) { threadRoot = threadRoots[k]; thread = Get.threadFromRoot(threadRoot); i = Index.liveThreadIDs.indexOf(thread.ID); if (!(lastReplies = Index.liveThreadData[i].last_replies)) { continue; } nodes = []; for (q = 0, len2 = lastReplies.length; q < len2; q++) { data = lastReplies[q]; if ((post = thread.posts[data.no]) && !post.isFetchedQuote) { nodes.push(post.nodes.root); continue; } nodes.push(node = Build.postFromObject(data, thread.board.ID)); try { posts.push(new Post(node, thread, thread.board)); } catch (_error) { err = _error; if (!errors) { errors = []; } errors.push({ message: "Parsing of Post No." + data.no + " failed. Post will be skipped.", error: err }); } } $.add(threadRoot, nodes); } if (errors) { Main.handleErrors(errors); } return Main.callbackNodes(Post, posts); }, buildCatalogViews: function() { var catalogThreads, k, len1, thread, threads; threads = Index.sortedNodes.map(function(threadRoot) { return Get.threadFromRoot(threadRoot); }).filter(function(thread) { return !thread.isHidden !== Index.showHiddenThreads; }); catalogThreads = []; for (k = 0, len1 = threads.length; k < len1; k++) { thread = threads[k]; if (!thread.catalogView) { catalogThreads.push(new CatalogThread(Build.catalogThread(thread), thread)); } } Main.callbackNodes(CatalogThread, catalogThreads); return threads.map(function(thread) { return thread.catalogView.nodes.root; }); }, sizeCatalogViews: function(nodes) { var height, k, len1, node, ratio, ref, size, thumb, width; size = Conf['Index Size'] === 'small' ? 150 : 250; for (k = 0, len1 = nodes.length; k < len1; k++) { node = nodes[k]; thumb = $('.catalog-thumb', node); ref = thumb.dataset, width = ref.width, height = ref.height; if (!width) { continue; } ratio = size / Math.max(width, height); thumb.style.width = width * ratio + 'px'; thumb.style.height = height * ratio + 'px'; } }, sort: function() { var k, len1, liveThreadData, liveThreadIDs, nodes, sortedNodes, sortedThreadIDs, threadID; liveThreadIDs = Index.liveThreadIDs, liveThreadData = Index.liveThreadData; sortedThreadIDs = { lastreply: slice.call(liveThreadData).sort(function(a, b) { var num; if ((num = a.last_replies)) { a = num[num.length - 1]; } if ((num = b.last_replies)) { b = num[num.length - 1]; } return b.no - a.no; }).map(function(post) { return post.no; }), bump: liveThreadIDs, birth: slice.call(liveThreadIDs).sort(function(a, b) { return b - a; }), replycount: slice.call(liveThreadData).sort(function(a, b) { return b.replies - a.replies; }).map(function(post) { return post.no; }), filecount: slice.call(liveThreadData).sort(function(a, b) { return b.images - a.images; }).map(function(post) { return post.no; }) }[Conf['Index Sort']]; Index.sortedNodes = sortedNodes = []; nodes = Index.nodes; for (k = 0, len1 = sortedThreadIDs.length; k < len1; k++) { threadID = sortedThreadIDs[k]; sortedNodes.push(nodes[Index.liveThreadIDs.indexOf(threadID)]); } if (Index.search && (nodes = Index.querySearch(Index.search))) { Index.sortedNodes = nodes; } Index.sortOnTop(function(thread) { return thread.isSticky; }); Index.sortOnTop(function(thread) { return thread.isOnTop || Conf['Pin Watched Threads'] && ThreadWatcher.isWatched(thread); }); if (Conf['Anchor Hidden Threads']) { return Index.sortOnTop(function(thread) { return !thread.isHidden; }); } }, sortOnTop: function(match) { var bottomNodes, k, len1, ref, threadRoot, topNodes; topNodes = []; bottomNodes = []; ref = Index.sortedNodes; for (k = 0, len1 = ref.length; k < len1; k++) { threadRoot = ref[k]; (match(Get.threadFromRoot(threadRoot)) ? topNodes : bottomNodes).push(threadRoot); } return Index.sortedNodes = topNodes.concat(bottomNodes); }, buildIndex: function() { var i, nodes, page, post; switch (Conf['Index Mode']) { case 'all pages': nodes = Index.sortedNodes; break; case 'catalog': nodes = Index.buildCatalogViews(); Index.sizeCatalogViews(nodes); break; default: if (Index.followedThreadID != null) { i = 0; while (Index.followedThreadID !== Get.threadFromRoot(Index.sortedNodes[i]).ID) { i++; } page = Math.floor(i / Index.threadsNumPerPage) + 1; if (page !== Index.getCurrentPage()) { Index.pushState({ page: page }); Index.setPage(); } } nodes = Index.buildSinglePage(Index.getCurrentPage()); } delete Index.pageNum; $.rmAll(Index.root); $.rmAll(Header.hover); if (Conf['Index Mode'] === 'catalog') { return $.add(Index.root, nodes); } else { if (Conf['Show Replies']) { Index.buildReplies(nodes); } Index.buildStructure(nodes); if ((Index.followedThreadID != null) && (post = g.posts[g.BOARD + "." + Index.followedThreadID])) { return Header.scrollTo(post.nodes.root); } } }, buildSinglePage: function(pageNum) { var nodesPerPage, offset; nodesPerPage = Index.threadsNumPerPage; offset = nodesPerPage * (pageNum - 1); return Index.sortedNodes.slice(offset, offset + nodesPerPage); }, buildStructure: function(nodes) { var k, len1, node, thumb; for (k = 0, len1 = nodes.length; k < len1; k++) { node = nodes[k]; if (thumb = $('img[data-src]', node)) { thumb.src = thumb.dataset.src; thumb.removeAttribute('data-src'); } $.add(Index.root, [node, $.el('hr')]); } if (doc.contains(Index.root)) { $.event('PostsInserted'); } return ThreadHiding.onIndexBuild(nodes); }, clearSearch: function() { Index.searchInput.value = ''; Index.onSearchInput(); return Index.searchInput.focus(); }, setupSearch: function(noUpdate) { if (!noUpdate) { Index.searchInput.value = Index.search; } if (Index.search) { return Index.searchInput.dataset.searching = 1; } else { return Index.searchInput.removeAttribute('data-searching'); } }, onSearchInput: function() { var search; search = Index.searchInput.value.trim(); if (search === Index.search) { return; } return Index.pageLoad(Index.pushState({ search: search, replace: !!search === !!Index.search })); }, querySearch: function(query) { var keywords; if (!(keywords = query.toLowerCase().match(/\S+/g))) { return; } return Index.sortedNodes.filter(function(threadRoot) { return Index.searchMatch(Get.threadFromRoot(threadRoot), keywords); }); }, searchMatch: function(thread, keywords) { var file, info, k, key, keyword, len1, len2, q, ref, ref1, text; ref = thread.OP, info = ref.info, file = ref.file; text = []; ref1 = ['comment', 'subject', 'name', 'tripcode', 'email']; for (k = 0, len1 = ref1.length; k < len1; k++) { key = ref1[k]; if (key in info) { text.push(info[key]); } } if (file) { text.push(file.name); } text = text.join(' ').toLowerCase(); for (q = 0, len2 = keywords.length; q < len2; q++) { keyword = keywords[q]; if (-1 === text.indexOf(keyword)) { return false; } } return true; } }; Build = { staticPath: '//s.4cdn.org/image/', gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', spoilerRange: {}, unescape: function(text) { if (text == null) { return text; } return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { return { '&': '&', ''': "'", '"': '"', '<': '<', '>': '>', ',': ',' }[c]; }); }, shortFilename: function(filename) { var ext, threshold; threshold = 30; ext = filename.match(/\.?[^\.]*$/)[0]; if (filename.length - ext.length > threshold) { return filename.slice(0, threshold - 5) + "(...)" + ext; } else { return filename; } }, spoilerThumb: function(boardID) { var spoilerRange; if (spoilerRange = Build.spoilerRange[boardID]) { return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; } else { return Build.staticPath + "spoiler.png"; } }, sameThread: function(boardID, threadID) { return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; }, postURL: function(boardID, threadID, postID) { if (Build.sameThread(boardID, threadID)) { return "#p" + postID; } else { return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, parseJSON: function(data, boardID) { var o; o = { postID: data.no, threadID: data.resto || data.no, boardID: boardID, isReply: !!data.resto, isSticky: !!data.sticky, isClosed: !!data.closed, isArchived: !!data.archived, fileDeleted: !!data.filedeleted }; o.info = { subject: Build.unescape(data.sub), email: Build.unescape(data.email), name: Build.unescape(data.name) || '', tripcode: data.trip, uniqueID: data.id, flagCode: data.country, flag: Build.unescape(data.country_name), dateUTC: data.time, dateText: data.now, commentHTML: { innerHTML: data.com || '' } }; if (data.capcode) { o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { return c.toUpperCase(); }); o.capcodeHighlight = /_highlight$/.test(data.capcode); delete o.info.uniqueID; } if (data.ext) { o.file = { name: (Build.unescape(data.filename)) + data.ext, url: boardID === 'f' ? location.protocol + "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, height: data.h, width: data.w, MD5: data.md5, size: $.bytesToString(data.fsize), thumbURL: location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", theight: data.tn_h, twidth: data.tn_w, isSpoiler: !!data.spoiler, tag: data.tag }; if (!/\.pdf$/.test(o.file.url)) { o.file.dimensions = o.file.width + "x" + o.file.height; } } return o; }, parseComment: function(o) { var html; html = o.info.commentHTML.innerHTML.replace(//gi, '\n').replace(/\n\nRolled [^<]*<\/b>/i, '').replace(/]*>/g, ''); return o.info.comment = Build.unescape(html); }, postFromObject: function(data, boardID, suppressThumb) { var o; o = Build.parseJSON(data, boardID); return Build.post(o, suppressThumb); }, post: function(o, suppressThumb) { var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, commentHTML, container, dateText, dateUTC, email, file, fileBlock, fileThumb, fileURL, flag, flagCode, gifIcon, href, k, len1, match, name, postClass, postID, postInfo, postLink, protocol, quote, quoteLink, ref, ref1, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; postID = o.postID, threadID = o.threadID, boardID = o.boardID, file = o.file; ref = o.info, subject = ref.subject, email = ref.email, name = ref.name, tripcode = ref.tripcode, capcode = ref.capcode, uniqueID = ref.uniqueID, flagCode = ref.flagCode, flag = ref.flag, dateUTC = ref.dateUTC, dateText = ref.dateText, commentHTML = ref.commentHTML; staticPath = Build.staticPath, gifIcon = Build.gifIcon; /* Post Info */ if (capcode) { capcodeLC = capcode.toLowerCase(); if (capcode === 'Founder') { capcodePlural = 'the Founder'; capcodeDescription = "4chan's Founder"; } else { capcodeLong = { 'Admin': 'Administrator', 'Mod': 'Moderator' }[capcode] || capcode; capcodePlural = capcodeLong + "s"; capcodeDescription = "a 4chan " + capcodeLong; } } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; postInfo = { innerHTML: "
" + (!o.isReply || boardID === "f" || subject ? "" + E(subject || "") + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcode) + "" : "") + (email ? "" : "") + (boardID === "f" && !o.isReply || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(dateText) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (!o.isReply && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ if (file) { protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; fileURL = file.url.replace(protocol, ''); shortFilename = Build.shortFilename(file.name); fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); } fileBlock = { innerHTML: (file ? "
" + (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + (file.tag ? ", " + E(file.tag) : "") + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
") + "
" : (o.fileDeleted ? "
\"File
" : "")) }; /* Whole Post */ postClass = o.isReply ? 'reply' : 'op'; wholePost = { innerHTML: (o.isReply ? "
>>
" : "") + "
" + (o.isReply ? postInfo.innerHTML + fileBlock.innerHTML : fileBlock.innerHTML + postInfo.innerHTML) + "
" + commentHTML.innerHTML + "
" }; container = $.el('div', { className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); ref1 = $$('.quotelink', container); for (k = 0, len1 = ref1.length; k < len1; k++) { quote = ref1[k]; href = quote.getAttribute('href'); if ((href[0] === '#') && !(Build.sameThread(boardID, threadID))) { quote.href = ("/" + boardID + "/thread/" + threadID) + href; } else if ((match = href.match(/^\/([^\/]+)\/thread\/(\d+)/)) && (Build.sameThread(match[1], match[2]))) { quote.href = href.match(/(#[^#]*)?$/)[0] || '#'; } else if (/^\d+(#|$)/.test(href) && !(g.VIEW === 'thread' && g.BOARD.ID === boardID)) { quote.href = "/" + boardID + "/thread/" + href; } } return container; }, summary: function(boardID, threadID, posts, files) { var text; text = []; text.push(posts + " post" + (posts > 1 ? 's' : '')); if (files) { text.push("and " + files + " image repl" + (files > 1 ? 'ies' : 'y')); } text.push('omitted.'); return $.el('a', { className: 'summary', textContent: text.join(' '), href: "/" + boardID + "/thread/" + threadID }); }, thread: function(board, data, full) { var OP, root; Build.spoilerRange[board] = data.custom_spoiler; if (OP = board.posts[data.no]) { if (OP.isFetchedQuote) { OP = null; } } if (OP && (root = OP.nodes.root.parentNode)) { $.rmAll(root); } else { root = $.el('div', { className: 'thread', id: "t" + data.no }); } $.add(root, Build[full ? 'fullThread' : 'excerptThread'](board, data, OP)); return root; }, excerptThread: function(board, data, OP) { var files, nodes, posts, ref; nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID, true)]; if (data.omitted_posts || !Conf['Show Replies'] && data.replies) { ref = Conf['Show Replies'] ? [ data.omitted_posts, data.images - data.last_replies.filter(function(data) { return !!data.ext; }).length ] : [data.replies, data.images], posts = ref[0], files = ref[1]; nodes.push(Build.summary(board.ID, data.no, posts, files)); } return nodes; }, fullThread: function(board, data) { return Build.postFromObject(data, board.ID); }, catalogThread: function(thread) { var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, u, v; staticPath = Build.staticPath, gifIcon = Build.gifIcon; data = Index.liveThreadData[Index.liveThreadIDs.indexOf(thread.ID)]; if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { src = staticPath + "spoiler"; if (spoilerRange = Build.spoilerRange[thread.board]) { src += ("-" + thread.board) + Math.floor(1 + spoilerRange * Math.random()); } src += '.png'; imgClass = 'spoiler-file'; } else if (data.filedeleted) { src = staticPath + "filedeleted-res" + gifIcon; imgClass = 'deleted-file'; } else if (thread.OP.file) { src = thread.OP.file.thumbURL; } else { src = staticPath + "nofile.png"; imgClass = 'no-file'; } postCount = data.replies + 1; fileCount = data.images + !!data.ext; pageCount = Math.floor(Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage) + 1; comment = { innerHTML: data.com || '' }; root = $.el('div', { className: 'catalog-thread' }); $.extend(root, { innerHTML: "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + (thread.OP.info.subject ? "
" + E(thread.OP.info.subject) + "
" : "") + "
" + comment.innerHTML + "
" }); root.dataset.fullID = thread.fullID; if (thread.OP.highlights) { $.addClass.apply($, [root].concat(slice.call(thread.OP.highlights))); } ref = $$('.quotelink', root.lastElementChild); for (k = 0, len1 = ref.length; k < len1; k++) { quote = ref[k]; href = quote.getAttribute('href'); if (href[0] === '#') { quote.href = ("/" + thread.board + "/thread/" + thread.ID) + href; } } ref1 = $$('.abbr, .exif', root.lastElementChild); for (q = 0, len2 = ref1.length; q < len2; q++) { exif = ref1[q]; $.rm(exif); } ref2 = $$('.prettyprint', root.lastElementChild); for (u = 0, len3 = ref2.length; u < len3; u++) { pp = ref2[u]; cc = $.el('span', { className: 'catalog-code' }); $.add(cc, slice.call(pp.childNodes)); $.replace(pp, cc); } ref3 = $$('br', root.lastElementChild); for (v = 0, len4 = ref3.length; v < len4; v++) { br = ref3[v]; if (((ref4 = br.previousSibling) != null ? ref4.nodeName : void 0) === 'BR') { $.rm(br); } } if (thread.isSticky) { $.add($('.catalog-icons', root), $.el('img', { src: staticPath + "sticky" + gifIcon, className: 'stickyIcon', title: 'Sticky' })); } if (thread.isClosed) { $.add($('.catalog-icons', root), $.el('img', { src: staticPath + "closed" + gifIcon, className: 'closedIcon', title: 'Closed' })); } if (data.bumplimit) { $.addClass($('.post-count', root), 'warning'); } if (data.imagelimit) { $.addClass($('.file-count', root), 'warning'); } return root; } }; Get = { threadExcerpt: function(thread) { var OP, excerpt, ref; OP = thread.OP; excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.commentDisplay.replace(/\n+/g, ' // ') || OP.info.nameBlock); if (excerpt.length > 73) { return excerpt.slice(0, 70) + "..."; } return 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; if (root == null) { return null; } link = $('.postNum > a[href*="#"]', 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, ref, threadID; 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 fullID, handleQuotes, k, len1, posts, qPost, quote, quotelinks, ref; quotelinks = []; posts = g.posts; fullID = post.fullID; handleQuotes = function(qPost, type) { var clone, k, len1, ref; quotelinks.push.apply(quotelinks, qPost.nodes[type]); ref = qPost.clones; for (k = 0, len1 = ref.length; k < len1; k++) { clone = ref[k]; quotelinks.push.apply(quotelinks, clone.nodes[type]); } }; posts.forEach(function(qPost) { if (indexOf.call(qPost.quotes, fullID) >= 0) { return handleQuotes(qPost, 'quotelinks'); } }); if (Conf['Quote Backlinks']) { ref = post.quotes; for (k = 0, len1 = ref.length; k < len1; k++) { quote = ref[k]; if (qPost = posts[quote]) { handleQuotes(qPost, 'backlinks'); } } } return quotelinks.filter(function(quotelink) { var boardID, postID, ref1; ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; return boardID === post.board.ID && postID === post.ID; }); }, scriptData: function() { var k, len1, ref, script; ref = $$('script:not([src])', d.head); for (k = 0, len1 = ref.length; k < len1; k++) { script = ref[k]; if (/\bcooldowns *=/.test(script.textContent)) { return script.textContent; } } return ''; } }; UI = (function() { var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; dialog = function(id, position, properties) { var child, el, k, len1, move, ref; el = $.el('div', { className: 'dialog', id: id }); $.extend(el, properties); 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 (k = 0, len1 = ref.length; k < len1; k++) { child = ref[k]; 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(type1) { this.type = type1; this.addEntry = bind(this.addEntry, this); this.onFocus = bind(this.onFocus, this); this.keybinds = bind(this.keybinds, this); this.close = bind(this.close, this); $.on(d, 'AddMenuEntry', (function(_this) { return function(arg) { var detail; detail = arg.detail; if (detail.type !== _this.type) { return; } delete detail.open; return _this.addEntry(detail); }; })(this)); 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; currentMenu.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, k, left, len1, mRect, menu, ref, ref1, ref2, right, style, top; menu = this.menu = this.makeMenu(); currentMenu = this; lastToggledButton = button; this.entries.sort(function(first, second) { return first.order - second.order; }); ref = this.entries; for (k = 0, len1 = ref.length; k < len1; k++) { entry = ref[k]; this.insertEntry(entry, menu, data); } $.addClass(lastToggledButton, 'active'); $.on(d, 'click CloseMenu', this.close); if (this.type !== 'gallery') { $.on(d, 'scroll', this.close); } $.add(button, 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 err, k, len1, ref, subEntry, submenu; if (typeof entry.open === 'function') { try { if (!entry.open(data)) { return; } } catch (_error) { err = _error; Main.handleErrors({ message: "Error in building the " + this.type + " menu.", error: err }); 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 (k = 0, len1 = ref.length; k < len1; k++) { subEntry = ref[k]; this.insertEntry(subEntry, submenu, data); } $.add(entry.el, submenu); }; Menu.prototype.close = function() { $.rm(this.menu); delete this.menu; $.rmClass(lastToggledButton, 'active'); currentMenu = null; lastToggledButton = null; return $.off(d, 'click scroll 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 - second.style.order; }); return entries[entries.indexOf(entry) + direction]; }; Menu.prototype.keybinds = function(e) { var entry, next, nextPrev, subEntry, submenu; entry = $('.focused', this.menu); 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.onFocus = function(e) { e.stopPropagation(); return this.focus(e.target); }; Menu.prototype.focus = function(entry) { var bottom, cHeight, cWidth, eRect, focused, k, left, len1, ref, ref1, ref2, right, sRect, style, submenu, top; while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { $.rmClass(focused, 'focused'); } ref = $$('.focused', entry); for (k = 0, len1 = ref.length; k < len1; k++) { focused = ref[k]; $.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 - 150 ? ['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(entry) { this.parseEntry(entry); return this.entries.push(entry); }; Menu.prototype.parseEntry = function(entry) { var el, k, len1, subEntries, subEntry; el = entry.el, subEntries = entry.subEntries; $.addClass(el, 'entry'); $.on(el, 'focus mouseover', this.onFocus); el.style.order = entry.order || 100; if (!subEntries) { return; } $.addClass(el, 'has-submenu'); for (k = 0, len1 = subEntries.length; k < len1; k++) { subEntry = subEntries[k]; this.parseEntry(subEntry); } }; return Menu; })(); dragstart = function(e) { var el, isTouching, o, rect, ref, screenHeight, screenWidth; 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 k, len1, ref, touch; ref = e.changedTouches; for (k = 0, len1 = ref.length; k < len1; k++) { touch = ref[k]; 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 k, len1, ref, touch; ref = e.changedTouches; for (k = 0, len1 = ref.length; k < len1; k++) { touch = ref[k]; 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, height, latestEvent, noRemove, o, ref, root; root = arg.root, el = arg.el, latestEvent = arg.latestEvent, endEvents = arg.endEvents, asapTest = arg.asapTest, height = arg.height, cb = arg.cb, noRemove = arg.noRemove; o = { root: root, el: el, style: el.style, isImage: (ref = el.nodeName) === 'IMG' || ref === 'VIDEO', cb: cb, endEvents: endEvents, latestEvent: latestEvent, clientHeight: doc.clientHeight, clientWidth: doc.clientWidth, height: height, noRemove: noRemove }; 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(e); } }; return $.on(doc, 'mousemove', o.workaround); }; hover = function(e) { var clientX, clientY, height, left, ref, right, style, threshold, top; this.latestEvent = e; height = this.height || this.el.offsetHeight; clientX = e.clientX, clientY = e.clientY; top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120)); threshold = this.clientWidth / 2; if (!this.isImage) { threshold = Math.max(threshold, this.clientWidth - 400); } ref = clientX <= threshold ? [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; } if (!this.noRemove) { $.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); } }; checkbox = function(name, text, checked) { var input, label; if (checked == null) { checked = Conf[name]; } label = $.el('label'); input = $.el('input', { type: 'checkbox', name: name, checked: checked }); $.add(label, [input, $.tn(" " + text)]); return label; }; return { dialog: dialog, Menu: Menu, hover: hoverstart, checkbox: checkbox }; })(); CrossOrigin = (function() { return { binary: function(url, cb, headers) { var options, ref, workaround; if (headers == null) { headers = {}; } workaround = $.engine === 'gecko' && (typeof GM_info !== "undefined" && GM_info !== null) && /^[0-2]\.|^3\.[01](?!\d)/.test(GM_info.version); workaround || (workaround = /PaleMoon\//.test(navigator.userAgent)); workaround || (workaround = (typeof GM_info !== "undefined" && GM_info !== null ? (ref = GM_info.script) != null ? ref.includeJSB : void 0 : void 0) != null); options = { method: "GET", url: url, headers: headers, onload: function(xhr) { var contentDisposition, contentType, data, i, r, ref1, ref2; if (workaround) { r = xhr.responseText; data = new Uint8Array(r.length); i = 0; while (i < r.length) { data[i] = r.charCodeAt(i); i++; } } else { data = new Uint8Array(xhr.response); } if (typeof xhr.responseHeaders === 'object') { contentType = xhr.responseHeaders['Content-Type']; contentDisposition = xhr.responseHeaders['Content-Disposition']; } else { contentType = (ref1 = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)) != null ? ref1[1] : void 0; contentDisposition = (ref2 = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)) != null ? ref2[1] : void 0; } return cb(data, contentType, contentDisposition); }, onerror: function() { return cb(null); }, onabort: function() { return cb(null); } }; if (workaround) { options.overrideMimeType = options.mimeType = 'text/plain; charset=x-user-defined'; } else { options.responseType = 'arraybuffer'; } return GM_xmlhttpRequest(options); }, file: function(url, cb) { return CrossOrigin.binary(url, function(data, contentType, contentDisposition) { var blob, match, mime, name, ref, ref1, ref2, ref3; if (data == null) { return cb(null); } name = (ref = url.match(/([^\/]+)\/*$/)) != null ? ref[1] : void 0; mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream'; match = (contentDisposition != null ? (ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref1[1] : void 0 : void 0) || (contentType != null ? (ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref2[1] : void 0 : void 0); if (match) { name = match.replace(/\\"/g, '"'); } if ((typeof GM_info !== "undefined" && GM_info !== null ? (ref3 = GM_info.script) != null ? ref3.includeJSB : void 0 : void 0) != null) { mime = QR.typeFromExtension[name.match(/[^.]*$/)[0].toLowerCase()] || 'application/octet-stream'; } blob = new Blob([data], { type: mime }); blob.name = name; return cb(blob); }); }, json: (function() { var callbacks, responses; callbacks = {}; responses = {}; return function(url, cb) { if (responses[url]) { cb(responses[url]); return; } if (callbacks[url]) { callbacks[url].push(cb); return; } callbacks[url] = [cb]; return GM_xmlhttpRequest({ method: "GET", url: url + '', onload: function(xhr) { var k, len1, ref, response; response = JSON.parse(xhr.responseText); ref = callbacks[url]; for (k = 0, len1 = ref.length; k < len1; k++) { cb = ref[k]; cb(response); } delete callbacks[url]; return responses[url] = response; }, onerror: function() { return delete callbacks[url]; }, onabort: function() { return delete callbacks[url]; } }); }; })() }; })(); Anonymize = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Anonymize'])) { return; } if (g.VIEW === 'archive') { return this.archive(); } return Post.callbacks.push({ name: 'Anonymize', cb: this.node }); }, node: function() { var email, name, ref, tripcode; 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) { $.replace(email, name); return delete this.nodes.email; } }, archive: function() { return $.ready(function() { var k, len1, len2, name, q, ref, ref1, trip; ref = $$('.name'); for (k = 0, len1 = ref.length; k < len1; k++) { name = ref[k]; name.textContent = 'Anonymous'; } ref1 = $$('.postertrip'); for (q = 0, len2 = ref1.length; q < len2; q++) { trip = ref1[q]; $.rm(trip); } }); } }; Filter = { filters: {}, init: function() { var boards, err, filter, hl, k, key, len1, line, op, ref, ref1, ref2, ref3, ref4, ref5, regexp, stub, top; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Filter'])) { return; } if (!Conf['Filtered Backlinks']) { $.addClass(doc, 'hide-backlinks'); } for (key in Config.filter) { this.filters[key] = []; ref1 = Conf[key].split('\n'); for (k = 0, len1 = ref1.length; k < len1; k++) { line = ref1[k]; if (line[0] === '#') { continue; } if (!(regexp = line.match(/\/(.+)\/(\w*)/))) { continue; } filter = line.replace(regexp[0], ''); boards = ((ref2 = filter.match(/boards:([^;]+)/)) != null ? ref2[1].toLowerCase() : void 0) || 'global'; boards = boards === 'global' ? null : boards.split(','); if (key === 'uniqueID' || key === 'MD5') { regexp = regexp[1]; } else { try { regexp = RegExp(regexp[1], regexp[2]); } catch (_error) { err = _error; new Notice('warning', [$.tn("Invalid " + key + " filter:"), $.el('br'), $.tn(line), $.el('br'), $.tn(err.message)], 60); continue; } } op = ((ref3 = filter.match(/[^t]op:(yes|no|only)/)) != null ? ref3[1] : void 0) || 'yes'; stub = (function() { var ref4; switch ((ref4 = filter.match(/stub:(yes|no)/)) != null ? ref4[1] : void 0) { case 'yes': return true; case 'no': return false; default: return Conf['Stubs']; } })(); if (hl = /highlight/.test(filter)) { hl = ((ref4 = filter.match(/highlight:([\w-]+)/)) != null ? ref4[1] : void 0) || 'filter-highlight'; top = ((ref5 = filter.match(/top:(yes|no)/)) != null ? ref5[1] : void 0) || 'yes'; top = top === 'yes'; } this.filters[key].push(this.createFilter(regexp, boards, op, stub, hl, top)); } if (!this.filters[key].length) { delete this.filters[key]; } } if (!Object.keys(this.filters).length) { return; } return Post.callbacks.push({ name: 'Filter', cb: this.node }); }, createFilter: function(regexp, boards, 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, boardID, isReply) { if (boards && indexOf.call(boards, boardID) < 0) { return false; } if (isReply && op === 'only' || !isReply && op === 'no') { return false; } if (!test(value)) { return false; } return settings; }; }, node: function() { var filter, k, key, len1, ref, ref1, result, value; if (this.isClone) { return; } for (key in Filter.filters) { if ((value = Filter[key](this)) != null) { ref = Filter.filters[key]; for (k = 0, len1 = ref.length; k < len1; k++) { filter = ref[k]; if (!(result = filter(value, this.board.ID, this.isReply))) { continue; } if (result.hide && !this.isFetchedQuote) { 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.highlights && (ref1 = result["class"], indexOf.call(this.highlights, ref1) >= 0))) { (this.highlights || (this.highlights = [])).push(result["class"]); } if (!this.isReply && result.top) { this.thread.isOnTop = true; } } } } }, isHidden: function(post) { var filter, k, key, len1, ref, result, value; for (key in Filter.filters) { if ((value = Filter[key](post)) != null) { ref = Filter.filters[key]; for (k = 0, len1 = ref.length; k < len1; k++) { filter = ref[k]; if (result = filter(value, post.boardID, post.isReply)) { if (result.hide) { return true; } } } } } return false; }, postID: function(post) { var ref; return "" + ((ref = post.ID) != null ? ref : post.postID); }, name: function(post) { return post.info.name; }, uniqueID: function(post) { return post.info.uniqueID; }, tripcode: function(post) { return post.info.tripcode; }, capcode: function(post) { return post.info.capcode; }, subject: function(post) { return post.info.subject; }, comment: function(post) { var ref; return (ref = post.info.comment) != null ? ref : Build.parseComment(post); }, flag: function(post) { return post.info.flag; }, filename: function(post) { var ref; return (ref = post.file) != null ? ref.name : void 0; }, dimensions: function(post) { var ref; return (ref = post.file) != null ? ref.dimensions : void 0; }, filesize: function(post) { var ref; return (ref = post.file) != null ? ref.size : void 0; }, MD5: function(post) { var ref; return (ref = post.file) != null ? ref.MD5 : void 0; }, menu: { init: function() { var div, entry, k, len1, ref, ref1, type; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Filter'])) { return; } div = $.el('div', { textContent: 'Filter' }); entry = { el: div, order: 50, open: function(post) { Filter.menu.post = post; return true; }, subEntries: [] }; ref1 = [['Name', 'name'], ['Unique ID', 'uniqueID'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Comment', 'comment'], ['Flag', 'flag'], ['Filename', 'filename'], ['Image dimensions', 'dimensions'], ['Filesize', 'filesize'], ['Image MD5', 'MD5']]; for (k = 0, len1 = ref1.length; k < len1; k++) { type = ref1[k]; entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); } return Menu.menu.addEntry(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 != null; } }; }, makeFilter: function() { var re, type, value; type = this.dataset.type; value = Filter[type](Filter.menu.post); re = type === 'uniqueID' || type === 'MD5' ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { if (c === '\n') { return '\\n'; } else if (c === '\\') { return '\\\\'; } else { return "\\" + c; } }); re = type === 'uniqueID' || type === 'MD5' ? "/" + 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() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link'])) { return; } if (Conf['Reply Hiding Buttons']) { $.addClass(doc, "reply-hide"); } this.db = new DataBoard('hiddenPosts'); return Post.callbacks.push({ name: 'Reply Hiding', cb: this.node }); }, node: function() { var data, sideArrows; if (!this.isReply || this.isClone || this.isFetchedQuote) { 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; } sideArrows = $('.sideArrows', this.nodes.root); $.replace(sideArrows.firstChild, PostHiding.makeButton(this, 'hide')); return sideArrows.removeAttribute('class'); }, menu: { init: function() { var apply, div, hideStubLink, makeStub, ref, replies, thisPost; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !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 = UI.checkbox('thisPost', 'This post', true); replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']); makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']); Menu.menu.addEntry({ 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 = UI.checkbox('thisPost', 'This post', false); replies = UI.checkbox('replies', 'Show replies', false); hideStubLink = $.el('a', { textContent: 'Hide stub', href: 'javascript:;' }); $.on(hideStubLink, 'click', PostHiding.menu.hideStub); Menu.menu.addEntry({ 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 Menu.menu.addEntry({ 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 data, post; post = PostHiding.menu.post; if (data = PostHiding.db.get({ boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID })) { PostHiding.show(post, data.hideRecursively); PostHiding.hide(post, false, data.hideRecursively); PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively); } $.event('CloseMenu'); } }, makeButton: function(post, type) { var a, span; span = $.el('span', { className: "fa fa-" + (type === 'hide' ? 'minus' : 'plus') + "-square-o", textContent: "" }); a = $.el('a', { className: type + "-reply-button", href: 'javascript:;' }); $.add(a, span); $.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, k, len1, quotelink, 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 (k = 0, len1 = ref.length; k < len1; k++) { quotelink = ref[k]; $.addClass(quotelink, 'filtered'); } if (!makeStub) { post.nodes.root.hidden = true; return; } a = PostHiding.makeButton(post, 'show'); $.add(a, $.tn(" " + post.info.nameBlock)); post.nodes.stub = $.el('div', { className: 'stub' }); $.add(post.nodes.stub, a); if (Conf['Menu']) { $.add(post.nodes.stub, Menu.makeButton(post)); } return $.prepend(post.nodes.root, post.nodes.stub); }, show: function(post, showRecursively) { var k, len1, quotelink, 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 (k = 0, len1 = ref.length; k < len1; k++) { quotelink = ref[k]; $.rmClass(quotelink, 'filtered'); } } }; Recursive = { recursives: {}, init: function() { var ref; if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { return; } return Post.callbacks.push({ name: 'Recursive', cb: this.node }); }, node: function() { var i, k, len1, len2, obj, q, quote, recursive, ref, ref1; if (this.isClone || this.isFetchedQuote) { return; } ref = this.quotes; for (k = 0, len1 = ref.length; k < len1; k++) { quote = ref[k]; if (obj = Recursive.recursives[quote]) { ref1 = obj.recursives; for (i = q = 0, len2 = ref1.length; q < len2; i = ++q) { recursive = ref1[i]; recursive.apply(null, [this].concat(slice.call(obj.args[i]))); } } } }, add: function() { var args, base1, name1, obj, post, recursive; recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; obj = (base1 = Recursive.recursives)[name1 = post.fullID] || (base1[name1] = { recursives: [], args: [] }); obj.recursives.push(recursive); return obj.args.push(args); }, rm: function(recursive, post) { var i, k, len1, obj, rec, ref; if (!(obj = Recursive.recursives[post.fullID])) { return; } ref = obj.recursives; for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { rec = ref[i]; if (!(rec === recursive)) { continue; } obj.recursives.splice(i, 1); obj.args.splice(i, 1); } }, apply: function() { var args, fullID, post, recursive; recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; fullID = post.fullID; return g.posts.forEach(function(post) { if (indexOf.call(post.quotes, fullID) >= 0) { return recursive.apply(null, [post].concat(slice.call(args))); } }); } }; ThreadHiding = { init: function() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'catalog') || !Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Navigation']) { return; } this.db = new DataBoard('hiddenThreads'); if (g.VIEW === 'catalog') { return this.catalogWatch(); } this.catalogSet(g.BOARD); return Post.callbacks.push({ name: 'Thread Hiding', cb: this.node }); }, catalogSet: function(board) { var hiddenThreads, threadID; if (!$.hasStorage) { return; } hiddenThreads = ThreadHiding.db.get({ boardID: board.ID, defaultValue: {} }); for (threadID in hiddenThreads) { hiddenThreads[threadID] = true; } return localStorage.setItem("4chan-hide-t-" + board, JSON.stringify(hiddenThreads)); }, catalogWatch: function() { if (!$.hasStorage) { return; } this.hiddenThreads = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; return Main.ready(function() { return new MutationObserver(ThreadHiding.catalogSave).observe($.id('threads'), { attributes: true, subtree: true, attributeFilter: ['style'] }); }); }, catalogSave: function() { var hiddenThreads2, threadID; hiddenThreads2 = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; for (threadID in hiddenThreads2) { if (!(threadID in ThreadHiding.hiddenThreads)) { ThreadHiding.db.set({ boardID: g.BOARD.ID, threadID: threadID, val: { makeStub: Conf['Stubs'] } }); } } for (threadID in ThreadHiding.hiddenThreads) { if (!(threadID in hiddenThreads2)) { ThreadHiding.db["delete"]({ boardID: g.BOARD.ID, threadID: threadID }); } } return ThreadHiding.hiddenThreads = hiddenThreads2; }, node: function() { var data; if (this.isReply || this.isClone || this.isFetchedQuote) { return; } if (data = ThreadHiding.db.get({ boardID: this.board.ID, threadID: this.ID })) { ThreadHiding.hide(this.thread, data.makeStub); } if (!Conf['Thread Hiding Buttons']) { return; } return $.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide')); }, onIndexBuild: function(nodes) { var k, len1, root, thread; for (k = 0, len1 = nodes.length; k < len1; k++) { root = nodes[k]; thread = Get.threadFromRoot(root); if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { ThreadHiding.makeStub(thread, root); } } }, 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 = UI.checkbox('Stubs', 'Make stub'); Menu.menu.addEntry({ el: div, order: 20, open: function(arg) { var isReply, thread; thread = arg.thread, isReply = arg.isReply; if (isReply || thread.isHidden || Conf['JSON Navigation'] && Conf['Index Mode'] === 'catalog') { 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); Menu.menu.addEntry({ el: div, order: 20, open: function(arg) { var isReply, thread; thread = arg.thread, isReply = arg.isReply; if (isReply || !thread.isHidden || Conf['JSON Navigation'] && Conf['Index Mode'] === 'catalog') { return false; } ThreadHiding.menu.thread = thread; return true; } }); hideStubLink = $.el('a', { textContent: 'Hide stub', href: 'javascript:;' }); $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); return Menu.menu.addEntry({ el: hideStubLink, order: 15, open: function(arg) { var isReply, thread; thread = arg.thread, isReply = arg.isReply; if (isReply || !thread.isHidden || Conf['JSON Navigation'] && Conf['Index Mode'] === 'catalog') { 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.show(thread); ThreadHiding.hide(thread, false); ThreadHiding.saveHiddenState(thread, false); $.event('CloseMenu'); } }, makeButton: function(thread, type) { var a; a = $.el('a', { className: type + "-thread-button", href: 'javascript:;' }); $.extend(a, { innerHTML: "" }); a.dataset.fullID = thread.fullID; $.on(a, 'click', ThreadHiding.toggle); return a; }, makeStub: function(thread, root) { var a, numReplies, summary; numReplies = $$('.thread > .replyContainer', root).length; if (summary = $('.summary', root)) { numReplies += +summary.textContent.match(/\d+/); } a = ThreadHiding.makeButton(thread, 'show'); $.add(a, $.tn(" " + thread.OP.info.nameBlock + " (" + (numReplies === 1 ? '1 reply' : numReplies + " replies") + ")")); thread.stub = $.el('div', { className: 'stub' }); if (Conf['Menu']) { $.add(thread.stub, [a, Menu.makeButton(thread.OP)]); } else { $.add(thread.stub, a); } return $.prepend(root, thread.stub); }, saveHiddenState: function(thread, makeStub) { if (thread.isHidden) { ThreadHiding.db.set({ boardID: thread.board.ID, threadID: thread.ID, val: { makeStub: makeStub } }); } else { ThreadHiding.db["delete"]({ boardID: thread.board.ID, threadID: thread.ID }); } return ThreadHiding.catalogSet(thread.board); }, 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 threadRoot; if (makeStub == null) { makeStub = Conf['Stubs']; } if (thread.isHidden) { return; } threadRoot = thread.OP.nodes.root.parentNode; thread.isHidden = true; if (Conf['JSON Navigation']) { Index.updateHideLabel(); } if (!makeStub) { return threadRoot.hidden = true; } return ThreadHiding.makeStub(thread, threadRoot); }, show: function(thread) { var threadRoot; if (thread.stub) { $.rm(thread.stub); delete thread.stub; } threadRoot = thread.OP.nodes.root.parentNode; threadRoot.hidden = thread.isHidden = false; if (Conf['JSON Navigation']) { return Index.updateHideLabel(); } } }; QuoteBacklink = { containers: {}, init: function() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Backlinks']) { return; } Post.callbacks.push({ name: 'Quote Backlinking Part 1', cb: this.firstNode }); return Post.callbacks.push({ name: 'Quote Backlinking Part 2', cb: this.secondNode }); }, firstNode: function() { var a, clone, container, containers, hash, k, len1, len2, len3, link, markYours, nodes, post, q, quote, ref, ref1, u; if (this.isClone || !this.quotes.length || this.isRebuilt) { return; } markYours = Conf['Quick Reply'] && Conf['Mark Quotes of You'] && QR.db.get({ boardID: this.board.ID, threadID: this.thread.ID, postID: this.ID }); a = $.el('a', { href: Build.postURL(this.board.ID, this.thread.ID, this.ID), className: this.isHidden ? 'filtered backlink' : 'backlink', textContent: Conf['backlink'].replace(/%(?:id|%)/g, (function(_this) { return function(x) { return { '%id': _this.ID, '%%': '%' }[x]; }; })(this)) + (markYours ? '\u00A0(You)' : '') }); ref = this.quotes; for (k = 0, len1 = ref.length; k < len1; k++) { quote = ref[k]; containers = [QuoteBacklink.getContainer(quote)]; if ((post = g.posts[quote]) && post.nodes.backlinkContainer) { ref1 = post.clones; for (q = 0, len2 = ref1.length; q < len2; q++) { clone = ref1[q]; containers.push(clone.nodes.backlinkContainer); } } for (u = 0, len3 = containers.length; u < len3; u++) { container = containers[u]; link = a.cloneNode(true); nodes = container.firstChild ? [$.tn(' '), link] : [link]; if (Conf['Quote Previewing']) { $.on(link, 'mouseover', QuotePreview.mouseover); } if (Conf['Quote Inlining']) { $.on(link, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')); nodes.push(hash); } } $.add(container, nodes); } } }, 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 base1; return (base1 = this.containers)[id] || (base1[id] = $.el('span', { className: 'container' })); } }; QuoteCT = { init: function() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark Cross-thread Quotes']) { return; } if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } this.text = '\u00A0(Cross-thread)'; return Post.callbacks.push({ name: 'Mark Cross-thread Quotes', cb: this.node }); }, node: function() { var board, boardID, k, len1, quotelink, ref, ref1, ref2, thread, threadID; 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 (k = 0, len1 = ref1.length; k < len1; k++) { quotelink = ref1[k]; 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() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Inlining']) { return; } this.process = Conf['Quote Hash Navigation'] ? function(link, clone) { if (!clone) { $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); } return $.on(link, 'click', QuoteInline.toggle); } : function(link) { return $.on(link, 'click', QuoteInline.toggle); }; if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } return Post.callbacks.push({ name: 'Quote Inlining', cb: this.node }); }, node: function() { var isClone, k, len1, len2, link, process, q, ref, ref1; process = QuoteInline.process; isClone = this.isClone; ref = this.nodes.quotelinks; for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; process(link, isClone); } ref1 = this.nodes.backlinks; for (q = 0, len2 = ref1.length; q < len2; q++) { link = ref1[q]; process(link, isClone); } }, qiQuote: function(link, hidden) { var name; name = "hashlink"; if (hidden) { name += " filtered"; } return $.el('a', { className: name, textContent: '#', href: link.href }); }, toggle: function(e) { var boardID, context, postID, ref, threadID; 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='pc" + 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'); new Fetcher(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, ref, root; 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() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark OP Quotes']) { return; } if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } this.text = '\u00A0(OP)'; return Post.callbacks.push({ name: 'Mark OP Quotes', cb: this.node }); }, node: function() { var boardID, fullID, i, postID, quotelink, quotelinks, quotes, ref, ref1; if (this.isClone && this.thread === this.context.thread) { return; } if (!(quotes = this.quotes).length) { return; } quotelinks = this.nodes.quotelinks; if (this.isClone && (ref = this.thread.fullID, indexOf.call(quotes, ref) >= 0)) { i = 0; while (quotelink = quotelinks[i++]) { quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, ''); } } fullID = (this.isClone ? this.context : this).thread.fullID; if (indexOf.call(quotes, fullID) < 0) { return; } i = 0; while (quotelink = quotelinks[i++]) { ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; if ((boardID + "." + postID) === fullID) { $.add(quotelink, $.tn(QuoteOP.text)); } } } }; QuotePreview = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Quote Previewing'])) { return; } if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } return Post.callbacks.push({ name: 'Quote Previewing', cb: this.node }); }, node: function() { var k, len1, link, ref; ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks)); for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; $.on(link, 'mouseover', QuotePreview.mouseover); } }, mouseover: function(e) { var boardID, clone, k, len1, len2, origin, post, postID, posts, q, qp, quote, quoterID, ref, ref1, threadID; if ($.hasClass(this, 'inlined') || !d.contains(this)) { 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); new Fetcher(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 (k = 0, len1 = posts.length; k < len1; k++) { post = posts[k]; $.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 (q = 0, len2 = ref1.length; q < len2; q++) { quote = ref1[q]; if (quote.hash.slice(2) === quoterID) { $.addClass(quote, 'forwardlink'); } } }, mouseout: function() { var clone, k, len1, post, ref, root; 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 (k = 0, len1 = ref.length; k < len1; k++) { post = ref[k]; $.rmClass(post.nodes.post, 'qphl'); } } }; QuoteStrikeThrough = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Reply Hiding Buttons'] || (Conf['Menu'] && Conf['Reply Hiding Link']) || Conf['Filter']))) { return; } return Post.callbacks.push({ name: 'Strike-through Quotes', cb: this.node }); }, node: function() { var boardID, k, len1, postID, quotelink, ref, ref1, ref2; if (this.isClone) { return; } ref = this.nodes.quotelinks; for (k = 0, len1 = ref.length; k < len1; k++) { quotelink = ref[k]; 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() { if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { return; } this.enabled = true; this.controls = $.el('span', { innerHTML: "" }); this.threadNewLink = $.el('span', { className: 'brackets-wrap threadnewlink', hidden: true }); $.extend(this.threadNewLink, { innerHTML: "Thread New Posts" }); this.input = $('input', this.controls); $.on(this.input, 'change', this.rethread); $.on(this.threadNewLink.firstElementChild, 'click', this.rethread); Header.menu.addEntry(this.entry = { el: this.controls, order: 99 }); Thread.callbacks.push({ name: 'Quote Threading', cb: this.setThread }); return Post.callbacks.push({ name: 'Quote Threading', cb: this.node }); }, parent: {}, children: {}, inserted: {}, setThread: function() { QuoteThreading.thread = this; return $.asap((function() { return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink'); }), function() { return $.add($('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]); }); }, node: function() { var ancestor, k, lastParent, len1, parent, parents, quote, ref; if (this.isFetchedQuote || this.isClone || !this.isReply) { return; } parents = new Set(); lastParent = null; ref = this.quotes; for (k = 0, len1 = ref.length; k < len1; k++) { quote = ref[k]; if (parent = g.posts[quote]) { if (!parent.isFetchedQuote && parent.isReply && parent.ID < this.ID) { parents.add(parent.ID); if (!lastParent || parent.ID > lastParent.ID) { lastParent = parent; } } } } if (!lastParent) { return; } ancestor = lastParent; while (ancestor = QuoteThreading.parent[ancestor.fullID]) { parents["delete"](ancestor.ID); } if (parents.size === 1) { return QuoteThreading.parent[this.fullID] = lastParent; } }, descendants: function(post) { var child, children, k, len1, posts; posts = [post]; if (children = QuoteThreading.children[post.fullID]) { for (k = 0, len1 = children.length; k < len1; k++) { child = children[k]; posts = posts.concat(QuoteThreading.descendants(child)); } } return posts; }, insert: function(post) { var base1, child, children, descendants, i, k, len1, name1, next, nodes, order, parent, prev, prev2, q, threadContainer, u, x; if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) { return false; } descendants = QuoteThreading.descendants(post); if (!Unread.posts.has(parent.ID)) { if ((function() { var k, len1, x; for (k = 0, len1 = descendants.length; k < len1; k++) { x = descendants[k]; if (Unread.posts.has(x.ID)) { return true; } } })()) { QuoteThreading.threadNewLink.hidden = false; return false; } } order = Unread.order; children = ((base1 = QuoteThreading.children)[name1 = parent.fullID] || (base1[name1] = [])); threadContainer = parent.nodes.threadContainer || $.el('div', { className: 'threadContainer' }); nodes = [post.nodes.root]; if (post.nodes.threadContainer) { nodes.push(post.nodes.threadContainer); } i = children.length; for (k = children.length - 1; k >= 0; k += -1) { child = children[k]; if (child.ID >= post.ID) { i--; } } if (i !== children.length) { next = children[i]; for (q = 0, len1 = descendants.length; q < len1; q++) { x = descendants[q]; order.before(order[next.ID], order[x.ID]); } children.splice(i, 0, post); $.before(next.nodes.root, nodes); } else { prev = parent; while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) { prev = prev2[prev2.length - 1]; } for (u = descendants.length - 1; u >= 0; u += -1) { x = descendants[u]; order.after(order[prev.ID], order[x.ID]); } children.push(post); $.add(threadContainer, nodes); } QuoteThreading.inserted[post.fullID] = true; if (!parent.nodes.threadContainer) { parent.nodes.threadContainer = threadContainer; $.addClass(parent.nodes.root, 'threadOP'); $.after(parent.nodes.root, threadContainer); } return true; }, rethread: function() { var nodes, posts, thread; thread = QuoteThreading.thread; posts = thread.posts; QuoteThreading.threadNewLink.hidden = true; if (QuoteThreading.enabled = QuoteThreading.input.checked) { posts.forEach(QuoteThreading.insert); } else { nodes = []; Unread.order = new RandomAccessList(); QuoteThreading.inserted = {}; posts.forEach(function(post) { if (post.isFetchedQuote) { return; } Unread.order.push(post); if (post.isReply) { nodes.push(post.nodes.root); } if (QuoteThreading.children[post.fullID]) { delete QuoteThreading.children[post.fullID]; $.rmClass(post.nodes.root, 'threadOP'); $.rm(post.nodes.threadContainer); return delete post.nodes.threadContainer; } }); $.add(thread.OP.nodes.root.parentNode, nodes); } Unread.position = Unread.order.first; Unread.updatePosition(); Unread.setLine(true); Unread.read(); return Unread.update(); } }; QuoteYou = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && 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); } this.text = '\u00A0(You)'; return Post.callbacks.push({ name: 'Mark Quotes of You', cb: this.node }); }, node: function() { var k, len1, quotelink, ref; if (this.isClone) { return; } if (QR.db.get({ boardID: this.board.ID, threadID: this.thread.ID, postID: this.ID })) { $.addClass(this.nodes.root, 'yourPost'); } if (!this.quotes.length) { return; } ref = this.nodes.quotelinks; for (k = 0, len1 = ref.length; k < len1; k++) { quotelink = ref[k]; if (!(QR.db.get(Get.postDataFromLink(quotelink)))) { continue; } $.add(quotelink, $.tn(QuoteYou.text)); $.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.scrollTo(post); $.addClass($('.post', post), 'highlight'); return true; } } } }; Quotify = { init: function() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Resurrect Quotes']) { return; } if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } return Post.callbacks.push({ name: 'Resurrect Quotes', cb: this.node }); }, node: function() { var deadlink, k, len1, ref; ref = $$('.deadlink', this.nodes.comment); for (k = 0, len1 = ref.length; k < len1; k++) { deadlink = ref[k]; if (this.isClone) { if ($.hasClass(deadlink, 'quotelink')) { this.nodes.quotelinks.push(deadlink); } } else { Quotify.parseDeadlink.call(this, deadlink); } } }, parseDeadlink: function(deadlink) { var a, boardID, fetchable, 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: Build.postURL(boardID, post.thread.ID, postID), className: 'quotelink', textContent: quote }); } else { a = $.el('a', { href: Build.postURL(boardID, post.thread.ID, postID), className: 'quotelink deadlink', textContent: quote + "\u00A0(Dead)" }); $.extend(a.dataset, { boardID: boardID, threadID: post.thread.ID, postID: postID }); } } else { redirect = Redirect.to('thread', { boardID: boardID, threadID: 0, postID: postID }); fetchable = Redirect.to('post', { boardID: boardID, postID: postID }); if (redirect || fetchable) { a = $.el('a', { href: redirect || 'javascript:;', className: 'deadlink', textContent: quote + "\u00A0(Dead)" }); if (fetchable) { $.addClass(a, 'quotelink'); $.extend(a.dataset, { boardID: boardID, postID: postID }); } } } if (indexOf.call(this.quotes, quoteID) < 0) { 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) { var el, green; if (!(el = deadlink.previousSibling) || el.nodeName === 'BR') { green = $.el('span', { className: 'quote' }); $.before(deadlink, green); $.add(green, deadlink); } return $.replace(deadlink, slice.call(deadlink.childNodes)); } }; QR = { mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash', 'video/webm'], validExtension: /\.(jpe?g|png|gif|pdf|swf|webm)$/i, typeFromExtension: { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'gif': 'image/gif', 'pdf': 'application/pdf', 'swf': 'application/vnd.adobe.flash.movie', 'webm': 'video/webm' }, extensionFromType: { 'image/jpeg': 'jpg', 'image/png': 'png', 'image/gif': 'gif', 'application/pdf': 'pdf', 'application/vnd.adobe.flash.movie': 'swf', 'application/x-shockwave-flash': 'swf', 'video/webm': 'webm' }, init: function() { var sc, version; if (!Conf['Quick Reply']) { return; } if (Conf['Mark Quotes of You']) { this.db = new DataBoard('yourPosts'); } this.posts = []; if (g.VIEW === 'archive') { return; } version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2'; this.captcha = Captcha[version]; $.on(d, '4chanXInitFinished', this.initReady); Post.callbacks.push({ name: 'Quick Reply', cb: this.node }); if (Conf['QR Shortcut']) { this.shortcut = sc = $.el('a', { className: 'qr-shortcut fa fa-comment-o disabled', textContent: 'QR', title: 'Quick Reply', href: 'javascript:;' }); $.on(sc, 'click', function() { if (!QR.postingIsEnabled) { return; } if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { QR.open(); return QR.nodes.com.focus(); } else { return QR.close(); } }); Header.addShortcut(sc); } if (Conf['Hide Original Post Form']) { $.addClass(doc, 'hide-original-post-form'); if (!$.hasClass(doc, 'js-enabled')) { return $.onExists(doc, '#postForm noscript', true, $.rm); } } }, initReady: function() { var link, linkBot; $.off(d, '4chanXInitFinished', this.initReady); QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { return; } link = $.el('h1', { className: "qr-link-container" }); $.extend(link, { innerHTML: "" + (g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread") + "" }); QR.link = link.firstElementChild; $.on(link.firstChild, 'click', function() { QR.open(); return QR.nodes.com.focus(); }); if (Conf['Bottom QR Link'] && g.VIEW === 'thread') { linkBot = $.el('div', { className: "brackets-wrap qr-link-container-bottom" }); $.extend(linkBot, { innerHTML: "Reply to Thread" }); $.on(linkBot.firstElementChild, 'click', function() { QR.open(); return QR.nodes.com.focus(); }); $.prepend($('.navLinksBot'), linkBot); } $.before($.id('togglePostFormLink'), link); $.on(d, 'QRGetFile', QR.getFile); $.on(d, 'QRSetFile', QR.setFile); $.on(d, 'paste', QR.paste); $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); $.on(d, 'dragstart dragend', QR.drag); $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); $.on(d, 'ThreadUpdate', QR.statusCheck); if (!Conf['Persistent QR']) { return; } QR.open(); if (Conf['Auto Hide QR']) { return QR.hide(); } }, statusCheck: function() { var thread; if (!QR.nodes) { return; } thread = QR.posts[0].thread; if (thread !== 'new' && g.threads[g.BOARD + "." + thread].isDead) { return QR.abort(); } else { return QR.status(); } }, node: function() { $.on(this.nodes.quote, 'click', QR.quote); if (this.isFetchedQuote) { return QR.generatePostableThreadsList(); } }, open: function() { var err; if (QR.nodes) { if (QR.nodes.el.hidden) { QR.captcha.setup(); } QR.nodes.el.hidden = false; QR.unhide(); } else { try { QR.dialog(); } catch (_error) { err = _error; delete QR.nodes; Main.handleErrors({ message: 'Quick Reply dialog creation crashed.', error: err }); return; } } if (Conf['QR Shortcut']) { return $.rmClass(QR.shortcut, 'disabled'); } }, close: function() { var k, len1, post, ref; if (QR.req) { QR.abort(); return; } QR.nodes.el.hidden = true; QR.cleanNotifications(); d.activeElement.blur(); $.rmClass(QR.nodes.el, 'dump'); if (Conf['QR Shortcut']) { $.addClass(QR.shortcut, 'disabled'); } new QR.post(true); ref = QR.posts.splice(0, QR.posts.length - 1); for (k = 0, len1 = ref.length; k < len1; k++) { post = ref[k]; post["delete"](); } QR.cooldown.auto = false; QR.status(); return QR.captcha.destroy(); }, focus: function() { return $.queueTask(function() { if (!QR.inBubble()) { QR.hasFocus = d.activeElement && QR.nodes.el.contains(d.activeElement); QR.nodes.el.classList.toggle('focus', QR.hasFocus); } if (QR.captcha.isEnabled && QR.captcha === Captcha.v2 && !QR.captcha.noscript) { if (QR.inCaptcha()) { QR.scrollY = window.scrollY; return $.on(d, 'scroll', QR.scrollLock); } else { return $.off(d, 'scroll', QR.scrollLock); } } }); }, inBubble: function() { var bubbles, ref; bubbles = $$('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); return (ref = d.activeElement, indexOf.call(bubbles, ref) >= 0) || bubbles.some(function(el) { return getComputedStyle(el).visibility !== 'hidden' && el.getBoundingClientRect().bottom > 0; }); }, inCaptcha: function() { var ref; return (((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && QR.nodes.el.contains(d.activeElement)) || (QR.hasFocus && QR.inBubble()); }, scrollLock: function() { if (QR.inCaptcha()) { return window.scroll(window.scrollX, QR.scrollY); } else { return $.off(d, 'scroll', QR.scrollLock); } }, 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(); } }, toggleSJIS: function(e) { e.preventDefault(); Conf['sjisPreview'] = !Conf['sjisPreview']; $.set('sjisPreview', Conf['sjisPreview']); return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']); }, texPreviewShow: function() { if ($.hasClass(QR.nodes.el, 'tex-preview')) { return QR.texPreviewHide(); } $.addClass(QR.nodes.el, 'tex-preview'); QR.nodes.texPreview.textContent = QR.nodes.com.value; return $.event('mathjax', null, QR.nodes.texPreview); }, texPreviewHide: function() { return $.rmClass(QR.nodes.el, 'tex-preview'); }, setCustomCooldown: function(enabled) { Conf['customCooldownEnabled'] = enabled; QR.cooldown.customCooldown = enabled; return QR.nodes.customCooldown.classList.toggle('disabled', !enabled); }, toggleCustomCooldown: function() { var enabled; enabled = $.hasClass(this, 'disabled'); QR.setCustomCooldown(enabled); return $.set('customCooldownEnabled', enabled); }, error: function(err, focusOverride) { var el, notice, notif; QR.open(); if (typeof err === 'string') { el = $.tn(err); } else { el = err; el.removeAttribute('style'); } notice = new Notice('warning', el); QR.notifications.push(notice); if (!Header.areNotificationsEnabled) { if (d.hidden && !QR.cooldown.auto) { return alert(el.textContent); } } else if (d.hidden || !(focusOverride || d.hasFocus())) { try { notif = new Notification(el.textContent, { body: el.textContent, icon: Favicon.logo }); notif.onclick = function() { return window.focus(); }; if ($.engine !== 'gecko') { notif.onclose = function() { return notice.close(); }; return notif.onshow = function() { return setTimeout(function() { notif.onclose = null; return notif.close(); }, 7 * $.SECOND); }; } } catch (_error) {} } }, notifications: [], cleanNotifications: function() { var k, len1, notification, ref; ref = QR.notifications; for (k = 0, len1 = ref.length; k < len1; k++) { notification = ref[k]; 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 = 'Dead'; 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; }, openPost: function() { var index; 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'); return QR.cooldown.auto = true; } }, quote: function(e) { var aa, ancestor, caretPos, com, frag, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, z; if (e != null) { e.preventDefault(); } if (!QR.postingIsEnabled) { return; } sel = d.getSelection(); post = Get.postFromNode(this); text = post.board.ID === g.BOARD.ID ? ">>" + post + "\n" : ">>>/" + post.board + "/" + post + "\n"; if (sel.toString().trim() && post === Get.postFromNode(sel.anchorNode)) { range = sel.getRangeAt(0); frag = range.cloneContents(); ancestor = range.commonAncestorContainer; if ($.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]', ancestor)) { $.prepend(frag, $.tn('[spoiler]')); $.add(frag, $.tn('[/spoiler]')); } if (insideCode = $.x('ancestor-or-self::pre[contains(@class,"prettyprint")]', ancestor)) { $.prepend(frag, $.tn('[code]')); $.add(frag, $.tn('[/code]')); } ref = $$((insideCode ? 'br' : '.prettyprint br'), frag); for (k = 0, len1 = ref.length; k < len1; k++) { node = ref[k]; $.replace(node, $.tn('\n')); } ref1 = $$('br', frag); for (q = 0, len2 = ref1.length; q < len2; q++) { node = ref1[q]; if (node !== frag.lastChild) { $.replace(node, $.tn('\n>')); } } ref2 = $$('s, .removed-spoiler', frag); for (u = 0, len3 = ref2.length; u < len3; u++) { node = ref2[u]; $.replace(node, [$.tn('[spoiler]')].concat(slice.call(node.childNodes), [$.tn('[/spoiler]')])); } ref3 = $$('.prettyprint', frag); for (v = 0, len4 = ref3.length; v < len4; v++) { node = ref3[v]; $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); } ref4 = $$('.linkify[data-original]', frag); for (z = 0, len5 = ref4.length; z < len5; z++) { node = ref4[z]; $.replace(node, $.tn(node.dataset.original)); } ref5 = $$('.embedder', frag); for (aa = 0, len6 = ref5.length; aa < len6; aa++) { node = ref5[aa]; if (((ref6 = node.previousSibling) != null ? ref6.nodeValue : void 0) === ' ') { $.rm(node.previousSibling); } $.rm(node); } text += ">" + (frag.textContent.trim()) + "\n"; } QR.openPost(); ref7 = QR.nodes, com = ref7.com, thread = ref7.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); return QR.selected.save(thread); }, characterCount: function() { var count, counter; counter = QR.nodes.charCount; count = QR.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '_').length; counter.textContent = count; counter.hidden = count < QR.max_comment / 2; return (count > QR.max_comment ? $.addClass : $.rmClass)(counter, 'warning'); }, getFile: function() { var ref; return $.event('QRFile', (ref = QR.selected) != null ? ref.file : void 0); }, setFile: function(e) { var file, name, ref, source; ref = e.detail, file = ref.file, name = ref.name, source = ref.source; if (name != null) { file.name = name; } if (source != null) { file.source = source; } QR.open(); return QR.handleFiles([file]); }, 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(); return QR.handleFiles(e.dataTransfer.files); }, paste: function(e) { var blob, files, item, k, len1, ref; if (!e.clipboardData.items) { return; } files = []; ref = e.clipboardData.items; for (k = 0, len1 = ref.length; k < len1; k++) { item = ref[k]; 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'); }, pasteFF: function() { var arr, blob, bstr, i, images, img, k, len1, m, pasteArea, q, ref, src; pasteArea = QR.nodes.pasteArea; if (!pasteArea.childNodes.length) { return; } images = $$('img', pasteArea); $.rmAll(pasteArea); for (k = 0, len1 = images.length; k < len1; k++) { img = images[k]; src = img.src; if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) { bstr = atob(m[3]); arr = new Uint8Array(bstr.length); for (i = q = 0, ref = bstr.length; 0 <= ref ? q < ref : q > ref; i = 0 <= ref ? ++q : --q) { arr[i] = bstr.charCodeAt(i); } blob = new Blob([arr], { type: m[1] }); blob.name = "file." + m[2]; QR.handleFiles([blob]); } else if (/^https?:\/\//.test(src)) { QR.handleUrl(src); } } }, handleUrl: function(urlDefault) { var url; url = prompt('Enter a URL:', urlDefault); if (url === null) { return; } QR.nodes.fileButton.focus(); return CrossOrigin.file(url, function(blob) { if (blob) { return QR.handleFiles([blob]); } else { return QR.error("Can't load file."); } }); }, handleFiles: function(files) { var file, k, len1; if (this !== QR) { files = slice.call(this.files); this.value = null; } if (!files.length) { return; } QR.cleanNotifications(); for (k = 0, len1 = files.length; k < len1; k++) { file = files[k]; QR.handleFile(file, files.length); } if (files.length !== 1) { $.addClass(QR.nodes.el, 'dump'); } if (d.activeElement === QR.nodes.fileButton && $.hasClass(QR.nodes.fileSubmit, 'has-file')) { return QR.nodes.filename.focus(); } }, handleFile: function(file, nfiles) { var isText, post; isText = /^text\//.test(file.type); if (nfiles === 1) { post = QR.selected; } else { post = QR.posts[QR.posts.length - 1]; if ((isText ? post.com || post.pasting : post.file)) { post = new QR.post(); } } return post[isText ? 'pasteText' : 'setFile'](file); }, openFileInput: function() { if (QR.nodes.fileButton.disabled) { return; } QR.nodes.fileInput.click(); return QR.nodes.fileButton.focus(); }, generatePostableThreadsList: function() { var k, len1, list, options, ref, thread, val; if (!QR.nodes) { return; } list = QR.nodes.thread; options = [list.firstElementChild]; ref = g.BOARD.threads.keys; for (k = 0, len1 = ref.length; k < len1; k++) { thread = ref[k]; options.push($.el('option', { value: thread, textContent: "Thread " + thread })); } val = list.value; $.rmAll(list); $.add(list, options); list.value = val; if (list.value === val) { return; } list.value = g.VIEW === 'thread' ? g.THREADID : 'new'; return (g.VIEW === 'thread' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); }, dialog: function() { var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, scriptData, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { innerHTML: "
×
No selected file
" }) }; setNode = function(name, query) { return nodes[name] = $(query, dialog); }; setNode('move', '.move'); setNode('autohide', '#autohide'); setNode('close', '.close'); setNode('thread', 'select'); setNode('form', 'form'); setNode('sjisToggle', '#sjis-toggle'); setNode('texButton', '#tex-preview-button'); setNode('name', '[data-name=name]'); setNode('email', '[data-name=email]'); setNode('sub', '[data-name=sub]'); setNode('com', '[data-name=com]'); setNode('charCount', '#char-count'); setNode('texPreview', '#tex-preview'); setNode('dumpList', '#dump-list'); setNode('addPost', '#add-post'); setNode('oekaki', '.oekaki'); setNode('drawButton', '#qr-draw-button'); setNode('fileSubmit', '#file-n-submit'); setNode('fileButton', '#qr-file-button'); setNode('noFile', '#qr-no-file'); setNode('filename', '#qr-filename'); setNode('spoiler', '#qr-file-spoiler'); setNode('oekakiButton', '#qr-oekaki-button'); setNode('fileRM', '#qr-filerm'); setNode('urlButton', '#url-button'); setNode('pasteArea', '#paste-area'); setNode('customCooldown', '#custom-cooldown-button'); setNode('dumpButton', '#dump-button'); setNode('status', '[type=submit]'); setNode('flashTag', '[name=filetag]'); setNode('fileInput', '[type=file]'); rules = $('ul.rules').textContent.trim(); match_min = rules.match(/.+smaller than (\d+)x(\d+).+/); match_max = rules.match(/.+greater than (\d+)x(\d+).+/); QR.min_width = +(match_min != null ? match_min[1] : void 0) || 1; QR.min_height = +(match_min != null ? match_min[2] : void 0) || 1; QR.max_width = +(match_max != null ? match_max[1] : void 0) || 10000; QR.max_height = +(match_max != null ? match_max[2] : void 0) || 10000; nodes.fileInput.max = $('input[name=MAX_FILE_SIZE]').value; scriptData = Get.scriptData(); QR.max_size_video = (m = scriptData.match(/\bmaxWebmFilesize *= *(\d+)\b/)) ? +m[1] : +nodes.fileInput.max; QR.max_comment = (m = scriptData.match(/\bcomlen *= *(\d+)\b/)) ? +m[1] : 2000; QR.max_width_video = QR.max_height_video = 2048; QR.max_duration_video = (ref = g.BOARD.ID) === 'gif' || ref === 'wsg' ? 300 : 120; if (Conf['Show New Thread Option in Threads']) { $.addClass(QR.nodes.el, 'show-new-thread-option'); } if (Conf['Show Name and Subject']) { $.addClass(QR.nodes.name, 'force-show'); $.addClass(QR.nodes.sub, 'force-show'); QR.nodes.email.placeholder = 'E-mail'; } QR.forcedAnon = !!$('form[name="post"] input[name="name"][type="hidden"]'); if (QR.forcedAnon) { $.addClass(QR.nodes.el, 'forced-anon'); } QR.spoiler = !!$('.postForm input[name=spoiler]'); if (QR.spoiler) { $.addClass(QR.nodes.el, 'has-spoiler'); } if (g.BOARD.ID === 'jp' && Conf['sjisPreview']) { $.addClass(QR.nodes.el, 'sjis-preview'); } if (parseInt(Conf['customCooldown'], 10) > 0) { $.addClass(QR.nodes.fileSubmit, 'custom-cooldown'); $.get('customCooldownEnabled', Conf['customCooldownEnabled'], function(arg) { var customCooldownEnabled; customCooldownEnabled = arg.customCooldownEnabled; QR.setCustomCooldown(customCooldownEnabled); return $.sync('customCooldownEnabled', QR.setCustomCooldown); }); } $.on(nodes.autohide, 'change', QR.toggleHide); $.on(nodes.close, 'click', QR.close); $.on(nodes.form, 'submit', QR.submit); $.on(nodes.sjisToggle, 'click', QR.toggleSJIS); $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); $.on(nodes.addPost, 'click', function() { return new QR.post(true); }); $.on(nodes.drawButton, 'click', QR.oekaki.draw); $.on(nodes.fileButton, 'click', QR.openFileInput); $.on(nodes.noFile, 'click', QR.openFileInput); $.on(nodes.filename, 'focus', function() { return $.addClass(this.parentNode, 'focus'); }); $.on(nodes.filename, 'blur', function() { return $.rmClass(this.parentNode, 'focus'); }); $.on(nodes.spoiler, 'change', function() { return QR.selected.nodes.spoiler.click(); }); $.on(nodes.oekakiButton, 'click', QR.oekaki.button); $.on(nodes.fileRM, 'click', function() { return QR.selected.rmFile(); }); $.on(nodes.urlButton, 'click', function() { return QR.handleUrl(''); }); $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); $.on(nodes.dumpButton, 'click', function() { return nodes.el.classList.toggle('dump'); }); $.on(nodes.fileInput, 'change', QR.handleFiles); window.addEventListener('focus', QR.focus, true); window.addEventListener('blur', QR.focus, true); $.on(d, 'click', QR.focus); if ($.engine === 'gecko') { nodes.pasteArea.hidden = false; new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, { childList: true }); } items = ['thread', 'name', 'email', 'sub', 'com', 'filename']; i = 0; save = function() { return QR.selected.save(this); }; while (name = items[i++]) { if (!(node = nodes[name])) { continue; } event = node.nodeName === 'SELECT' ? 'change' : 'input'; $.on(nodes[name], event, save); } if ($.engine === 'gecko' && 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.generatePostableThreadsList(); QR.persona.init(); new QR.post(true); QR.status(); QR.cooldown.setup(); QR.captcha.init(); $.add(d.body, dialog); QR.captcha.setup(); QR.oekaki.setup(); return $.event('QRDialogCreation', null, dialog); }, submit: function(e) { var captcha, cb, err, extra, filetag, formData, options, post, ref, textOnly, thread, threadID; 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(); threadID = post.thread; thread = g.BOARD.threads[threadID]; if (g.BOARD.ID === 'f' && threadID === 'new') { filetag = QR.nodes.flashTag.value; } if (threadID === 'new') { threadID = null; if (g.BOARD.ID === 'vg' && !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 comment or file.'; } else if (post.file && thread.fileLimit) { err = 'Max limit of image replies has been reached.'; } if (g.BOARD.ID === 'r9k' && !((ref = post.com) != null ? ref.match(/[a-z-]/i) : void 0)) { err || (err = 'Original comment required.'); } if (QR.captcha.isEnabled && !err) { captcha = QR.captcha.getOne(); if (!captcha) { err = 'No valid captcha.'; QR.captcha.setup(!QR.cooldown.auto || d.activeElement === QR.nodes.status); } } 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(); formData = { resto: threadID, name: !QR.forcedAnon ? post.name : void 0, email: post.email, sub: !(QR.forcedAnon || threadID) ? post.sub : void 0, com: post.com, upfile: post.file, filetag: filetag, spoiler: post.spoiler, textonly: textOnly, mode: 'regist', pwd: QR.persona.pwd }; 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. [Banned?] [More info]" })); } }; extra = { form: $.formData(formData), upCallbacks: { onload: function() { QR.req.isUploadFinished = true; QR.req.progress = '...'; return QR.status(); }, onprogress: function(e) { QR.req.progress = (Math.round(e.loaded / e.total * 100)) + "%"; return QR.status(); } } }; cb = function(response) { if (response != null) { if (response.challenge != null) { extra.form.append('recaptcha_challenge_field', response.challenge); extra.form.append('recaptcha_response_field', response.response); } else { extra.form.append('g-recaptcha-response', response.response); } } QR.req = $.ajax("https://sys.4chan.org/" + g.BOARD + "/post", options, extra); return QR.req.progress = '...'; }; if (typeof captcha === 'function') { QR.req = { progress: '...', abort: function() { return cb = null; } }; captcha(function(response) { if (response) { return typeof cb === "function" ? cb(response) : void 0; } else { delete QR.req; post.unlock(); QR.cooldown.auto = !!QR.captcha.captchas.length; return QR.status(); } }); } else { cb(captcha); } return QR.status(); }, response: function() { var URL, _, ban, err, h1, isReply, lastPostToThread, m, open, post, postID, postsCount, ref, ref1, ref2, req, resDoc, seconds, threadID; req = QR.req; delete QR.req; post = QR.posts[0]; post.unlock(); resDoc = req.response; if (ban = $('.banType', resDoc)) { err = $.el('span', ban.textContent.toLowerCase() === 'banned' ? { innerHTML: "You are banned on " + $(".board", resDoc).innerHTML + "! ;_;
Click here to see the reason." } : { innerHTML: "You were issued a warning on " + $(".board", resDoc).innerHTML + " as " + $(".nameBlock", resDoc).innerHTML + ".
Reason: " + $(".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 = $.el('span', { innerHTML: "You mistyped the CAPTCHA, or the CAPTCHA malfunctioned [complain here]." }); } else if (/expired/i.test(err.textContent)) { err = 'This CAPTCHA is no longer valid because it has expired.'; } QR.cooldown.auto = QR.captcha.isEnabled || err === 'Connection error with sys.4chan.org.'; QR.cooldown.addDelay(post, 2); } else if (err.textContent && (m = err.textContent.match(/(?:(\d+)\s+minutes?\s+)?(\d+)\s+second/i)) && !/duplicate|hour/i.test(err.textContent)) { QR.cooldown.auto = !/have\s+been\s+muted/i.test(err.textContent); seconds = 60 * (+(m[1] || 0)) + (+m[2]); if (/muted/i.test(err.textContent)) { QR.cooldown.addMute(seconds); } else { QR.cooldown.addDelay(post, seconds); } } else { QR.cooldown.auto = false; } QR.captcha.setup(QR.cooldown.auto && d.activeElement === QR.nodes.status); if (QR.captcha.isEnabled && !QR.captcha.captchas.length) { 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)); } 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; if ((ref2 = QR.db) != null) { ref2.set({ boardID: g.BOARD.ID, threadID: threadID, postID: postID, val: true }); } $.event('QRPostSuccessful', { boardID: g.BOARD.ID, threadID: threadID, postID: postID }); $.event('QRPostSuccessful_', { boardID: g.BOARD.ID, threadID: threadID, postID: postID }); postsCount = QR.posts.length - 1; QR.cooldown.auto = postsCount && isReply; lastPostToThread = !((function() { var k, len1, p, ref3; ref3 = QR.posts.slice(1); for (k = 0, len1 = ref3.length; k < len1; k++) { p = ref3[k]; if (p.thread === post.thread) { return true; } } })()); if (!(Conf['Persistent QR'] || postsCount)) { QR.close(); } else { post.rm(); QR.captcha.setup(d.activeElement === QR.nodes.status); } QR.cooldown.add(threadID, postID); URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; if (URL) { open = Conf['Open Post in New Tab'] || postsCount ? function() { return $.open(URL); } : function() { return window.location = URL; }; if (threadID === postID) { QR.waitForThread(URL, open); } else { open(); } } return QR.status(); }, waitForThread: function(url, cb) { var attempts, check; attempts = 0; check = function() { return $.ajax(url, { onloadend: function() { attempts++; if (attempts >= 5 || this.status === 200) { return cb(); } else { return setTimeout(check, attempts * $.SECOND); } } }, { type: 'HEAD' }); }; return check(); }, 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(); } }; Captcha = {}; Captcha.fixes = { imageKeys: '789456123uiojklm'.split('').concat(['Comma', 'Period']), imageKeys16: '7890uiopjkl'.split('').concat(['Semicolon', 'm', 'Comma', 'Period', 'Slash']), css: '.rc-imageselect-target > div:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-imageselect-target td:focus {\n box-shadow: inset 0 0 0 2px #4a90e2;\n outline: none;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}', cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}', init: function() { switch (location.pathname.split('/')[3]) { case 'anchor': return this.initMain(); case 'frame': return this.initPopup(); case 'fallback': return this.initNoscript(); } }, initMain: function() { return $.onExists(d.body, '#recaptcha-anchor', true, function(checkbox) { var focus; focus = function() { if (d.hasFocus() && d.activeElement !== checkbox) { return checkbox.focus(); } }; focus(); return $.on(window, 'focus', function() { return $.queueTask(focus); }); }); }, initPopup: function() { $.addStyle(this.css); this.fixImages(); new MutationObserver((function(_this) { return function() { return _this.fixImages(); }; })(this)).observe(d.body, { childList: true, subtree: true }); return $.on(d, 'keydown', this.keybinds.bind(this)); }, initNoscript: function() { this.noscript = true; this.images = $$('.fbc-payload-imageselect > input'); if (this.images.length !== 9) { return; } $.addStyle(this.cssNoscript); this.addLabels(); $.on(d, 'keydown', this.keybinds.bind(this)); return $.on($('.fbc-imageselect-challenge > form'), 'submit', this.checkForm.bind(this)); }, fixImages: function() { var img, k, len1, ref; this.images = $$('.rc-imageselect-target > div, .rc-imageselect-target td'); ref = this.images; for (k = 0, len1 = ref.length; k < len1; k++) { img = ref[k]; img.tabIndex = 0; } if (this.images.length === 9) { this.addTooltips(this.images); } if (this.images.length === 16) { this.addTooltips16(this.images); } return this.complaintLinks(); }, complaintLinks: function() { var errmsg, k, len1, link, ref; ref = $$('.rc-imageselect-incorrect-response, .rc-imageselect-error-select-one, .rc-imageselect-error-select-more'); for (k = 0, len1 = ref.length; k < len1; k++) { errmsg = ref[k]; if (!$('a', errmsg)) { link = $.el('a', { href: 'https://www.4chan-x.net/captchas.html', target: '_blank', textContent: '[complain]' }); $.add(errmsg, [$.tn(' '), link]); } } }, addLabels: function() { var checkbox, i, imageSelect, label, labels; imageSelect = $('.fbc-payload-imageselect'); labels = (function() { var k, len1, ref, results; ref = this.images; results = []; for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { checkbox = ref[i]; checkbox.id = "checkbox-" + i; label = $.el('label', { htmlFor: checkbox.id }); label.dataset.row = Math.floor(i / 3); label.dataset.col = i % 3; results.push(label); } return results; }).call(this); $.add(imageSelect, labels); return this.addTooltips(labels); }, addTooltips: function(nodes) { var i, k, len1, node; for (i = k = 0, len1 = nodes.length; k < len1; i = ++k) { node = nodes[i]; node.title = this.imageKeys[i] + " or " + (this.imageKeys[i + 9][0].toUpperCase()) + this.imageKeys[i + 9].slice(1); } }, addTooltips16: function(nodes) { var i, k, len1, node; for (i = k = 0, len1 = nodes.length; k < len1; i = ++k) { node = nodes[i]; node.title = "" + (this.imageKeys16[i][0].toUpperCase()) + this.imageKeys16[i].slice(1); } }, checkForm: function(e) { var checkbox, k, len1, n, ref; n = 0; ref = this.images; for (k = 0, len1 = ref.length; k < len1; k++) { checkbox = ref[k]; if (checkbox.checked) { n++; } } if (n === 0) { return e.preventDefault(); } }, keybinds: function(e) { var dx, i, key, last, n, reload, verify, w, x; if (!(this.images && doc.contains(this.images[0]))) { return; } n = this.images.length; w = Math.round(Math.sqrt(n)); last = n + w - 1; reload = $('#recaptcha-reload-button, .fbc-button-reload'); verify = $('#recaptcha-verify-button, .fbc-button-verify > input'); x = this.images.indexOf(d.activeElement); if (x < 0) { x = d.activeElement === verify ? last : n; } key = Keybinds.keyCode(e); if (!this.noscript && key === 'Space' && x < n) { this.images[x].click(); } else if (n === 9 && (i = this.imageKeys.indexOf(key)) >= 0) { this.images[i % 9].click(); verify.focus(); } else if (n === 16 && (i = this.imageKeys16.indexOf(key)) >= 0) { this.images[i].click(); verify.focus(); } else if (dx = { 'Up': n, 'Down': w, 'Left': last, 'Right': 1 }[key]) { x = (x + dx) % (n + w); if ((n < x && x < last)) { x = dx === last ? n : last; } (this.images[x] || (x === n ? reload : void 0) || (x === last ? verify : void 0)).focus(); } else { return; } e.preventDefault(); return e.stopPropagation(); } }; Captcha.replace = { init: function() { var jsEnabled; if (!(d.cookie.indexOf('pass_enabled=1') < 0)) { return; } if (location.hostname === 'boards.4chan.org' && Conf['Hide Original Post Form']) { return; } jsEnabled = $.hasClass(doc, 'js-enabled'); if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && jsEnabled) { $.ready(Captcha.replace.v2); return; } if (Conf['Use Recaptcha v1'] && jsEnabled && location.hostname !== 'www.4chan.org') { $.ready(Captcha.replace.v1); return; } if (Conf['captchaLanguage'].trim()) { if (location.hostname === 'boards.4chan.org') { return $.onExists(doc, '#captchaFormPart', true, function(node) { return $.onExists(node, 'iframe', true, Captcha.replace.iframe); }); } else { return $.onExists(doc, 'iframe', true, Captcha.replace.iframe); } } }, v1: function() { var form, link; if (!$.id('g-recaptcha')) { return; } Captcha.v1.replace(); if (link = $.id('form-link')) { return $.on(link, 'click', function() { return Captcha.v1.create(); }); } else if (location.hostname === 'boards.4chan.org') { form = $.id('postForm'); return form.addEventListener('focus', (function() { return Captcha.v1.create(); }), true); } else { return Captcha.v1.create(); } }, v2: function() { var container, lang, old, script, url; if (!(old = $.id('captchaContainerAlt'))) { return; } container = $.el('div', { className: 'g-recaptcha' }); $.extend(container.dataset, { sitekey: '6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc', tabindex: 3 }); $.replace(old, container); url = 'https://www.google.com/recaptcha/api.js'; if (lang = Conf['captchaLanguage'].trim()) { url += "?hl=" + (encodeURIComponent(lang)); } script = $.el('script', { src: url }); return $.add(d.head, script); }, iframe: function(el) { var lang, src; if (!(lang = Conf['captchaLanguage'].trim())) { return; } src = /[?&]hl=/.test(el.src) ? el.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : el.src + ("&hl=" + (encodeURIComponent(lang))); if (el.src !== src) { return el.src = src; } } }; Captcha.v1 = { blank: "data:image/svg+xml,", init: function() { var imgContainer, input; if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt'))) { return; } imgContainer = $.el('div', { className: 'captcha-img', title: 'Reload reCAPTCHA' }); $.extend(imgContainer, { innerHTML: "" }); input = $.el('input', { className: 'captcha-input field', title: 'Verification', autocomplete: 'off', spellcheck: false }); this.nodes = { img: imgContainer.firstChild, input: input }; $.on(input, 'blur', QR.focusout); $.on(input, 'focus', QR.focusin); $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha)); $.on(this.nodes.img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha)); $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v1'); $.after(QR.nodes.com.parentNode, [imgContainer, input]); this.captchas = []; $.get('captchas', [], function(arg) { var captchas; captchas = arg.captchas; QR.captcha.sync(captchas); return QR.captcha.clear(); }); $.sync('captchas', this.sync); this.replace(); this.beforeSetup(); if (Conf['Auto-load captcha']) { this.setup(); } new MutationObserver(this.afterSetup).observe($.id('captchaContainerAlt'), { childList: true }); return this.afterSetup(); }, replace: function() { var container, old; if (this.script) { return; } if (!(this.script = $('script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]', d.head))) { this.script = $.el('script', { src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js' }); $.add(d.head, this.script); } if (old = $.id('g-recaptcha')) { container = $.el('div', { id: 'captchaContainerAlt' }); return $.replace(old, container); } }, create: function() { return $.globalEval('(function() {\n var container = document.getElementById("captchaContainerAlt");\n if (container.firstChild) return;\n var options = {\n theme: "clean",\n tabindex: {"boards.4chan.org": 5, "sys.4chan.org": 3}[location.hostname]\n };\n if (window.Recaptcha) {\n window.Recaptcha.create("6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc", container, options);\n } else {\n var script = document.head.querySelector(\'script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]\');\n script.addEventListener(\'load\', function() {\n window.Recaptcha.create("6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc", container, options);\n }, false);\n }\n})();'); }, cb: { focus: function() { return QR.captcha.setup(false, true); } }, beforeSetup: function() { var img, input, ref; ref = this.nodes, img = ref.img, input = ref.input; img.parentNode.hidden = true; img.src = this.blank; input.value = ''; input.placeholder = 'Focus to load reCAPTCHA'; this.count(); return $.on(input, 'focus click', this.cb.focus); }, needed: function() { var captchaCount, postsCount; captchaCount = this.captchas.length; if (QR.req) { captchaCount++; } postsCount = QR.posts.length; if (postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) { postsCount = 0; } return captchaCount < postsCount; }, onNewPost: function() {}, onPostChange: function() {}, setup: function(focus, force) { if (!(this.isEnabled && (force || this.needed()))) { return; } this.create(); if (focus) { return this.nodes.input.focus(); } }, afterSetup: function() { var challenge, img, input, ref, setLifetime; if (!(challenge = $.id('recaptcha_challenge_field_holder'))) { return; } if (challenge === QR.captcha.nodes.challenge) { return; } setLifetime = function(e) { return QR.captcha.lifetime = e.detail; }; $.on(window, 'captcha:timeout', setLifetime); $.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))'); $.off(window, 'captcha:timeout', setLifetime); ref = QR.captcha.nodes, img = ref.img, input = ref.input; img.parentNode.hidden = false; input.placeholder = 'Verification'; QR.captcha.count(); $.off(input, 'focus click', QR.captcha.cb.focus); QR.captcha.nodes.challenge = challenge; new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, { childList: true, subtree: true, attributes: true }); QR.captcha.load(); if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { QR.nodes.el.style.top = null; return QR.nodes.el.style.bottom = '0px'; } }, destroy: function() { if (!this.script) { return; } $.globalEval('window.Recaptcha.destroy();'); if (this.nodes) { return this.beforeSetup(); } }, sync: function(captchas) { if (captchas == null) { captchas = []; } QR.captcha.captchas = captchas; return QR.captcha.count(); }, getOne: function() { var captcha, challenge, response, timeout; this.clear(); if (captcha = this.captchas.shift()) { this.count(); $.set('captchas', this.captchas); return captcha; } else { challenge = this.nodes.img.alt; timeout = this.timeout; if (/\S/.test(response = this.nodes.input.value)) { this.destroy(); return { challenge: challenge, response: response, timeout: timeout }; } else { return null; } } }, save: function() { var response; if (!/\S/.test(response = this.nodes.input.value)) { return; } this.nodes.input.value = ''; this.captchas.push({ challenge: this.nodes.img.alt, response: response, timeout: this.timeout }); this.captchas.sort(function(a, b) { return a.timeout - b.timeout; }); this.count(); this.destroy(); this.setup(false, true); return $.set('captchas', this.captchas); }, clear: function() { var captcha, i, k, len1, now, ref; if (!this.captchas.length) { return; } $.forceSync('captchas'); now = Date.now(); ref = this.captchas; for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { 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, challenge_image; if ($('#captchaContainerAlt[class~="recaptcha_is_showing_audio"]')) { this.nodes.img.src = this.blank; return; } if (!this.nodes.challenge.firstChild) { return; } if (!(challenge_image = $.id('recaptcha_challenge_image'))) { return; } this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE; challenge = this.nodes.challenge.firstChild.value; this.nodes.img.alt = challenge; this.nodes.img.src = challenge_image.src; this.nodes.input.value = ''; return this.clear(); }, count: function() { var count, placeholder; count = this.captchas ? this.captchas.length : 0; placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, ''); placeholder += (function() { switch (count) { case 0: if (placeholder === 'Verification') { return ' (Shift + Enter to cache)'; } else { return ''; } break; case 1: return ' (1 cached captcha)'; default: return " (" + count + " cached captchas)"; } })(); this.nodes.input.placeholder = placeholder; this.nodes.input.alt = count; clearTimeout(this.timer); if (count) { return this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); } }, reload: function(focus) { $.globalEval('if (window.Recaptcha.type === "image") {\n window.Recaptcha.reload();\n} else {\n window.Recaptcha.switch_type("image");\n}\nwindow.Recaptcha.should_focus = false;'); 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(); } }; Captcha.v2 = { lifetime: 2 * $.MINUTE, init: function() { var counter, root; if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt'))) { return; } if (this.noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled')) { this.conn = new Connection(null, location.protocol + "//www.google.com", { token: (function(_this) { return function(token) { return _this.save(true, token); }; })(this) }); $.addClass(QR.nodes.el, 'noscript-captcha'); } this.captchas = []; $.get('captchas', [], function(arg) { var captchas; captchas = arg.captchas; return QR.captcha.sync(captchas); }); $.sync('captchas', this.sync.bind(this)); root = $.el('div', { className: 'captcha-root' }); $.extend(root, { innerHTML: "
" }); counter = $('.captcha-counter > a', root); this.nodes = { root: root, counter: counter }; this.count(); $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2'); $.after(QR.nodes.com.parentNode, root); $.on(counter, 'click', this.toggle.bind(this)); $.on(counter, 'keydown', (function(_this) { return function(e) { if (Keybinds.keyCode(e) !== 'Space') { return; } _this.toggle(); e.preventDefault(); return e.stopPropagation(); }; })(this)); $.on(window, 'captcha:success', (function(_this) { return function() { return $.queueTask(function() { return _this.save(false); }); }; })(this)); return new MutationObserver(this.watchBubbles.bind(this)).observe(d.body, { childList: true }); }, initFrame: function() { var conn, ref, token; if (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) { conn = new Connection(window.parent, location.protocol + "//boards.4chan.org"); return conn.send({ token: token }); } }, timeouts: {}, postsCount: 0, noscriptURL: function() { var lang, url; url = '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; if (lang = Conf['captchaLanguage'].trim()) { url += "&hl=" + (encodeURIComponent(lang)); } return url; }, needed: function() { var captchaCount; captchaCount = this.captchas.length; if (QR.req) { captchaCount++; } this.postsCount = QR.posts.length; if (this.postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) { this.postsCount = 0; } return captchaCount < this.postsCount; }, onNewPost: function() { return this.setup(); }, onPostChange: function() { if (this.postsCount === 0) { this.setup(); } if (QR.posts.length === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) { return this.postsCount = 0; } }, toggle: function() { if (this.nodes.container && !this.timeouts.destroy) { return this.destroy(); } else { return this.setup(true, true); } }, setup: function(focus, force) { var iframe; if (!(this.isEnabled && (this.needed() || force))) { return; } if (focus) { this.nodes.counter.focus(); } if (this.timeouts.destroy) { clearTimeout(this.timeouts.destroy); delete this.timeouts.destroy; return this.reload(); } if (this.nodes.container) { if (d.activeElement === this.nodes.counter && (iframe = $('iframe', this.nodes.container))) { iframe.focus(); QR.focus(); } return; } this.nodes.container = $.el('div', { className: 'captcha-container' }); $.prepend(this.nodes.root, this.nodes.container); new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, { childList: true, subtree: true }); if (this.noscript) { return this.setupNoscript(); } else { return this.setupJS(); } }, setupNoscript: function() { var iframe; iframe = $.el('iframe', { id: 'qr-captcha-iframe', src: this.noscriptURL() }); $.add(this.nodes.container, iframe); return this.conn.target = iframe; }, setupJS: function() { return $.globalEval('(function() {\n function render() {\n var container = document.querySelector("#qr .captcha-container");\n container.dataset.widgetID = window.grecaptcha.render(container, {\n sitekey: \'6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc\',\n theme: document.documentElement.classList.contains(\'tomorrow\') ? \'dark\' : \'light\',\n callback: function(response) {\n window.dispatchEvent(new CustomEvent("captcha:success", {detail: response}));\n }\n });\n }\n if (window.grecaptcha) {\n render();\n } else {\n var cbNative = window.onRecaptchaLoaded;\n window.onRecaptchaLoaded = function() {\n render();\n cbNative();\n }\n }\n})();'); }, afterSetup: function(mutations) { var iframe, k, len1, len2, mutation, node, q, ref, textarea; for (k = 0, len1 = mutations.length; k < len1; k++) { mutation = mutations[k]; ref = mutation.addedNodes; for (q = 0, len2 = ref.length; q < len2; q++) { node = ref[q]; if (iframe = $.x('./descendant-or-self::iframe', node)) { this.setupIFrame(iframe); } if (textarea = $.x('./descendant-or-self::textarea', node)) { this.setupTextArea(textarea); } } } }, setupIFrame: function(iframe) { Captcha.replace.iframe(iframe); $.addClass(QR.nodes.el, 'captcha-open'); if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { QR.nodes.el.style.top = null; QR.nodes.el.style.bottom = '0px'; } if (d.activeElement === this.nodes.counter) { iframe.focus(); } return $.global(function() { var f; f = document.querySelector('#qr iframe'); return f.focus = f.blur = function() {}; }); }, setupTextArea: function(textarea) { return $.one(textarea, 'input', (function(_this) { return function() { return _this.save(true); }; })(this)); }, destroy: function() { var garbage, i, ins, node, ref; if (!this.isEnabled) { return; } delete this.timeouts.destroy; $.rmClass(QR.nodes.el, 'captcha-open'); if (this.nodes.container) { $.rm(this.nodes.container); } delete this.nodes.container; garbage = $.X('//iframe[starts-with(@src, "https://www.google.com/recaptcha/api2/frame")]/ancestor-or-self::*[parent::body]'); i = 0; while (node = garbage.snapshotItem(i++)) { if (((ref = (ins = node.nextSibling)) != null ? ref.nodeName : void 0) === 'INS') { $.rm(ins); } $.rm(node); } }, sync: function(captchas) { if (captchas == null) { captchas = []; } this.captchas = captchas; this.clear(); return this.count(); }, getOne: function() { var captcha; this.clear(); if (captcha = this.captchas.shift()) { $.set('captchas', this.captchas); this.count(); return captcha; } else { return null; } }, save: function(pasted, token) { var base1, focus, ref; $.forceSync('captchas'); this.captchas.push({ response: token || $('textarea', this.nodes.container).value, timeout: Date.now() + this.lifetime }); this.captchas.sort(function(a, b) { return a.timeout - b.timeout; }); $.set('captchas', this.captchas); this.count(); focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && /https?:\/\/www\.google\.com\/recaptcha\//.test(d.activeElement.src); if (this.needed()) { if (focus) { if (QR.cooldown.auto || Conf['Post on Captcha Completion']) { this.nodes.counter.focus(); } else { QR.nodes.status.focus(); } } this.reload(); } else { if (pasted) { this.destroy(); } else { if ((base1 = this.timeouts).destroy == null) { base1.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND); } } if (focus) { QR.nodes.status.focus(); } } if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { return QR.submit(); } }, clear: function() { var captcha, i, k, len1, now, ref; if (!this.captchas.length) { return; } $.forceSync('captchas'); now = Date.now(); ref = this.captchas; for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { captcha = ref[i]; if (captcha.timeout > now) { break; } } if (!i) { return; } this.captchas = this.captchas.slice(i); this.count(); $.set('captchas', this.captchas); return this.setup(d.activeElement === QR.nodes.status); }, count: function() { this.nodes.counter.textContent = "Captchas: " + this.captchas.length; clearTimeout(this.timeouts.clear); if (this.captchas.length) { return this.timeouts.clear = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); } }, reload: function() { if (this.noscript) { return $('iframe', this.nodes.container).src = this.noscriptURL(); } else if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { this.destroy(); return this.setup(false, true); } else { return $.globalEval('(function() {\n var container = document.querySelector("#qr .captcha-container");\n window.grecaptcha.reset(container.dataset.widgetID);\n})();'); } }, watchBubbles: function(mutations) { var k, len1, mutation, node, overlay, results; results = []; for (k = 0, len1 = mutations.length; k < len1; k++) { mutation = mutations[k]; results.push((function() { var len2, q, ref, results1; ref = mutation.addedNodes; results1 = []; for (q = 0, len2 = ref.length; q < len2; q++) { node = ref[q]; if ($('iframe[src^="https://www.google.com/recaptcha/api2/frame"]', node)) { new MutationObserver(this.fixBubble.bind(this, node)).observe(node, { attributes: true }); if (overlay = $('div[style*="position: fixed;"]', node)) { results1.push($.on(overlay, 'click', function() { var ref1; return (ref1 = $('#qr iframe')) != null ? ref1.blur() : void 0; })); } else { results1.push(void 0); } } else { results1.push(void 0); } } return results1; }).call(this)); } return results; }, fixBubble: function(node) { var bottom, newLeft, qrLeft, ref, right, width; ref = node.getBoundingClientRect(), bottom = ref.bottom, right = ref.right, width = ref.width; if (getComputedStyle(node).visibility !== 'hidden' && bottom > 0 && right > doc.clientWidth) { qrLeft = QR.nodes.el.getBoundingClientRect().left; newLeft = Math.max(0, qrLeft - width); return node.style.left = newLeft + "px"; } } }; PassLink = { init: function() { if (!Conf['Pass Link']) { return; } return Main.ready(this.ready); }, ready: function() { var passLink, styleSelector; if (!(styleSelector = $.id('styleSelector'))) { return; } passLink = $.el('span', { className: 'brackets-wrap pass-link-container' }); $.extend(passLink, { innerHTML: "4chan Pass" }); $.on(passLink.firstElementChild, 'click', function() { return window.open('//sys.4chan.org/auth', Date.now(), 'width=500,height=280,toolbar=0'); }); return $.before(styleSelector.previousSibling, [passLink, $.tn('\u00A0\u00A0')]); } }; PostSuccessful = { init: function() { if (!Conf['Mark Quotes of You']) { return; } return $.ready(this.ready); }, ready: function() { var _, db, postID, ref, threadID; if (d.title !== 'Post successful!') { return; } ref = $('h1').nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref[0], threadID = ref[1], postID = ref[2]; postID = +postID; threadID = +threadID || postID; db = new DataBoard('yourPosts'); return db.set({ boardID: g.BOARD.ID, threadID: threadID, postID: postID, val: true }); } }; QR.cooldown = { seconds: 0, delays: { thread: 0, reply: 0, image: 0, reply_intra: 0, image_intra: 0, deletion: 60, thread_global: 300 }, init: function() { if (!(Conf['Quick Reply'] && Conf['Cooldown'])) { return; } this.data = Conf['cooldowns']; return $.sync('cooldowns', this.sync); }, setup: function() { var delay, m, ref, type; if (!Conf['Cooldown']) { return; } if (m = Get.scriptData().match(/\bcooldowns *= *({[^}]+})/)) { $.extend(QR.cooldown.delays, JSON.parse(m[1])); } QR.cooldown.maxDelay = 0; ref = QR.cooldown.delays; for (type in ref) { delay = ref[type]; if (type !== 'thread' && type !== 'thread_global') { QR.cooldown.maxDelay = Math.max(QR.cooldown.maxDelay, delay); } } QR.cooldown.isSetup = true; return QR.cooldown.start(); }, start: function() { var data; data = QR.cooldown.data; if (!(QR.cooldown.isSetup && !QR.cooldown.isCounting && Object.keys(data[g.BOARD.ID] || {}).length + Object.keys(data.global || {}).length > 0)) { return; } QR.cooldown.isCounting = true; return QR.cooldown.count(); }, sync: function(data) { QR.cooldown.data = data || {}; return QR.cooldown.start(); }, add: function(threadID, postID) { var boardID, start; if (!Conf['Cooldown']) { return; } start = Date.now(); boardID = g.BOARD.ID; QR.cooldown.set(boardID, start, { threadID: threadID, postID: postID }); if (threadID === postID) { QR.cooldown.set('global', start, { boardID: boardID, threadID: threadID, postID: postID }); } return QR.cooldown.start(); }, addDelay: function(post, delay) { var cooldown; if (!Conf['Cooldown']) { return; } cooldown = QR.cooldown.categorize(post); cooldown.delay = delay; QR.cooldown.set(g.BOARD.ID, Date.now(), cooldown); return QR.cooldown.start(); }, addMute: function(delay) { if (!Conf['Cooldown']) { return; } QR.cooldown.set(g.BOARD.ID, Date.now(), { type: 'mute', delay: delay }); return QR.cooldown.start(); }, "delete": function(post) { var base1, cooldown, cooldowns, id, name1; if (!Conf['Cooldown']) { return; } $.forceSync('cooldowns'); cooldowns = ((base1 = QR.cooldown.data)[name1 = post.board.ID] || (base1[name1] = {})); for (id in cooldowns) { cooldown = cooldowns[id]; if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { delete cooldowns[id]; } } return QR.cooldown.save([post.board.ID]); }, secondsDeletion: function(post) { var cooldown, cooldowns, seconds, start; if (!(Conf['Quick Reply'] && Conf['Cooldown'])) { return 0; } cooldowns = QR.cooldown.data[post.board.ID] || {}; for (start in cooldowns) { cooldown = cooldowns[start]; if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { seconds = QR.cooldown.delays.deletion - Math.floor((Date.now() - start) / $.SECOND); return Math.max(seconds, 0); } } return 0; }, categorize: function(post) { if (post.thread === 'new') { return { type: 'thread' }; } else { return { type: !!post.file ? 'image' : 'reply', threadID: +post.thread }; } }, set: function(scope, id, value) { var base1, cooldowns; $.forceSync('cooldowns'); cooldowns = ((base1 = QR.cooldown.data)[scope] || (base1[scope] = {})); cooldowns[id] = value; return $.set('cooldowns', QR.cooldown.data); }, save: function(scopes) { var data, k, len1, scope; data = QR.cooldown.data; for (k = 0, len1 = scopes.length; k < len1; k++) { scope = scopes[k]; if (scope in data && !Object.keys(data[scope]).length) { delete data[scope]; } } return $.set('cooldowns', data); }, count: function() { var base1, cooldown, cooldowns, elapsed, k, len1, maxDelay, nCooldowns, now, ref, ref1, save, scope, seconds, start, suffix, threadID, type, update; $.forceSync('cooldowns'); save = []; nCooldowns = 0; now = Date.now(); ref = QR.cooldown.categorize(QR.posts[0]), type = ref.type, threadID = ref.threadID; seconds = 0; ref1 = [g.BOARD.ID, 'global']; for (k = 0, len1 = ref1.length; k < len1; k++) { scope = ref1[k]; cooldowns = ((base1 = QR.cooldown.data)[scope] || (base1[scope] = {})); for (start in cooldowns) { cooldown = cooldowns[start]; start = +start; elapsed = Math.floor((now - start) / $.SECOND); if (elapsed < 0) { delete cooldowns[start]; save.push(scope); continue; } if (cooldown.delay != null) { if (cooldown.delay <= elapsed) { delete cooldowns[start]; save.push(scope); } else if ((cooldown.type === type && cooldown.threadID === threadID) || cooldown.type === 'mute') { seconds = Math.max(seconds, cooldown.delay - elapsed); } continue; } maxDelay = cooldown.threadID !== cooldown.postID ? QR.cooldown.maxDelay : QR.cooldown.delays[scope === 'global' ? 'thread_global' : 'thread']; if (QR.cooldown.customCooldown) { maxDelay = Math.max(maxDelay, parseInt(Conf['customCooldown'], 10)); } if (maxDelay <= elapsed) { delete cooldowns[start]; save.push(scope); continue; } if ((type === 'thread') === (cooldown.threadID === cooldown.postID) && cooldown.boardID !== g.BOARD.ID) { suffix = scope === 'global' ? '_global' : type !== 'thread' && threadID === cooldown.threadID ? '_intra' : ''; seconds = Math.max(seconds, QR.cooldown.delays[type + suffix] - elapsed); } if (QR.cooldown.customCooldown) { seconds = Math.max(seconds, parseInt(Conf['customCooldown'], 10) - elapsed); } } nCooldowns += Object.keys(cooldowns).length; } if (save.length) { QR.cooldown.save(save); } if (nCooldowns) { clearTimeout(QR.cooldown.timeout); QR.cooldown.timeout = setTimeout(QR.cooldown.count, $.SECOND); } else { delete QR.cooldown.isCounting; } update = seconds !== QR.cooldown.seconds; QR.cooldown.seconds = seconds; if (update) { QR.status(); } if (seconds === 0 && QR.cooldown.auto && !QR.req) { return QR.submit(); } } }; QR.oekaki = { init: function() { if (!(Conf['Quick Reply'] && Conf['Oekaki Links'])) { return; } return Post.callbacks.push({ name: 'Oekaki Links', cb: this.node }); }, node: function() { var link; if (!(this.file && (this.file.isImage || this.file.isVideo))) { return; } if (this.isClone) { link = $('.file-oekaki', this.file.text); } else { link = $.el('a', { className: 'file-oekaki', href: 'javascript:;', title: 'Edit in Tegaki' }); $.extend(link, { innerHTML: "" }); $.add(this.file.text, [$.tn('\u00A0'), link]); } return $.on(link, 'click', QR.oekaki.editFile); }, editFile: function() { var currentTime, isVideo, post, ref; if (!QR.postingIsEnabled) { return; } QR.quote.call(this); post = Get.postFromNode(this); isVideo = post.file.isVideo; currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; return CrossOrigin.file(post.file.url, function(blob) { var video; if (!blob) { return QR.error("Can't load file."); } else if (isVideo) { video = $.el('video'); $.on(video, 'loadedmetadata', function() { $.on(video, 'seeked', function() { var canvas; canvas = $.el('canvas', { width: video.videoWidth, height: video.videoHeight }); canvas.getContext('2d').drawImage(video, 0, 0); return canvas.toBlob(function(snapshot) { snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; QR.handleFiles([snapshot]); return QR.oekaki.edit(); }); }); return video.currentTime = currentTime; }); return video.src = URL.createObjectURL(blob); } else { blob.name = post.file.name; QR.handleFiles([blob]); return QR.oekaki.edit(); } }); }, setup: function() { return $.global(function() { var FCX; FCX = window.FCX; FCX.oekakiCB = function() { return window.Tegaki.flatten().toBlob(function(file) { var source; source = "oekaki-" + (Date.now()); FCX.oekakiLatest = source; return document.dispatchEvent(new CustomEvent('QRSetFile', { bubbles: true, detail: { file: file, name: FCX.oekakiName, source: source } })); }); }; if (window.Tegaki) { return document.querySelector('#qr .oekaki').hidden = false; } }); }, load: function(cb) { var n, onload, script, style; if ($('script[src^="//s.4cdn.org/js/painter"]', d.head)) { return cb(); } else { style = $.el('link', { rel: 'stylesheet', href: "//s.4cdn.org/css/painter." + (Date.now()) + ".css" }); script = $.el('script', { src: "//s.4cdn.org/js/painter.min." + (Date.now()) + ".js" }); n = 0; onload = function() { if (++n === 2) { return cb(); } }; $.on(style, 'load', onload); $.on(script, 'load', onload); return $.add(d.head, [style, script]); } }, draw: function() { return $.global(function() { var FCX, Tegaki; Tegaki = window.Tegaki, FCX = window.FCX; if (Tegaki.bg) { Tegaki.destroy(); } FCX.oekakiName = 'tegaki.png'; return Tegaki.open({ onDone: FCX.oekakiCB, onCancel: function() { return Tegaki.bgColor = '#ffffff'; }, width: +document.querySelector('#qr [name=oekaki-width]').value, height: +document.querySelector('#qr [name=oekaki-height]').value, bgColor: document.querySelector('#qr [name=oekaki-bg]').checked ? document.querySelector('#qr [name=oekaki-bgcolor]').value : 'transparent' }); }); }, button: function() { if (QR.selected.file) { return QR.oekaki.edit(); } else { return QR.oekaki.toggle(); } }, edit: function() { return QR.oekaki.load(function() { return $.global(function() { var FCX, Tegaki, cb, error, name, source; Tegaki = window.Tegaki, FCX = window.FCX; name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; source = document.getElementById('file-n-submit').dataset.source; error = function(content) { return document.dispatchEvent(new CustomEvent('CreateNotification', { bubbles: true, detail: { type: 'warning', content: content, lifetime: 20 } })); }; cb = function(e) { var file, isVideo; document.removeEventListener('QRFile', cb, false); if (!e.detail) { return error('No file to edit.'); } if (!/^(image|video)\//.test(e.detail.type)) { return error('Not an image.'); } isVideo = /^video\//.test(e.detail.type); file = document.createElement(isVideo ? 'video' : 'img'); file.addEventListener('error', function() { return error('Could not open file.', false); }); file.addEventListener((isVideo ? 'loadeddata' : 'load'), function() { if (Tegaki.bg) { Tegaki.destroy(); } FCX.oekakiName = name; Tegaki.open({ onDone: FCX.oekakiCB, onCancel: function() { return Tegaki.bgColor = '#ffffff'; }, width: file.naturalWidth || file.videoWidth, height: file.naturalHeight || file.videoHeight, bgColor: 'transparent' }); return Tegaki.activeCtx.drawImage(file, 0, 0); }, false); return file.src = URL.createObjectURL(e.detail); }; if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { FCX.oekakiName = name; return Tegaki.resume(); } else { document.addEventListener('QRFile', cb, false); return document.dispatchEvent(new CustomEvent('QRGetFile', { bubbles: true })); } }); }); }, toggle: function() { return QR.oekaki.load(function() { return QR.nodes.oekaki.hidden = !QR.nodes.oekaki.hidden; }); } }; QR.persona = { pwd: '', always: {}, init: function() { QR.persona.getPassword(); return $.get('QR.personas', Conf['QR.personas'], function(arg) { var arr, item, k, len1, personas, ref, type, types; personas = arg['QR.personas']; types = { name: [], email: [], sub: [] }; ref = personas.split('\n'); for (k = 0, len1 = ref.length; k < len1; k++) { item = ref[k]; 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, ref, ref1, ref2, type, val; if (item[0] === '#') { return; } if (!(match = item.match(/(name|options|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' && (ref2 = g.BOARD.ID, indexOf.call(boards.split(','), ref2) < 0)) { return; } if (type === 'password') { QR.persona.pwd = val; return; } if (type === 'options') { type = 'email'; } if (type === 'subject') { type = 'sub'; } if (/always/i.test(item)) { QR.persona.always[type] = val; } if (indexOf.call(types[type], val) < 0) { return types[type].push(val); } }, loadPersonas: function(type, arr) { var k, len1, list, val; list = $("#list-" + type, QR.nodes.el); for (k = 0, len1 = arr.length; k < len1; k++) { val = arr[k]; if (val) { $.add(list, $.el('option', { textContent: val })); } } }, getPassword: function() { var input, m, ref; if (!QR.persona.pwd) { QR.persona.pwd = (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : (input = $.id('postPassword')) ? input.value : ((ref = $.id('delPassword')) != null ? ref.value : void 0) || ''; } 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 }; return $.set('QR.persona', persona); }); } }; QR.post = (function() { function _Class(select) { this.select = bind(this.select, this); var el, event, k, label, len1, len2, prev, q, ref, ref1; el = $.el('a', { className: 'qr-preview', draggable: true, href: 'javascript:;' }); $.extend(el, { innerHTML: "" }); this.nodes = { el: el, rm: el.firstChild, spoiler: $('.qr-preview-spoiler input', el), span: el.lastChild }; $.on(el, 'click', this.select); $.on(this.nodes.rm, 'click', (function(_this) { return function(e) { e.stopPropagation(); return _this.rm(); }; })(this)); $.on(this.nodes.spoiler, 'change', (function(_this) { return function(e) { _this.spoiler = e.target.checked; if (_this === QR.selected) { return QR.nodes.spoiler.checked = _this.spoiler; } }; })(this)); ref = $$('label', el); for (k = 0, len1 = ref.length; k < len1; k++) { label = ref[k]; $.on(label, 'click', function(e) { return e.stopPropagation(); }); } $.add(QR.nodes.dumpList, el); ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']; for (q = 0, len2 = ref1.length; q < len2; q++) { event = ref1[q]; $.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(_this) { return 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 : ''; _this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : ''; if (QR.selected === _this) { return _this.load(); } }; })(this)); if (select) { this.select(); } this.unlock(); $.queueTask(function() { return QR.captcha.onNewPost(); }); } _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); URL.revokeObjectURL(this.URL); return this.dismissErrors(); }; _Class.prototype.lock = function(lock) { var k, len1, name, node, ref; if (lock == null) { lock = true; } this.isLocked = lock; if (this !== QR.selected) { return; } ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler']; for (k = 0, len1 = ref.length; k < len1; k++) { name = ref[k]; if (node = QR.nodes[name]) { node.disabled = lock; } } this.nodes.rm.style.visibility = lock ? 'hidden' : ''; 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.removeAttribute('id'); 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; return this.load(); }; _Class.prototype.load = function() { var k, len1, name, node, ref; ref = ['thread', 'name', 'email', 'sub', 'com', 'filename']; for (k = 0, len1 = ref.length; k < len1; k++) { name = ref[k]; if (!(node = QR.nodes[name])) { continue; } node.value = this[name] || node.dataset["default"] || ''; } (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); 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 || input.dataset["default"] || null; switch (name) { case 'thread': (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); QR.status(); return this.updateFlashURL(); case 'com': this.nodes.span.textContent = this.com; QR.captcha.onPostChange(); 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.saveFilename(); this.updateFilename(); return this.updateFlashURL(); case 'name': return QR.persona.set(this); } }; _Class.prototype.forceSave = function() { var k, len1, name, node, ref; if (this !== QR.selected) { return; } ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler']; for (k = 0, len1 = ref.length; k < len1; k++) { name = ref[k]; if (!(node = QR.nodes[name])) { continue; } this.save(node); } }; _Class.rmErrored = function(e) { var error, errors, k, len1, post, q, ref; e.stopPropagation(); ref = QR.posts; for (k = ref.length - 1; k >= 0; k += -1) { post = ref[k]; if (errors = post.errors) { for (q = 0, len1 = errors.length; q < len1; q++) { error = errors[q]; if (!(doc.contains(error))) { continue; } post.rm(); break; } } } }; _Class.prototype.error = function(className, message) { var div, ref, rm, rmAll; div = $.el('div', { className: className }); $.extend(div, { innerHTML: E(message) + "
[delete] [delete all]" }); (this.errors || (this.errors = [])).push(div); ref = $$('a', div), rm = ref[0], rmAll = ref[1]; $.on(div, 'click', (function(_this) { return function() { if (indexOf.call(QR.posts, _this) >= 0) { return _this.select(); } }; })(this)); $.on(rm, 'click', (function(_this) { return function(e) { e.stopPropagation(); if (indexOf.call(QR.posts, _this) >= 0) { return _this.rm(); } }; })(this)); $.on(rmAll, 'click', QR.post.rmErrored); return QR.error(div, true); }; _Class.prototype.fileError = function(message) { return this.error('file-error', this.filename + ": " + message); }; _Class.prototype.dismissErrors = function(test) { var error, k, len1, ref; if (test == null) { test = function() { return true; }; } if (this.errors) { ref = this.errors; for (k = 0, len1 = ref.length; k < len1; k++) { error = ref[k]; if (doc.contains(error) && test(error)) { error.parentNode.previousElementSibling.click(); } } } }; _Class.prototype.setFile = function(file1) { var ext, ref; this.file = file1; if (Conf['Randomize Filename'] && g.BOARD.ID !== 'f') { this.filename = "" + (Date.now() - Math.floor(Math.random() * 365 * $.DAY)); if (ext = this.file.name.match(QR.validExtension)) { this.filename += ext[0]; } } else { this.filename = this.file.name; } this.filesize = $.bytesToString(this.file.size); this.checkSize(); $.addClass(this.nodes.el, 'has-file'); QR.captcha.onPostChange(); URL.revokeObjectURL(this.URL); this.saveFilename(); if (this === QR.selected) { this.showFileData(); } else { this.updateFilename(); } this.updateFlashURL(); this.nodes.el.style.backgroundImage = null; if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) { return this.fileError('Unsupported file type.'); } else if (/^(image|video)\//.test(this.file.type)) { return this.readFile(); } }; _Class.prototype.checkSize = function() { var max; max = QR.nodes.fileInput.max; if (/^video\//.test(this.file.type)) { max = Math.min(max, QR.max_size_video); } if (this.file.size > max) { return this.fileError("File too large (file: " + this.filesize + ", max: " + ($.bytesToString(max)) + ")."); } }; _Class.prototype.readFile = function() { var el, event, isVideo, onerror, onload; isVideo = /^video\//.test(this.file.type); el = $.el(isVideo ? 'video' : 'img'); if (isVideo && !el.canPlayType(this.file.type)) { return; } event = isVideo ? 'loadeddata' : 'load'; onload = (function(_this) { return function() { $.off(el, event, onload); $.off(el, 'error', onerror); _this.checkDimensions(el); return _this.setThumbnail(el); }; })(this); onerror = (function(_this) { return function() { $.off(el, event, onload); $.off(el, 'error', onerror); _this.fileError((isVideo ? 'Video' : 'Image') + " appears corrupt"); return URL.revokeObjectURL(el.src); }; })(this); $.on(el, event, onload); $.on(el, 'error', onerror); return el.src = URL.createObjectURL(this.file); }; _Class.prototype.checkDimensions = function(el) { var duration, height, max_height, max_width, ref, videoHeight, videoWidth, width; if (el.tagName === 'IMG') { height = el.height, width = el.width; if (height > QR.max_height || width > QR.max_width) { this.fileError("Image too large (image: " + height + "x" + width + "px, max: " + QR.max_height + "x" + QR.max_width + "px)"); } if (height < QR.min_height || width < QR.min_width) { return this.fileError("Image too small (image: " + height + "x" + width + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); } } else { videoHeight = el.videoHeight, videoWidth = el.videoWidth, duration = el.duration; max_height = Math.min(QR.max_height, QR.max_height_video); max_width = Math.min(QR.max_width, QR.max_width_video); if (videoHeight > max_height || videoWidth > max_width) { this.fileError("Video too large (video: " + videoHeight + "x" + videoWidth + "px, max: " + max_height + "x" + max_width + "px)"); } if (videoHeight < QR.min_height || videoWidth < QR.min_width) { this.fileError("Video too small (video: " + videoHeight + "x" + videoWidth + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); } if (!isFinite(duration)) { this.fileError('Video lacks duration metadata (try remuxing)'); } else if (duration > QR.max_duration_video) { this.fileError("Video too long (video: " + duration + "s, max: " + QR.max_duration_video + "s)"); } if (((ref = g.BOARD.ID) !== 'gif' && ref !== 'wsg') && $.hasAudio(el)) { return this.fileError('Audio not allowed'); } } }; _Class.prototype.setThumbnail = function(el) { var cv, height, isVideo, s, width; isVideo = el.tagName === 'VIDEO'; s = 90 * 2 * window.devicePixelRatio; if (this.file.type === 'image/gif') { s *= 3; } if (isVideo) { height = el.videoHeight; width = el.videoWidth; } else { height = el.height, width = el.width; if (height < s || width < s) { this.URL = el.src; 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 = height; cv.width = width; cv.getContext('2d').drawImage(el, 0, 0, width, height); URL.revokeObjectURL(el.src); return cv.toBlob((function(_this) { return function(blob) { _this.URL = URL.createObjectURL(blob); return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; }; })(this)); }; _Class.prototype.rmFile = function() { if (this.isLocked) { return; } delete this.file; delete this.filename; delete this.filesize; this.nodes.el.removeAttribute('title'); QR.nodes.filename.removeAttribute('title'); this.nodes.el.style.backgroundImage = null; $.rmClass(this.nodes.el, 'has-file'); this.showFileData(); this.updateFlashURL(); URL.revokeObjectURL(this.URL); return this.dismissErrors(function(error) { return $.hasClass(error, 'file-error'); }); }; _Class.prototype.saveFilename = function() { this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); if (!QR.validExtension.test(this.filename)) { return this.file.newName += "." + (QR.extensionFromType[this.file.type] || 'jpg'); } }; _Class.prototype.updateFilename = function() { var long; long = this.filename + " (" + this.filesize + ")"; this.nodes.el.title = long; if (this !== QR.selected) { return; } return QR.nodes.filename.title = long; }; _Class.prototype.showFileData = function() { var ref; if (this.file) { this.updateFilename(); QR.nodes.filename.value = this.filename; $.addClass(QR.nodes.oekaki, 'has-file'); $.addClass(QR.nodes.fileSubmit, 'has-file'); } else { $.rmClass(QR.nodes.oekaki, 'has-file'); $.rmClass(QR.nodes.fileSubmit, 'has-file'); } if (((ref = this.file) != null ? ref.source : void 0) != null) { QR.nodes.fileSubmit.dataset.source = this.file.source; } else { QR.nodes.fileSubmit.removeAttribute('data-source'); } return QR.nodes.spoiler.checked = this.spoiler; }; _Class.prototype.updateFlashURL = function() { var oldURL, ref, url; if (g.BOARD.ID !== 'f') { return; } if (this.thread === 'new' || !this.file) { url = ''; } else { url = this.file.newName; if ((ref = $.engine) === 'blink' || ref === 'webkit') { url = url.replace(/"/g, '%22'); } url = url.replace(/[\t\n\f\r \xa0\u200B\u2029\u3000]+/g, ' ').replace(/(^ | $)/g, '').replace(/\.[0-9A-Za-z]+$/, ''); url = "https://i.4cdn.org/f/" + (encodeURIComponent(E(url))) + ".swf\n"; } oldURL = this.flashURL || ''; if (url !== oldURL) { this.com || (this.com = ''); if (this.com.slice(0, oldURL.length) === oldURL) { this.com = this.com.slice(oldURL.length); } this.com = (url + this.com) || null; if (this === QR.selected) { QR.nodes.com.value = this.com; QR.characterCount(); } return this.flashURL = url; } }; _Class.prototype.pasteText = function(file) { var reader; this.pasting = true; reader = new FileReader(); reader.onload = (function(_this) { return 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; } _this.nodes.span.textContent = _this.com; return delete _this.pasting; }; })(this); 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; })(); FappeTyme = { init: function() { var el, k, lc, len1, ref, ref1, type; if (!((Conf['Fappe Tyme'] || Conf['Werk Tyme']) && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { return; } this.nodes = {}; this.enabled = { fappe: false, werk: Conf['werk'] }; ref1 = ["Fappe", "Werk"]; for (k = 0, len1 = ref1.length; k < len1; k++) { type = ref1[k]; if (!Conf[type + " Tyme"]) { continue; } lc = type.toLowerCase(); el = UI.checkbox(lc, type + " Tyme", false); el.title = type + " Tyme"; this.nodes[lc] = el.firstElementChild; if (Conf[lc]) { this.set(lc, true); } $.on(this.nodes[lc], 'change', this.toggle.bind(this, lc)); Header.menu.addEntry({ el: el, order: 97 }); } if (Conf['Werk Tyme']) { $.sync('werk', this.set.bind(this, 'werk')); } Post.callbacks.push({ name: 'Fappe Tyme', cb: this.node }); return CatalogThread.callbacks.push({ name: 'Werk Tyme', cb: this.catalogNode }); }, node: function() { return this.nodes.root.classList.toggle('noFile', !this.file); }, catalogNode: function() { var file, filename; file = this.thread.OP.file; if (!file) { return; } filename = $.el('div', { textContent: file.name, className: 'werkTyme-filename' }); return $.add(this.nodes.thumb.parentNode, filename); }, set: function(type, enabled) { this.enabled[type] = this.nodes[type].checked = enabled; return $[(enabled ? 'add' : 'rm') + "Class"](doc, type + "Tyme"); }, toggle: function(type) { this.set(type, !this.enabled[type]); if (type === 'werk') { return $.cb.checked.call(this.nodes[type]); } } }; Gallery = { init: function() { var el, ref; if (!(this.enabled = Conf['Gallery'] && ((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) { return; } this.delay = Conf['Slide Delay']; el = $.el('a', { href: 'javascript:;', id: 'appchan-gal', title: 'Gallery', className: 'fa fa-picture-o', textContent: 'Gallery' }); $.on(el, 'click', this.cb.toggle); Header.addShortcut(el); return Post.callbacks.push({ name: 'Gallery', cb: this.node }); }, node: function() { var ref; if (!((ref = this.file) != null ? ref.thumb : void 0)) { return; } if (Gallery.nodes) { Gallery.generateThumb(this); 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 candidate, cb, dialog, entry, file, k, key, len1, len2, menuButton, nodes, post, q, ref, ref1, ref2, ref3, thumb, value; cb = Gallery.cb; if (Conf['Fullscreen Gallery']) { $.one(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', function() { return $.on(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close); }); if (typeof doc.mozRequestFullScreen === "function") { doc.mozRequestFullScreen(); } if (typeof doc.webkitRequestFullScreen === "function") { doc.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); } } Gallery.images = []; nodes = Gallery.nodes = {}; Gallery.fullIDs = {}; Gallery.slideshow = false; nodes.el = dialog = $.el('div', { id: 'a-gallery' }); $.extend(dialog, { innerHTML: "
× /
" }); ref = { buttons: '.gal-buttons', 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'); $.on(nodes.frame, 'click', cb.blank); if (Conf['Mouse Wheel Volume']) { $.on(nodes.frame, 'wheel', Volume.wheel); } $.on(nodes.next, 'click', cb.click); $.on(nodes.name, 'click', ImageCommon.download); $.on($('.gal-prev', dialog), 'click', cb.prev); $.on($('.gal-next', dialog), 'click', cb.next); $.on($('.gal-start', dialog), 'click', cb.start); $.on($('.gal-stop', dialog), 'click', cb.stop); $.on($('.gal-close', dialog), 'click', cb.close); $.on(menuButton, 'click', function(e) { return nodes.menu.toggle(e, this, g); }); ref1 = Gallery.menu.createSubEntries(); for (k = 0, len1 = ref1.length; k < len1; k++) { entry = ref1[k]; entry.order = 0; nodes.menu.addEntry(entry); } $.on(d, 'keydown', cb.keybinds); if (Conf['Keybinds']) { $.off(d, 'keydown', Keybinds.keydown); } ref2 = $$('.post .file'); for (q = 0, len2 = ref2.length; q < len2; q++) { file = ref2[q]; post = Get.postFromNode(file); if (!((ref3 = post.file) != null ? ref3.thumb : void 0)) { continue; } Gallery.generateThumb(post); if (!image && Gallery.fullIDs[post.fullID]) { candidate = post.file.thumb.parentNode; if (Header.getTopOf(candidate) + candidate.getBoundingClientRect().height >= 0) { image = candidate; } } } $.addClass(doc, 'gallery-open'); $.add(d.body, dialog); nodes.thumbs.scrollTop = 0; nodes.current.parentElement.scrollTop = 0; if (image) { thumb = $("[href='" + image.href + "']", nodes.thumbs); } thumb || (thumb = Gallery.images[Gallery.images.length - 1]); if (thumb) { Gallery.open(thumb); } doc.style.overflow = 'hidden'; return nodes.total.textContent = Gallery.images.length; }, generateThumb: function(post) { var thumb, thumbImg; if (post.isClone || post.isHidden) { return; } if (!(post.file && post.file.thumb && (post.file.isImage || post.file.isVideo || Conf['PDF in Gallery']))) { return; } if (Gallery.fullIDs[post.fullID]) { return; } Gallery.fullIDs[post.fullID] = true; thumb = $.el('a', { className: 'gal-thumb', href: post.file.url, target: '_blank', title: post.file.name }); thumb.dataset.id = Gallery.images.length; thumb.dataset.post = post.fullID; thumbImg = post.file.thumb.cloneNode(false); thumbImg.style.cssText = ''; $.add(thumb, thumbImg); $.on(thumb, 'click', Gallery.cb.open); Gallery.images.push(thumb); return $.add(Gallery.nodes.thumbs, thumb); }, load: function(thumb, errorCB) { var elType, ext, file; ext = thumb.href.match(/\w*$/); elType = { 'webm': 'video', 'pdf': 'iframe' }[ext] || 'img'; file = $.el(elType, { title: thumb.title }); $.extend(file.dataset, thumb.dataset); $.on(file, 'error', errorCB); file.src = thumb.href; return file; }, open: function(thumb) { var el, file, newID, nodes, oldID, post, ref; nodes = Gallery.nodes; oldID = +nodes.current.dataset.id; newID = +thumb.dataset.id; if (el = Gallery.images[oldID]) { $.rmClass(el, 'gal-highlight'); } $.addClass(thumb, 'gal-highlight'); nodes.thumbs.scrollTop = thumb.offsetTop + thumb.offsetHeight / 2 - nodes.thumbs.clientHeight / 2; if (((ref = Gallery.cache) != null ? ref.dataset.id : void 0) === '' + newID) { file = Gallery.cache; $.off(file, 'error', Gallery.cacheError); $.on(file, 'error', Gallery.error); } else { file = Gallery.load(thumb, Gallery.error); } $.off(nodes.current, 'error', Gallery.error); ImageCommon.pause(nodes.current); $.replace(nodes.current, file); nodes.current = file; if (file.nodeName === 'VIDEO') { file.loop = true; Volume.setup(file); if (Conf['Autoplay']) { file.play(); } if (Conf['Show Controls']) { ImageCommon.addControls(file); } } doc.classList.toggle('gal-pdf', file.nodeName === 'IFRAME'); Gallery.cb.setHeight(); nodes.count.textContent = +thumb.dataset.id + 1; nodes.name.download = nodes.name.textContent = thumb.title; nodes.name.href = thumb.href; nodes.frame.scrollTop = 0; nodes.next.focus(); if (Gallery.slideshow && (newID > oldID || (oldID === Gallery.images.length - 1 && newID === 0))) { Gallery.setupTimer(); } else { Gallery.cb.stop(); } if (Conf['Scroll to Post'] && (post = g.posts[file.dataset.post])) { Header.scrollTo(post.nodes.root); } if (isNaN(oldID) || newID === (oldID + 1) % Gallery.images.length) { return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError); } }, error: function() { var ref; if (((ref = this.error) != null ? ref.code : void 0) === MediaError.MEDIA_ERR_DECODE) { return new Notice('error', 'Corrupt or unplayable video', 30); } if (this.src.split('/')[2] !== 'i.4cdn.org') { return; } return ImageCommon.error(this, g.posts[this.dataset.post], null, (function(_this) { return function(url) { if (!url) { return; } Gallery.images[_this.dataset.id].href = url; if (Gallery.nodes.current === _this) { return _this.src = url; } }; })(this)); }, cacheError: function() { return delete Gallery.cache; }, cleanupTimer: function() { var current; clearTimeout(Gallery.timeoutID); current = Gallery.nodes.current; $.off(current, 'canplaythrough load', Gallery.startTimer); return $.off(current, 'ended', Gallery.cb.next); }, startTimer: function() { return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * $.SECOND); }, setupTimer: function() { var current, isVideo; Gallery.cleanupTimer(); current = Gallery.nodes.current; isVideo = current.nodeName === 'VIDEO'; if (isVideo) { current.play(); } if ((isVideo ? current.readyState >= 4 : current.complete) || current.nodeName === 'IFRAME') { return Gallery.startTimer(); } else { return $.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer); } }, checkTimer: function() { var current; current = Gallery.nodes.current; if (current.nodeName === 'VIDEO' && !current.paused) { $.on(current, 'ended', Gallery.cb.next); return current.loop = false; } else { return Gallery.cb.next(); } }, cb: { keybinds: function(e) { var cb, key; if (!(key = Keybinds.keyCode(e))) { return; } cb = (function() { switch (key) { case Conf['Close']: case Conf['Open Gallery']: return Gallery.cb.close; case 'Right': return Gallery.cb.next; case 'Enter': return Gallery.cb.advance; case 'Left': case '': return Gallery.cb.prev; case Conf['Pause']: return Gallery.cb.pause; case Conf['Slideshow']: return Gallery.cb.toggleSlideshow; } })(); if (!cb) { return; } e.stopPropagation(); e.preventDefault(); return cb(); }, open: function(e) { if (e) { e.preventDefault(); } if (this) { return Gallery.open(this); } }, 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] || Gallery.images[Gallery.images.length - 1]); }, next: function() { return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0]); }, click: function(e) { if (ImageCommon.onControls(e)) { return; } e.preventDefault(); return Gallery.cb.advance(); }, advance: function() { if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { return Gallery.nodes.current.play(); } else { return Gallery.cb.next(); } }, toggle: function() { return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); }, blank: function(e) { if (e.target === this) { return Gallery.cb.close(); } }, toggleSlideshow: function() { return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); }, pause: function() { var current; Gallery.cb.stop(); current = Gallery.nodes.current; if (current.nodeName === 'VIDEO') { return current[current.paused ? 'play' : 'pause'](); } }, start: function() { $.addClass(Gallery.nodes.buttons, 'gal-playing'); Gallery.slideshow = true; return Gallery.setupTimer(); }, stop: function() { var current; if (!Gallery.slideshow) { return; } Gallery.cleanupTimer(); current = Gallery.nodes.current; if (current.nodeName === 'VIDEO') { current.loop = true; } $.rmClass(Gallery.nodes.buttons, 'gal-playing'); return Gallery.slideshow = false; }, close: function() { $.off(Gallery.nodes.current, 'error', Gallery.error); ImageCommon.pause(Gallery.nodes.current); $.rm(Gallery.nodes.el); $.rmClass(doc, 'gallery-open'); if (Conf['Fullscreen Gallery']) { $.off(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close); if (typeof d.mozCancelFullScreen === "function") { d.mozCancelFullScreen(); } if (typeof d.webkitExitFullscreen === "function") { d.webkitExitFullscreen(); } } delete Gallery.nodes; delete Gallery.fullIDs; doc.style.overflow = ''; $.off(d, 'keydown', Gallery.cb.keybinds); if (Conf['Keybinds']) { $.on(d, 'keydown', Keybinds.keydown); } return clearTimeout(Gallery.timeoutID); }, setFitness: function() { return (this.checked ? $.addClass : $.rmClass)(doc, "gal-" + (this.name.toLowerCase().replace(/\s+/g, '-'))); }, setHeight: function() { var current, dim, frame, height, minHeight, ref, ref1, ref2, style, width; ref = Gallery.nodes, current = ref.current, frame = ref.frame; style = current.style; if (Conf['Stretch to Fit'] && (dim = (ref1 = g.posts[current.dataset.post]) != null ? ref1.file.dimensions : void 0)) { ref2 = dim.split('x'), width = ref2[0], height = ref2[1]; minHeight = Math.min(doc.clientHeight - 25, height / width * frame.clientWidth); style.minHeight = minHeight + 'px'; return style.minWidth = (width / height * minHeight) + 'px'; } else { return style.minHeight = style.minWidth = null; } }, setDelay: function() { return Gallery.delay = +this.value; } }, menu: { init: function() { var el; if (!Gallery.enabled) { return; } el = $.el('span', { textContent: 'Gallery', className: 'gallery-link' }); return Header.menu.addEntry({ el: el, order: 105, subEntries: Gallery.menu.createSubEntries() }); }, createSubEntry: function(name) { var input, label; label = UI.checkbox(name, name); input = label.firstElementChild; if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height') { $.on(input, 'change', Gallery.cb.setFitness); } $.event('change', null, input); $.on(input, 'change', $.cb.checked); if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height' || name === 'Stretch to Fit') { $.on(input, 'change', Gallery.cb.setHeight); } return { el: label }; }, createSubEntries: function() { var delayInput, delayLabel, item, subEntries; subEntries = (function() { var k, len1, ref, results; ref = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post']; results = []; for (k = 0, len1 = ref.length; k < len1; k++) { item = ref[k]; results.push(Gallery.menu.createSubEntry(item)); } return results; })(); delayLabel = $.el('label', { innerHTML: "Slide Delay: " }); delayInput = delayLabel.firstElementChild; delayInput.value = Gallery.delay; $.on(delayInput, 'change', Gallery.cb.setDelay); $.on(delayInput, 'change', $.cb.value); subEntries.push({ el: delayLabel }); return subEntries; } } }; ImageCommon = { pause: function(video) { if (video.nodeName !== 'VIDEO') { return; } video.pause(); $.off(video, 'volumechange', Volume.change); return video.muted = true; }, rewind: function(el) { if (el.nodeName === 'VIDEO') { if (el.readyState >= el.HAVE_METADATA) { return el.currentTime = 0; } } else if (/\.gif$/.test(el.src)) { return $.queueTask(function() { return el.src = el.src; }); } }, pushCache: function(el) { ImageCommon.cache = el; return $.on(el, 'error', ImageCommon.cacheError); }, popCache: function() { var el; el = ImageCommon.cache; $.off(el, 'error', ImageCommon.cacheError); delete ImageCommon.cache; return el; }, cacheError: function() { if (ImageCommon.cache === this) { return delete ImageCommon.cache; } }, decodeError: function(file, post) { var message, ref; if (((ref = file.error) != null ? ref.code : void 0) !== MediaError.MEDIA_ERR_DECODE) { return false; } if (!(message = $('.warning', post.file.thumb.parentNode))) { message = $.el('div', { className: 'warning' }); $.after(post.file.thumb, message); } message.textContent = 'Error: Corrupt or unplayable video'; return true; }, error: function(file, post, delay, cb) { var URL, redirect, src, timeoutID; src = post.file.url.split('/'); URL = Redirect.to('file', { boardID: post.board.ID, filename: src[src.length - 1] }); if (!(Conf['404 Redirect'] && URL && Redirect.securityCheck(URL))) { URL = null; } if ((post.isDead || post.file.isDead) && file.src.split('/')[2] === 'i.4cdn.org') { return cb(URL); } if (delay != null) { timeoutID = setTimeout((function() { return cb(URL); }), delay); } if (post.isDead || post.file.isDead) { return; } redirect = function() { if (file.src.split('/')[2] === 'i.4cdn.org') { if (delay != null) { clearTimeout(timeoutID); } return cb(URL); } }; return $.ajax("//a.4cdn.org/" + post.board + "/thread/" + post.thread + ".json", { onload: function() { var k, len1, postObj, ref; if (this.status === 404) { post.kill(); } if (this.status !== 200) { return redirect(); } ref = this.response.posts; for (k = 0, len1 = ref.length; k < len1; k++) { postObj = ref[k]; if (postObj.no === post.ID) { break; } } if (postObj.no !== post.ID) { post.kill(); return redirect(); } else if (postObj.filedeleted) { post.kill(true); return redirect(); } else { return URL = post.file.url; } } }); }, addControls: function(video) { var handler; handler = function() { var t; $.off(video, 'mouseover', handler); t = new Date().getTime(); return $.asap((function() { return $.engine !== 'gecko' || (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || new Date().getTime() >= t + 1000; }), function() { return video.controls = true; }); }; return $.on(video, 'mouseover', handler); }, onControls: function(e) { return (Conf['Show Controls'] && Conf['Click Passthrough'] && e.target.nodeName === 'VIDEO') || (e.target.controls && e.target.getBoundingClientRect().bottom - e.clientY < 35); }, download: function(e) { if (this.protocol === 'blob:') { return true; } e.preventDefault(); return CrossOrigin.file(this.href, (function(_this) { return function(blob) { if (blob) { _this.href = URL.createObjectURL(blob); return _this.click(); } else { return new Notice('error', "Could not download " + _this.href, 30); } }; })(this)); } }; ImageExpand = { init: function() { var ref; if (!(this.enabled = Conf['Image Expansion'] && ((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) { return; } this.EAI = $.el('a', { className: 'expand-all-shortcut fa fa-expand', textContent: 'EAI', title: 'Expand All Images', href: 'javascript:;' }); $.on(this.EAI, 'click', this.cb.toggleAll); Header.addShortcut(this.EAI, 3); $.on(d, 'scroll visibilitychange', this.cb.playVideos); this.videoControls = $.el('span', { className: 'video-controls' }); $.extend(this.videoControls, { innerHTML: " contract" }); return Post.callbacks.push({ name: 'Image Expansion', cb: this.node }); }, node: function() { var ref; if (!(this.file && (this.file.isImage || this.file.isVideo))) { return; } $.on(this.file.thumb.parentNode, 'click', ImageExpand.cb.toggle); if (this.isClone) { if (this.file.isExpanding) { ImageExpand.contract(this); return ImageExpand.expand(this); } else if (this.file.isExpanded && this.file.isVideo) { Volume.setup(this.file.fullImage); ImageExpand.setupVideoCB(this); return ImageExpand.setupVideo(this, !((ref = this.origin.file.fullImage) != null ? ref.paused : void 0) || this.origin.file.wasPlaying, this.file.fullImage.controls); } } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote && (Conf['Expand spoilers'] || !this.file.isSpoiler) && (Conf['Expand videos'] || !this.file.isVideo)) { return ImageExpand.expand(this); } }, cb: { toggle: function(e) { var file, post, ref; if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } post = Get.postFromNode(this); file = post.file; if (file.isExpanded && ImageCommon.onControls(e)) { return; } e.preventDefault(); if (!Conf['Autoplay'] && ((ref = file.fullImage) != null ? ref.paused : void 0)) { return file.fullImage.play(); } else { return ImageExpand.toggle(post); } }, toggleAll: function() { var func, toggle; $.event('CloseMenu'); toggle = function(post) { var file; file = post.file; if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { return; } if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || !Conf['Expand videos'] && file.isVideo || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { return; } return $.queueTask(func, post); }; if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'; ImageExpand.EAI.title = 'Contract All Images'; func = ImageExpand.expand; } else { ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'; ImageExpand.EAI.title = 'Expand All Images'; func = ImageExpand.contract; } return g.posts.forEach(function(post) { var k, len1, ref; ref = [post].concat(slice.call(post.clones)); for (k = 0, len1 = ref.length; k < len1; k++) { post = ref[k]; toggle(post); } }); }, playVideos: function() { return g.posts.forEach(function(post) { var file, k, len1, ref, video, visible; ref = [post].concat(slice.call(post.clones)); for (k = 0, len1 = ref.length; k < len1; k++) { post = ref[k]; file = post.file; if (!(file && file.isVideo && file.isExpanded)) { continue; } video = file.fullImage; visible = ($.hasAudio(video) && !video.muted) || Header.isNodeVisible(video); if (visible && file.wasPlaying) { delete file.wasPlaying; video.play(); } else if (!visible && !video.paused) { file.wasPlaying = true; video.pause(); } } }); }, setFitness: function() { return $[this.checked ? 'addClass' : 'rmClass'](doc, this.name.toLowerCase().replace(/\s+/g, '-')); } }, toggle: function(post) { var next; if (!(post.file.isExpanding || post.file.isExpanded)) { post.file.scrollIntoView = Conf['Scroll into view']; ImageExpand.expand(post); return; } ImageExpand.contract(post); if (Conf['Advance on contract']) { next = post.nodes.root; while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { if (!($('.stub', next) || next.offsetHeight === 0)) { break; } } if (next) { return Header.scrollTo(next); } } }, contract: function(post) { var bottom, cb, el, eventName, file, k, len1, oldHeight, ref, ref1, scrollY, top, x; file = post.file; if (el = file.fullImage) { top = Header.getTopOf(el); bottom = top + el.getBoundingClientRect().height; oldHeight = d.body.clientHeight; scrollY = window.scrollY; } $.rmClass(post.nodes.root, 'expanded-image'); $.rmClass(file.thumb, 'expanding'); $.rm(file.videoControls); file.thumb.parentNode.href = file.url; file.thumb.parentNode.target = '_blank'; ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; for (k = 0, len1 = ref.length; k < len1; k++) { x = ref[k]; delete file[x]; } if (!el) { return; } if (doc.contains(el)) { if (bottom <= 0) { window.scroll(0, scrollY + d.body.clientHeight - oldHeight); } else { Header.scrollToIfNeeded(post.nodes.root); } if (window.scrollX > 0) { window.scroll(0, window.scrollY); } } $.off(el, 'error', ImageExpand.error); ImageCommon.pushCache(el); if (file.isVideo) { ImageCommon.pause(el); ref1 = ImageExpand.videoCB; for (eventName in ref1) { cb = ref1[eventName]; $.off(el, eventName, cb); } } if (Conf['Restart when Opened']) { ImageCommon.rewind(file.thumb); } delete file.fullImage; return $.queueTask(function() { if (file.isExpanding || file.isExpanded) { return; } $.rmClass(el, 'full-image'); if (el.id) { return; } return $.rm(el); }); }, expand: function(post, src) { var el, file, isVideo, ref, thumb; file = post.file; thumb = file.thumb, isVideo = file.isVideo; if (post.isHidden || file.isExpanding || file.isExpanded) { return; } $.addClass(thumb, 'expanding'); file.isExpanding = true; if (file.fullImage) { el = file.fullImage; } else if (((ref = ImageCommon.cache) != null ? ref.dataset.fullID : void 0) === post.fullID) { el = file.fullImage = ImageCommon.popCache(); $.on(el, 'error', ImageExpand.error); if (Conf['Restart when Opened'] && el.id !== 'ihover') { ImageCommon.rewind(el); } el.removeAttribute('id'); } else { el = file.fullImage = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', ImageExpand.error); el.src = src || file.url; } el.className = 'full-image'; $.after(thumb, el); if (isVideo) { if (Conf['Show Controls'] && Conf['Click Passthrough'] && !file.videoControls) { file.videoControls = ImageExpand.videoControls.cloneNode(true); $.add(file.text, file.videoControls); } thumb.parentNode.removeAttribute('href'); thumb.parentNode.removeAttribute('target'); el.loop = true; Volume.setup(el); ImageExpand.setupVideoCB(post); } if (!isVideo) { return $.asap((function() { return el.naturalHeight; }), function() { return ImageExpand.completeExpand(post); }); } else if (el.readyState >= el.HAVE_METADATA) { return ImageExpand.completeExpand(post); } else { return $.on(el, 'loadedmetadata', function() { return ImageExpand.completeExpand(post); }); } }, completeExpand: function(post) { var bottom, file, imageBottom, oldHeight, scrollY; file = post.file; if (!file.isExpanding) { return; } bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height; oldHeight = d.body.clientHeight; scrollY = window.scrollY; $.addClass(post.nodes.root, 'expanded-image'); $.rmClass(file.thumb, 'expanding'); file.isExpanded = true; delete file.isExpanding; if (doc.contains(post.nodes.root) && bottom <= 0) { window.scroll(window.scrollX, scrollY + d.body.clientHeight - oldHeight); } if (file.scrollIntoView) { delete file.scrollIntoView; imageBottom = Math.min(doc.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header.getBottomOf(file.fullImage)); if (imageBottom < 0) { window.scrollBy(0, Math.min(-imageBottom, Header.getTopOf(file.fullImage))); } } if (file.isVideo) { return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']); } }, setupVideo: function(post, playing, controls) { var fullImage; fullImage = post.file.fullImage; if (!playing) { fullImage.controls = controls; return; } fullImage.controls = false; $.asap((function() { return doc.contains(fullImage); }), function() { if (!d.hidden && Header.isNodeVisible(fullImage)) { return fullImage.play(); } else { return post.file.wasPlaying = true; } }); if (controls) { return ImageCommon.addControls(fullImage); } }, videoCB: (function() { var mousedown; mousedown = false; return { mouseover: function() { return mousedown = false; }, mousedown: function(e) { if (e.button === 0) { return mousedown = true; } }, mouseup: function(e) { if (e.button === 0) { return mousedown = false; } }, mouseout: function(e) { if (mousedown && e.clientX <= this.getBoundingClientRect().left) { return ImageExpand.toggle(Get.postFromNode(this)); } } }; })(), setupVideoCB: function(post) { var cb, eventName, ref; ref = ImageExpand.videoCB; for (eventName in ref) { cb = ref[eventName]; $.on(post.file.fullImage, eventName, cb); } if (post.file.videoControls) { return $.on(post.file.videoControls.firstElementChild, 'click', function() { return ImageExpand.toggle(post); }); } }, error: function() { var post; post = Get.postFromNode(this); $.rm(this); delete post.file.fullImage; if (!(post.file.isExpanding || post.file.isExpanded)) { return; } if (ImageCommon.decodeError(this, post)) { return ImageExpand.contract(post); } if (this.src.split('/')[2] !== 'i.4cdn.org') { return ImageExpand.contract(post); } return ImageCommon.error(this, post, 10 * $.SECOND, function(URL) { if (post.file.isExpanding || post.file.isExpanded) { ImageExpand.contract(post); if (URL) { return ImageExpand.expand(post, URL); } } }); }, menu: { init: function() { var conf, createSubEntry, el, name, ref, subEntries; if (!ImageExpand.enabled) { 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 Header.menu.addEntry({ el: el, order: 105, subEntries: subEntries }); }, createSubEntry: function(name, desc) { var input, label; label = UI.checkbox(name, name); label.title = desc; input = label.firstElementChild; if (name === 'Fit width' || name === 'Fit height') { $.on(input, 'change', ImageExpand.cb.setFitness); } $.event('change', null, input); $.on(input, 'change', $.cb.checked); return { el: label }; } } }; ImageHover = { init: function() { var ref; if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { return; } if (Conf['Image Hover']) { Post.callbacks.push({ name: 'Image Hover', cb: this.node }); } if (Conf['Image Hover in Catalog']) { return CatalogThread.callbacks.push({ name: 'Image Hover', cb: this.catalogNode }); } }, node: function() { if (!(this.file && (this.file.isImage || this.file.isVideo))) { return; } return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover(this)); }, catalogNode: function() { var file; file = this.thread.OP.file; if (!(file && (file.isImage || file.isVideo))) { return; } return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover(this.thread.OP)); }, mouseover: function(post) { return function(e) { var el, error, file, height, isVideo, left, maxHeight, maxWidth, padding, ref, ref1, ref2, right, scale, width, x; if (!doc.contains(this)) { return; } file = post.file; isVideo = file.isVideo; if (file.isExpanding || file.isExpanded) { return; } error = ImageHover.error(post); if (((ref = ImageCommon.cache) != null ? ref.dataset.fullID : void 0) === post.fullID) { el = ImageCommon.popCache(); $.on(el, 'error', error); } else { el = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', error); el.src = file.url; } if (Conf['Restart when Opened']) { ImageCommon.rewind(el); ImageCommon.rewind(this); } el.id = 'ihover'; $.add(Header.hover, el); if (isVideo) { el.loop = true; el.controls = false; Volume.setup(el); if (Conf['Autoplay']) { el.play(); } } ref1 = (function() { var k, len1, ref1, results; ref1 = file.dimensions.split('x'); results = []; for (k = 0, len1 = ref1.length; k < len1; k++) { x = ref1[k]; results.push(+x); } return results; })(), width = ref1[0], height = ref1[1]; ref2 = this.getBoundingClientRect(), left = ref2.left, right = ref2.right; padding = 25; maxWidth = Math.max(left, doc.clientWidth - right); maxHeight = doc.clientHeight - padding; scale = Math.min(1, maxWidth / width, maxHeight / height); el.style.maxWidth = (scale * width) + "px"; el.style.maxHeight = (scale * height) + "px"; return UI.hover({ root: this, el: el, latestEvent: e, endEvents: 'mouseout click', asapTest: function() { return true; }, height: scale * height + padding, noRemove: true, cb: function() { $.off(el, 'error', error); ImageCommon.pushCache(el); ImageCommon.pause(el); $.rm(el); return el.removeAttribute('style'); } }); }; }, error: function(post) { return function() { if (ImageCommon.decodeError(this, post)) { return; } return ImageCommon.error(this, post, 3 * $.SECOND, (function(_this) { return function(URL) { if (URL) { return _this.src = URL + (_this.src === URL ? '?' + Date.now() : ''); } else { return $.rm(_this); } }; })(this)); }; } }; ImageLoader = { init: function() { var prefetch, ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) { return; } if (!(Conf['Image Prefetching'] || Conf['Replace JPG'] || Conf['Replace PNG'] || Conf['Replace GIF'] || Conf['Replace WEBM'])) { return; } Post.callbacks.push({ name: 'Image Replace', cb: this.node }); $.on(d, 'PostsInserted', function() { return g.posts.forEach(ImageLoader.prefetch); }); if (Conf['Replace WEBM']) { $.on(d, 'scroll visibilitychange 4chanXInitFinished PostsInserted', this.playVideos); } if (!Conf['Image Prefetching']) { return; } prefetch = $.el('label', { innerHTML: " Prefetch Images" }); this.el = prefetch.firstElementChild; $.on(this.el, 'change', this.toggle); return Header.menu.addEntry({ el: prefetch, order: 98 }); }, node: function() { if (this.isClone || !this.file) { return; } if (Conf['Replace WEBM'] && this.file.isVideo) { ImageLoader.replaceVideo(this); } return ImageLoader.prefetch(this); }, replaceVideo: function(post) { var attr, file, k, len1, ref, thumb, video; file = post.file; thumb = file.thumb; video = $.el('video', { preload: 'none', loop: true, muted: true, poster: thumb.src || thumb.dataset.src, textContent: thumb.alt, className: thumb.className }); video.setAttribute('muted', 'muted'); video.dataset.md5 = thumb.dataset.md5; ref = ['height', 'width', 'maxHeight', 'maxWidth']; for (k = 0, len1 = ref.length; k < len1; k++) { attr = ref[k]; video.style[attr] = thumb.style[attr]; } video.src = file.url; $.replace(thumb, video); file.thumb = video; return file.videoThumb = true; }, prefetch: function(post) { var clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type, url; file = post.file; if (!file) { return; } isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { return; } type = (match = url.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; } if (![post].concat(slice.call(post.clones)).some(function(clone) { return doc.contains(clone.nodes.root); })) { return; } file.isPrefetched = true; if (file.videoThumb) { ref = post.clones; for (k = 0, len1 = ref.length; k < len1; k++) { clone = ref[k]; clone.file.thumb.preload = 'auto'; } thumb.preload = 'auto'; if ($.engine === 'gecko') { $.on(thumb, 'loadeddata', function() { return this.removeAttribute('poster'); }); } return; } el = $.el(isImage ? 'img' : 'video'); if (replace && isImage) { $.on(el, 'load', function() { var len2, q, ref1; ref1 = post.clones; for (q = 0, len2 = ref1.length; q < len2; q++) { clone = ref1[q]; clone.file.thumb.src = url; } thumb.src = url; return thumb.removeAttribute('data-src'); }); } return el.src = url; }, toggle: function() { if (Conf['prefetch'] = this.checked) { g.posts.forEach(ImageLoader.prefetch); } }, playVideos: function() { var qpClone, ref; qpClone = (ref = $.id('qp')) != null ? ref.firstElementChild : void 0; return g.posts.forEach(function(post) { var k, len1, ref1, ref2, thumb; ref1 = [post].concat(slice.call(post.clones)); for (k = 0, len1 = ref1.length; k < len1; k++) { post = ref1[k]; if (!((ref2 = post.file) != null ? ref2.videoThumb : void 0)) { continue; } thumb = post.file.thumb; if (Header.isNodeVisible(thumb) || post.nodes.root === qpClone) { thumb.play(); } else { thumb.pause(); } } }); } }; Metadata = { init: function() { var ref; if (!(Conf['WEBM Metadata'] && ((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) { return; } return Post.callbacks.push({ name: 'WEBM Metadata', cb: this.node }); }, node: function() { var el; if (!(this.file && /webm$/i.test(this.file.url))) { return; } if (this.isClone) { el = $('.webm-title', this.file.text); } else { el = $.el('span', { className: 'webm-title' }); $.extend(el, { innerHTML: "" }); $.add(this.file.text, [$.tn('\u00A0'), el]); } if (el.children.length === 1) { return $.one(el.lastElementChild, 'mouseover focus', Metadata.load); } }, load: function() { $.rmClass(this.parentNode, 'error'); $.addClass(this.parentNode, 'loading'); return CrossOrigin.binary(Get.postFromNode(this).file.url, (function(_this) { return function(data) { var output, title; $.rmClass(_this.parentNode, 'loading'); if (data != null) { title = Metadata.parse(data); output = $.el('span', { textContent: title || '' }); if (title == null) { $.addClass(_this.parentNode, 'not-found'); } $.before(_this, output); _this.parentNode.tabIndex = 0; if (d.activeElement === _this) { _this.parentNode.focus(); } return _this.tabIndex = -1; } else { $.addClass(_this.parentNode, 'error'); return $.one(_this, 'click', Metadata.load); } }; })(this), { Range: 'bytes=0-9999' }); }, parse: function(data) { var element, i, readInt, size, title; readInt = function() { var len, n; n = data[i++]; len = 0; while (n < (0x80 >> len)) { len++; } n ^= 0x80 >> len; while (len-- && i < data.length) { n = (n << 8) ^ data[i++]; } return n; }; i = 0; while (i < data.length) { element = readInt(); size = readInt(); if (element === 0x3BA9) { title = ''; while (size-- && i < data.length) { title += String.fromCharCode(data[i++]); } return decodeURIComponent(escape(title)); } else if (element !== 0x8538067 && element !== 0x549A966) { i += size; } } return null; } }; RevealSpoilers = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Reveal Spoiler Thumbnails'])) { return; } return Post.callbacks.push({ name: 'Reveal Spoiler Thumbnails', cb: this.node }); }, node: function() { var thumb; if (!(!this.isClone && this.file && this.file.thumb && this.file.isSpoiler)) { return; } thumb = this.file.thumb; thumb.removeAttribute('style'); thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; if (thumb.src) { return thumb.src = this.file.thumbURL; } else { return thumb.dataset.src = this.file.thumbURL; } } }; Sauce = { init: function() { var err, k, len1, link, links, ref, ref1; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Sauce'])) { return; } links = []; ref1 = Conf['sauces'].split('\n'); for (k = 0, len1 = ref1.length; k < len1; k++) { link = ref1[k]; try { if (link[0] !== '#') { links.push(link.trim()); } } catch (_error) { err = _error; } } if (!links.length) { return; } this.links = links; this.link = $.el('a', { target: '_blank', className: 'sauce' }); return Post.callbacks.push({ name: 'Sauce', cb: this.node }); }, sandbox: function(url) { return E.url({ innerHTML: "[sb] " + E(url) + "" }); }, rmOrigin: function(e) { if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } $.open(this.href); return e.preventDefault(); }, createSauceLink: function(link, post) { var a, ext, i, k, key, len1, m, part, parts, ref, ref1, ref2, skip, url; if (!(link = link.trim())) { return null; } parts = {}; ref = link.split(/;(?=(?:text|boards|types|sandbox):?)/); for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { part = ref[i]; if (i === 0) { parts['url'] = part; } else { m = part.match(/^(\w*):?(.*)$/); parts[m[1]] = m[2]; } } parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); ext = post.file.url.match(/[^.]*$/)[0]; skip = false; for (key in parts) { parts[key] = parts[key].replace(/%(T?URL|IMG|MD5|board|name|%|semi)/g, function(parameter) { var type; type = { '%TURL': post.file.thumbURL, '%URL': post.file.url, '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.url : post.file.thumbURL, '%MD5': post.file.MD5, '%board': post.board.ID, '%name': post.file.name, '%%': '%', '%semi': ';' }[parameter]; if (type == null) { skip = true; return ''; } if (key === 'url' && parameter !== '%%' && parameter !== '%semi') { if (/^javascript:/i.test(parts['url'])) { type = JSON.stringify(type); } type = encodeURIComponent(type); } return type; }); } if (skip) { return null; } if (!(!parts['boards'] || (ref2 = post.board.ID, indexOf.call(parts['boards'].split(','), ref2) >= 0))) { return null; } if (!(!parts['types'] || indexOf.call(parts['types'].split(','), ext) >= 0)) { return null; } url = parts['url']; if (parts['sandbox'] != null) { url = Sauce.sandbox(url); } a = Sauce.link.cloneNode(true); a.href = url; a.textContent = parts['text']; if (/^javascript:/i.test(parts['url'])) { a.removeAttribute('target'); } if (parts['sandbox'] != null) { $.on(a, 'click', Sauce.rmOrigin); } return a; }, node: function() { var k, len1, link, node, nodes, ref; if (this.isClone || !this.file) { return; } nodes = []; ref = Sauce.links; for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; if (node = Sauce.createSauceLink(link, this)) { nodes.push($.tn('\u00A0'), node); } } return $.add(this.file.text, nodes); } }; Volume = { init: function() { var ref, ref1, unmuteEntry, volumeEntry; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Image Expansion'] || Conf['Image Hover'] || Conf['Image Hover in Catalog'] || Conf['Gallery']))) { return; } $.sync('Allow Sound', function(x) { var ref1; Conf['Allow Sound'] = x; return (ref1 = Volume.inputs) != null ? ref1.unmute.checked = x : void 0; }); $.sync('Default Volume', function(x) { var ref1; Conf['Default Volume'] = x; return (ref1 = Volume.inputs) != null ? ref1.volume.value = x : void 0; }); if (Conf['Mouse Wheel Volume']) { Post.callbacks.push({ name: 'Mouse Wheel Volume', cb: this.node }); } if ((ref1 = g.BOARD.ID) !== 'gif' && ref1 !== 'wsg') { return; } if (Conf['Mouse Wheel Volume']) { CatalogThread.callbacks.push({ name: 'Mouse Wheel Volume', cb: this.catalogNode }); } unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound'); unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1]; volumeEntry = $.el('label', { title: 'Default volume for videos.' }); $.extend(volumeEntry, { innerHTML: " Volume" }); this.inputs = { unmute: unmuteEntry.firstElementChild, volume: volumeEntry.firstElementChild }; $.on(this.inputs.unmute, 'change', $.cb.checked); $.on(this.inputs.volume, 'change', $.cb.value); Header.menu.addEntry({ el: unmuteEntry, order: 200 }); return Header.menu.addEntry({ el: volumeEntry, order: 201 }); }, setup: function(video) { video.muted = !Conf['Allow Sound']; video.volume = Conf['Default Volume']; return $.on(video, 'volumechange', Volume.change); }, change: function() { var items, key, muted, val, volume; muted = this.muted, volume = this.volume; items = { 'Allow Sound': !muted, 'Default Volume': volume }; for (key in items) { val = items[key]; if (Conf[key] === val) { delete items[key]; } } $.set(items); $.extend(Conf, items); if (Volume.inputs) { Volume.inputs.unmute.checked = !muted; return Volume.inputs.volume.value = volume; } }, node: function() { var ref, ref1; if (!(((ref = this.board.ID) === 'gif' || ref === 'wsg') && ((ref1 = this.file) != null ? ref1.isVideo : void 0))) { return; } $.on(this.file.thumb, 'wheel', Volume.wheel.bind(Header.hover)); return $.on($('a', this.file.text), 'wheel', Volume.wheel.bind(this.file.thumb.parentNode)); }, catalogNode: function() { var file; file = this.thread.OP.file; if (!(file != null ? file.isVideo : void 0)) { return; } return $.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header.hover)); }, wheel: function(e) { var el, volume; if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { return; } if (!(el = $('video:not([data-md5])', this))) { return; } if (el.muted || !$.hasAudio(el)) { return; } volume = el.volume + 0.1; if (e.deltaY < 0) { volume *= 1.1; } if (e.deltaY > 0) { volume /= 1.1; } el.volume = $.minmax(volume - 0.1, 0, 1); return e.preventDefault(); } }; Embedding = { init: function() { var k, len1, ref, type; if (!(Conf['Embedding'] || Conf['Link Title'])) { return; } this.types = {}; ref = this.ordered_types; for (k = 0, len1 = ref.length; k < len1; k++) { type = ref[k]; this.types[type.key] = type; } if (Conf['Floating Embeds']) { this.dialog = UI.dialog('embedding', 'top: 50px; right: 0px;', { innerHTML: "
" }); this.media = $('#media-embed', this.dialog); $.one(d, '4chanXInitFinished', this.ready); } if (Conf['Link Title']) { return $.on(d, '4chanXInitFinished PostsInserted', function() { var key, ref1, ref2, service; ref1 = Embedding.types; for (key in ref1) { service = ref1[key]; if ((ref2 = service.title) != null ? ref2.batchSize : void 0) { Embedding.flushTitles(service.title); } } }); } }, events: function(post) { var el, i, items; if (!Conf['Embedding']) { return; } i = 0; items = $$('.embedder', post.nodes.comment); while (el = items[i++]) { $.on(el, 'click', Embedding.cb.toggle); if ($.hasClass(el, 'embedded')) { Embedding.cb.toggle.call(el); } } }, process: function(link, post) { var data; if (!(Conf['Embedding'] || Conf['Link Title'])) { return; } if ($.x('ancestor::pre', link)) { return; } if (data = Embedding.services(link)) { data.post = post; if (Conf['Embedding']) { Embedding.embed(data); } if (Conf['Link Title']) { return Embedding.title(data); } } }, services: function(link) { var href, k, len1, match, ref, type; href = link.href; ref = Embedding.ordered_types; for (k = 0, len1 = ref.length; k < len1; k++) { type = ref[k]; if (!(match = type.regExp.exec(href))) { continue; } if (type.dummy) { return; } return { key: type.key, uid: match[1], options: match[2], link: link }; } }, embed: function(data) { var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { return; } $.addClass(link, key.toLowerCase()); embed = $.el('a', { className: 'embedder', href: 'javascript:;', textContent: '(embed)' }); ref = { key: key, uid: uid, options: options, href: href }; for (name in ref) { value = ref[name]; embed.dataset[name] = value; } $.on(embed, 'click', Embedding.cb.toggle); $.after(link, [$.tn(' '), embed]); if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote && key !== 'TwitchTV') { return $.asap((function() { return doc.contains(embed); }), function() { return Embedding.cb.toggle.call(embed); }); } }, ready: function() { $.addClass(Embedding.dialog, 'empty'); $.on($('.close', Embedding.dialog), 'click', Embedding.closeFloat); $.on($('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed); $.on($('.jump', Embedding.dialog), 'click', function() { if (doc.contains(Embedding.lastEmbed)) { return Header.scrollTo(Embedding.lastEmbed); } }); return $.add(d.body, Embedding.dialog); }, closeFloat: function() { delete Embedding.lastEmbed; $.addClass(Embedding.dialog, 'empty'); return $.replace(Embedding.media.firstChild, $.el('div')); }, dragEmbed: function() { var style; style = Embedding.media.style; if (Embedding.dragEmbed.mouseup) { $.off(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = false; style.visibility = ''; return; } $.on(d, 'mouseup', Embedding.dragEmbed); Embedding.dragEmbed.mouseup = true; return style.visibility = 'hidden'; }, title: function(data) { var key, link, options, post, service, uid; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; if (!(service = Embedding.types[key].title)) { return; } $.addClass(link, key.toLowerCase()); if (service.batchSize) { (service.queue || (service.queue = [])).push(data); if (service.queue.length >= service.batchSize) { return Embedding.flushTitles(service); } } else { if (!$.cache(service.api(uid), (function() { return Embedding.cb.title(this, data); }), { responseType: 'json' })) { return $.extend(link, { innerHTML: "[" + E(key) + "] Title Link Blocked (are you using NoScript?)" }); } } }, flushTitles: function(service) { var cb, data, k, len1, queue; queue = service.queue; if (!(queue != null ? queue.length : void 0)) { return; } service.queue = []; cb = function() { var data, k, len1; for (k = 0, len1 = queue.length; k < len1; k++) { data = queue[k]; Embedding.cb.title(this, data); } }; if (!$.cache(service.api((function() { var k, len1, results; results = []; for (k = 0, len1 = queue.length; k < len1; k++) { data = queue[k]; results.push(data.uid); } return results; })()), cb, { responseType: 'json' })) { for (k = 0, len1 = queue.length; k < len1; k++) { data = queue[k]; $.extend(data.link, { innerHTML: "[" + E(data.key) + "] Title Link Blocked (are you using NoScript?)" }); } } }, cb: { toggle: function(e) { var div; if (e != null) { e.preventDefault(); } if (Conf['Floating Embeds']) { if (!(div = Embedding.media.firstChild)) { return; } $.replace(div, Embedding.cb.embed(this)); Embedding.lastEmbed = Get.postFromNode(this).nodes.root; $.rmClass(Embedding.dialog, 'empty'); return; } if ($.hasClass(this, "embedded")) { $.rm(this.nextElementSibling); this.textContent = '(embed)'; } else { $.after(this, Embedding.cb.embed(this)); this.textContent = '(unembed)'; } return $.toggleClass(this, 'embedded'); }, embed: function(a) { var container, el, type; container = $.el('div'); $.add(container, el = (type = Embedding.types[a.dataset.key]).el(a)); el.style.cssText = type.style != null ? type.style : "border:0;width:640px;height:390px"; return container; }, title: function(req, data) { var base1, k, key, len1, len2, link, link2, options, post, post2, q, ref, ref1, service, status, text, uid; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; status = req.status; service = Embedding.types[key].title; text = "[" + key + "] " + ((function() { switch (status) { case 200: case 304: return service.text(req.response, uid); case 404: return "Not Found"; case 403: return "Forbidden or Private"; default: return status + "'d"; } })()); link.dataset.original = link.textContent; link.textContent = text; ref = post.clones; for (k = 0, len1 = ref.length; k < len1; k++) { post2 = ref[k]; ref1 = $$('a.linkify', post2.nodes.comment); for (q = 0, len2 = ref1.length; q < len2; q++) { link2 = ref1[q]; if (!(link2.href === link.href)) { continue; } if ((base1 = link2.dataset).original == null) { base1.original = link2.textContent; } link2.textContent = text; } } } }, ordered_types: [ { key: 'audio', regExp: /\.(?:mp3|ogg|wav)(?:\?|$)/i, style: '', el: function(a) { return $.el('audio', { controls: true, preload: 'auto', src: a.dataset.href }); } }, { key: 'Gist', regExp: /^\w+:\/\/gist\.github\.com\/(?:[\w\-]+\/)?(\w+)/, el: function(a) { var content, el; el = $.el('iframe'); el.setAttribute('sandbox', 'allow-scripts'); content = { innerHTML: "" + E(a.dataset.uid) + "" }; el.src = E.url(content); return el; }, 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; } } } } }, { key: 'image', regExp: /\.(?:gif|png|jpg|jpeg|bmp)(?:\?|$)/i, style: '', el: function(a) { return $.el('div', { innerHTML: "" }); } }, { key: 'InstallGentoo', regExp: /^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/, el: function(a) { return $.el('iframe', { src: "https://paste.installgentoo.com/view/embed/" + a.dataset.uid }); } }, { key: 'Twitter', regExp: /^\w+:\/\/(?:www\.)?twitter\.com\/(\w+\/status\/\d+)/, el: function(a) { return $.el('iframe', { src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid }); } }, { key: 'LiveLeak', regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*i=(\w+)/, httpOnly: true, style: 'border: none; width: 640px; height: 360px;', el: function(a) { var el; el = $.el('iframe', { src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid }); el.setAttribute("allowfullscreen", "true"); return el; } }, { key: 'Pastebin', regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w\.]+\?i\=)?(\w+)/, httpOnly: true, el: function(a) { var div; return div = $.el('iframe', { src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid }); } }, { key: 'Gfycat', regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/, el: function(a) { var div; return div = $.el('iframe', { src: "//gfycat.com/iframe/" + a.dataset.uid }); } }, { key: 'SoundCloud', regExp: /^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/, style: 'border: 0; width: 500px; height: 400px;', el: function(a) { return $.el('iframe', { src: "https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(a.dataset.uid)) }); }, title: { api: function(uid) { return "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(uid)); }, text: function(_) { return _.title; } } }, { key: 'StrawPoll', regExp: /^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/, style: 'border: 0; width: 600px; height: 406px;', el: function(a) { return $.el('iframe', { src: "//strawpoll.me/embed_1/" + a.dataset.uid }); } }, { key: 'TwitchTV', regExp: /^\w+:\/\/(?:www\.)?twitch\.tv\/(\w[^#\&\?]*)/, style: "border: none; width: 620px; height: 378px;", el: function(a) { var _, channel, flashvars, id, idprefix, k, len1, obj, part, ref, result, seconds, start, type; if (result = /(\w+)\/([bcv])\/(\d+)/i.exec(a.dataset.uid)) { _ = result[0], channel = result[1], type = result[2], id = result[3]; idprefix = type === 'b' ? 'a' : type; flashvars = "channel=" + channel + "&start_volume=25&auto_play=false&videoId=" + idprefix + id; if (start = a.dataset.href.match(/\bt=(\w+)/)) { seconds = 0; ref = start[1].match(/\d+[hms]/g); for (k = 0, len1 = ref.length; k < len1; k++) { part = ref[k]; seconds += +part.slice(0, -1) * { 'h': 3600, 'm': 60, 's': 1 }[part.slice(-1)]; } flashvars += "&initial_time=" + seconds; } } else { channel = (/(\w+)/.exec(a.dataset.uid))[0]; flashvars = "channel=" + channel + "&start_volume=25&auto_play=false"; } obj = $.el('object', { data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf' }); $.extend(obj, { innerHTML: "" }); obj.children[1].value = flashvars; return obj; } }, { key: 'Vocaroo', regExp: /^\w+:\/\/(?:www\.)?vocaroo\.com\/i\/(\w+)/, style: '', el: function(a) { var el, type; el = $.el('audio', { controls: true, preload: 'auto' }); type = el.canPlayType('audio/ogg') ? 'ogg' : 'mp3'; el.src = "http://vocaroo.com/media_command.php?media=" + a.dataset.uid + "&command=download_" + type; return el; } }, { key: 'Vimeo', regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/, 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=https://vimeo.com/" + uid; }, text: function(_) { return _.title; } } }, { key: 'Vine', regExp: /^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/, style: 'border: none; width: 500px; height: 500px;', el: function(a) { return $.el('iframe', { src: "https://vine.co/v/" + a.dataset.uid + "/card" }); } }, { key: 'YouTube', regExp: /^\w+:\/\/(?:youtu.be\/|[\w\.]*youtube[\w\.]*\/.*(?:v=|\/embed\/|\/v\/|\/videos\/))([\w\-]{11})[^#\&\?]?(.*)/, el: function(a) { var el, start; start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/); if (start) { start = start[1]; } if (start && !/^\d+$/.test(start)) { start += ' 0h0m0s'; start = 3600 * start.match(/(\d+)h/)[1] + 60 * start.match(/(\d+)m/)[1] + 1 * start.match(/(\d+)s/)[1]; } el = $.el('iframe', { src: "//www.youtube.com/embed/" + a.dataset.uid + "?wmode=opaque" + (start ? '&start=' + start : '') }); el.setAttribute("allowfullscreen", "true"); return el; }, title: { batchSize: 50, api: function(uids) { var ids, key; ids = encodeURIComponent(uids.join(',')); key = 'AIzaSyB5_zaen_-46Uhz1xGR-lz1YoUMHqCD6CE'; return "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" + ids + "&fields=items%28id%2Csnippet%28title%29%29&key=" + key; }, text: function(data, uid) { var item, k, len1, ref; ref = data.items; for (k = 0, len1 = ref.length; k < len1; k++) { item = ref[k]; if (item.id === uid) { return item.snippet.title; } } return 'Not Found'; } } }, { key: 'Loopvid', regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|mf|pc|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, style: 'max-width: 80vw; max-height: 80vh;', el: function(a) { var _, base, el, host, k, len1, len2, name, names, q, ref, ref1, type, types, url; el = $.el('video', { controls: true, preload: 'auto', loop: true }); ref = a.dataset.uid.match(/(\w+)\/(.*)/), _ = ref[0], host = ref[1], names = ref[2]; types = (function() { switch (host) { case 'gd': case 'wu': case 'fc': return ['']; case 'gc': return ['giant', 'fat', 'zippy']; default: return ['.webm', '.mp4']; } })(); ref1 = names.split(','); for (k = 0, len1 = ref1.length; k < len1; k++) { name = ref1[k]; for (q = 0, len2 = types.length; q < len2; q++) { type = types[q]; base = "" + name + type; url = (function() { switch (host) { case 'pf': return "https://web.archive.org/web/2/http://a.pomf.se/" + base; case 'kd': return "http://kastden.org/loopvid/" + base; case 'lv': return "http://kastden.org/_loopvid_media/lv/" + base; case 'gd': return "https://docs.google.com/uc?export=download&id=" + base; case 'gh': return "https://googledrive.com/host/" + base; case 'db': return "https://dl.dropboxusercontent.com/u/" + base; case 'dx': return "https://dl.dropboxusercontent.com/" + base; case 'nn': return "http://naenara.eu/loopvids/" + base; case 'cp': return "https://copy.com/" + base; case 'wu': return "http://webmup.com/" + base + "/vid.webm"; case 'ig': return "https://i.imgur.com/" + base; case 'ky': return "https://kiyo.me/" + base; case 'mf': return "https://d.maxfile.ro/" + base; case 'pc': return "http://a.pomf.cat/" + base; case 'fc': return "//i.4cdn.org/" + base + ".webm"; case 'gc': return "https://" + type + ".gfycat.com/" + name + ".webm"; } })(); $.add(el, $.el('source', { src: url })); } } return el; } }, { key: 'Clyp', regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w+)/, style: '', el: function(a) { var el, type; el = $.el('audio', { controls: true, preload: 'auto' }); type = el.canPlayType('audio/ogg') ? 'ogg' : 'mp3'; el.src = "https://clyp.it/" + a.dataset.uid + "." + type; return el; } }, { key: 'Loopvid-dummy', regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\//, dummy: true }, { key: 'MediaFire-dummy', regExp: /^\w+:\/\/(?:www\.)?mediafire.com\//, dummy: true }, { key: 'video', regExp: /\.(?:ogv|webm|mp4)(?:\?|$)/i, style: 'max-width: 80vw; max-height: 80vh;', el: function(a) { return $.el('video', { controls: true, preload: 'auto', src: a.dataset.href, loop: /^https?:\/\/i\.4cdn\.org\//.test(a.dataset.href) }); } } ] }; Linkify = { init: function() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Linkify']) { return; } if (Conf['Comment Expansion']) { ExpandComment.callbacks.push(this.node); } Post.callbacks.push({ name: 'Linkify', cb: this.node }); CatalogThread.callbacks.push({ name: 'Linkify', cb: this.catalogNode }); return Embedding.init(); }, node: function() { var k, len1, len2, link, links, q, ref; if (this.isClone) { return Embedding.events(this); } if (!Linkify.regString.test(this.info.comment)) { return; } ref = $$('a[href^="http://i.4cdn.org/"], a[href^="https://i.4cdn.org/"]', this.nodes.comment); for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; $.addClass(link, 'linkify'); Embedding.process(link, this); } links = Linkify.process(this.nodes.comment); for (q = 0, len2 = links.length; q < len2; q++) { link = links[q]; Embedding.process(link, this); } }, catalogNode: function() { if (!Linkify.regString.test(this.thread.OP.info.comment)) { return; } return Linkify.process(this.nodes.comment); }, process: function(node) { var data, end, endNode, i, index, length, links, ref, ref1, result, saved, snapshot, space, test, word; test = /[^\s"]+/g; space = /[\s"]/; snapshot = $.X('.//br|.//text()', node); i = 0; links = []; while (node = snapshot.snapshotItem(i++)) { data = node.data; if (!data || node.parentElement.nodeName === "A") { 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') { if (/^(https?:\/\/)?[a-z0-9\-\.]+$/i.test(word) && ((ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z0-9\-]+)*\//i) : void 0 : void 0)) { continue; } else { break; } } endNode = saved; data = saved.data; if (end = space.exec(data)) { word += data.slice(0, end.index); test.lastIndex = length = end.index; i--; break; } else { length = data.length; word += data; } } } if (Linkify.regString.test(word)) { links.push(Linkify.makeRange(node, endNode, index, length)); } if (!(test.lastIndex && node === endNode)) { break; } } } i = links.length; while (i--) { links[i] = Linkify.makeLink(links[i]); } return links; }, regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, 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, encodedDomain, i, t, text; text = range.toString(); i = text.search(Linkify.regString); if (i > 0) { 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(t = text.charAt(text.length - (1 + i)))) { if (!(/[.,]/.test(t) || (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 (!/((mailto|magnet):|.+:\/\/)/.test(text)) { text = (/@/.test(text) ? 'mailto:' : 'http://') + text; } if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { if (y === '25') { return x; } else { return String.fromCharCode(parseInt(y, 16)); } }) + encodedDomain[2]; } a = $.el('a', { className: 'linkify', rel: 'nofollow noreferrer', target: '_blank', href: text }); $.add(a, range.extractContents()); range.insertNode(a); range.detach(); return a; } }; ArchiveLink = { init: function() { var div, entry, k, len1, ref, ref1, type; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Archive Link'])) { return; } div = $.el('div', { textContent: 'Archive' }); entry = { 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: [] }; ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']]; for (k = 0, len1 = ref1.length; k < len1; k++) { type = ref1[k]; entry.subEntries.push(this.createSubEntry(type[0], type[1])); } return Menu.menu.addEntry(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 = { auto: [{}, {}], init: function() { var div, fileEl, fileEntry, postEl, postEntry, ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && 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:;' }); this.nodes = { menu: div.firstChild, links: [postEl, fileEl] }; postEntry = { el: postEl, open: function() { postEl.textContent = DeleteLink.linkText(false); $.on(postEl, 'click', DeleteLink.toggle); return true; } }; fileEntry = { el: fileEl, open: function(arg) { var file; file = arg.file; if (!file || file.isDead) { return false; } fileEl.textContent = DeleteLink.linkText(true); $.on(fileEl, 'click', DeleteLink.toggle); return true; } }; return Menu.menu.addEntry({ el: div, order: 40, open: function(post) { if (post.isDead) { return false; } DeleteLink.post = post; DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); DeleteLink.cooldown.start(post); return true; }, subEntries: [postEntry, fileEntry] }); }, menuText: function() { var seconds; if (seconds = DeleteLink.cooldown.seconds[DeleteLink.post.fullID]) { return "Delete (" + seconds + ")"; } else { return 'Delete'; } }, linkText: function(fileOnly) { var text; text = fileOnly ? 'File' : 'Post'; if (DeleteLink.auto[+fileOnly][DeleteLink.post.fullID]) { text = "Deleting " + (text.toLowerCase()) + "..."; } return text; }, toggle: function() { var auto, fileOnly, post; post = DeleteLink.post; fileOnly = $.hasClass(this, 'delete-file'); auto = DeleteLink.auto[+fileOnly]; if (auto[post.fullID]) { delete auto[post.fullID]; } else { auto[post.fullID] = true; } this.textContent = DeleteLink.linkText(fileOnly); if (!DeleteLink.cooldown.seconds[post.fullID]) { return DeleteLink["delete"](post, fileOnly); } }, "delete": function(post, fileOnly) { var form, link; link = DeleteLink.nodes.links[+fileOnly]; delete DeleteLink.auto[+fileOnly][post.fullID]; if (post.fullID === DeleteLink.post.fullID) { $.off(link, 'click', DeleteLink.toggle); } form = { mode: 'usrdel', onlyimgdel: fileOnly, pwd: QR.persona.getPassword() }; form[post.ID] = 'delete'; 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, post); } }, { form: $.formData(form) }); }, load: function(link, post, fileOnly, resDoc) { var el, msg; link.textContent = DeleteLink.linkText(fileOnly); if (resDoc.title === '4chan - Banned') { el = $.el('span', { innerHTML: "You can't delete posts because you are banned." }); return new Notice('warning', el, 20); } else if (msg = resDoc.getElementById('errmsg')) { new Notice('warning', msg.textContent, 20); if (post.fullID === DeleteLink.post.fullID) { $.on(link, 'click', DeleteLink.toggle); } if (Conf['Quick Reply'] && Conf['Cooldown'] && /\bwait\b/i.test(msg.textContent)) { DeleteLink.cooldown.start(post, 5); DeleteLink.auto[+fileOnly][post.fullID] = true; return DeleteLink.nodes.links[+fileOnly].textContent = DeleteLink.linkText(fileOnly); } } else { if (!fileOnly) { QR.cooldown["delete"](post); } if (resDoc.title === 'Updating index...') { (post.origin || post).kill(fileOnly); } if (post.fullID === DeleteLink.post.fullID) { return link.textContent = 'Deleted'; } } }, error: function(link, post) { new Notice('warning', 'Connection error, please retry.', 20); if (post.fullID === DeleteLink.post.fullID) { return $.on(link, 'click', DeleteLink.toggle); } }, cooldown: { seconds: {}, start: function(post, seconds) { if (DeleteLink.cooldown.seconds[post.fullID] != null) { return; } if (seconds == null) { seconds = QR.cooldown.secondsDeletion(post); } if (seconds > 0) { DeleteLink.cooldown.seconds[post.fullID] = seconds; return DeleteLink.cooldown.count(post); } }, count: function(post) { var fileOnly, k, len1, ref; if (post.fullID === DeleteLink.post.fullID) { DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); } if (DeleteLink.cooldown.seconds[post.fullID] > 0) { DeleteLink.cooldown.seconds[post.fullID]--; setTimeout(DeleteLink.cooldown.count, 1000, post); } else { delete DeleteLink.cooldown.seconds[post.fullID]; ref = [false, true]; for (k = 0, len1 = ref.length; k < len1; k++) { fileOnly = ref[k]; if (DeleteLink.auto[+fileOnly][post.fullID]) { DeleteLink["delete"](post, fileOnly); } } } } } }; DownloadLink = { init: function() { var a, ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Download Link'])) { return; } a = $.el('a', { className: 'download-link', textContent: 'Download file' }); $.on(a, 'click', ImageCommon.download); return Menu.menu.addEntry({ 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() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'])) { return; } this.button = $.el('a', { className: 'menu-button', href: 'javascript:;' }); $.extend(this.button, { innerHTML: "" }); this.menu = new UI.Menu('post'); Post.callbacks.push({ name: 'Menu', cb: this.node }); return CatalogThread.callbacks.push({ name: 'Menu', cb: this.catalogNode }); }, node: function() { if (this.isClone) { Menu.makeButton(this, $('.menu-button', this.nodes.info)); return; } return $.add(this.nodes.info, Menu.makeButton(this)); }, catalogNode: function() { return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP)); }, makeButton: function(post, button) { button || (button = Menu.button.cloneNode(true)); $.on(button, 'click', function(e) { return Menu.menu.toggle(e, this, post); }); return button; } }; ReportLink = { init: function() { var a, ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Report Link'])) { return; } a = $.el('a', { className: 'report-link', href: 'javascript:;' }); $.on(a, 'click', ReportLink.report); return Menu.menu.addEntry({ el: a, order: 10, open: function(post) { if (!(post.isDead || (post.thread.isDead && !post.thread.isArchived))) { a.textContent = 'Report this post'; ReportLink.url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post; ReportLink.height = 180; } else if (Conf['Archive Report']) { a.textContent = 'Report to archive'; ReportLink.url = Redirect.to('report', { boardID: post.board.ID, postID: post.ID }); ReportLink.height = 350; } else { ReportLink.url = ''; } return !!ReportLink.url; } }); }, report: function() { var height, id, set, url; url = ReportLink.url, height = ReportLink.height; id = Date.now(); set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=700,height=" + height; return window.open(url, id, set); } }; Favicon = { init: function() { return $.asap((function() { return d.head && (Favicon.el = $('link[rel="shortcut icon"]', d.head)); }), Favicon.initAsap); }, initAsap: function() { var href; Favicon.el.type = 'image/x-icon'; href = Favicon.el.href; Favicon.SFW = /ws\.ico$/.test(href); Favicon["default"] = href; return Favicon["switch"](); }, "switch": function() { var f, i, items, t; items = { ferongr: ['iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///9zBQC/AADpDAP/gID/q6voCwJJTwpOAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8AcH4AtswA2PJ55fKi6fIA1/FtpPADAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8oeQBJ3ABV/wHM/7Lu/+ZU/gAqUP3dAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg=='], 'xat-': ['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'], Mayhem: ['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'], '4chanJS': ['iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AABnZ2f///8nFk05AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AAD///9nZ2f77Y6hAAAAAXRSTlMAQObYZgAAAEBJREFUeF6NjQEKACAMAnfW/98cAxFiBIngOsTqR8B1IGkeG9p5i7XabgAGZNigXgA8aoCUxvzWAIcBItGiSEwdccYA3BuRAWkAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8NnZ2f////82iC9AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8P///9nZ2cgIeMlAAAAAXRSTlMAQObYZgAAAEBJREFUeF6NjQEKACAMAnfW/98cAxFiBIngOsTqR8B1IGkeG9p5i7XabgAGZNigXgA8aoCUxvzWAIcBItGiSEwdccYA3BuRAWkAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDNlyjJnZ2f///+6o7dfAAAAAXRSTlMAQObYZgAAAERJREFUeF6NjkEKADEIA51o///lJZfQxUsHITogWi8AvwZJuxmYa25xDooBLEwOWFTYAsYVhdorLZt9Ng9xCUTCUCQ2H3F4ANrZ2WNiAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDP///9lyjJnZ2cIHys9AAAAAXRSTlMAQObYZgAAAENJREFUeF6NjUEKwEAMAjNm9/9fLkEslFwqgjoEUn8EfAqSdrkwzj6ieyyTkQEVGWRvANfO1iEX620AjgBEwqR4Y+sBeGAA6d+vQ4IAAAAASUVORK5CYII='], Original: ['iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX/////AAD///8AAABBZmS3AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///8ul8P///8AAACaqgkzAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///9mzDP///8AAACT0n1lAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC'], 'Metro': ['iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAHAAAdAAApAAAsAAA4AABsAACQAAC/AAD///9SVhtjAAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAACAkAISUALzQAMTcAQEcAeokAorYA1/H///8BrzTFAAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAADCgANKAASOAATOwAZTAAwkQBAwQBV/wH////+Fmy4AAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC'] }[Conf['favicon']]; f = Favicon; t = 'data:image/png;base64,'; i = 0; while (items[i]) { items[i] = t + items[i++]; } f.unreadDead = items[0], f.unreadDeadY = items[1], f.unreadSFW = items[2], f.unreadSFWY = items[3], f.unreadNSFW = items[4], f.unreadNSFWY = items[5]; return f.update(); }, update: function() { if (this.SFW) { this.unread = this.unreadSFW; return this.unreadY = this.unreadSFWY; } else { this.unread = this.unreadNSFW; return this.unreadY = this.unreadNSFWY; } }, dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==', logo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg==' }; MarkNewIPs = { init: function() { if (g.VIEW !== 'thread' || !Conf['Mark New IPs']) { return; } return Thread.callbacks.push({ name: 'Mark New IPs', cb: this.node }); }, node: function() { MarkNewIPs.ipCount = this.ipCount; MarkNewIPs.postCount = this.posts.keys.length; return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate); }, onUpdate: function(e) { var deletedPosts, fullID, i, ipCount, k, len1, len2, newPosts, postCount, q, ref; ref = e.detail, ipCount = ref.ipCount, postCount = ref.postCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts; if (ipCount == null) { return; } switch (ipCount - MarkNewIPs.ipCount) { case postCount - MarkNewIPs.postCount + deletedPosts.length: i = MarkNewIPs.ipCount; for (k = 0, len1 = newPosts.length; k < len1; k++) { fullID = newPosts[k]; MarkNewIPs.markNew(g.posts[fullID], ++i); } break; case -deletedPosts.length: for (q = 0, len2 = newPosts.length; q < len2; q++) { fullID = newPosts[q]; MarkNewIPs.markOld(g.posts[fullID]); } } MarkNewIPs.ipCount = ipCount; return MarkNewIPs.postCount = postCount; }, markNew: function(post, ipCount) { var counter, suffix; suffix = (Math.floor(ipCount / 10)) % 10 === 1 ? 'th' : ['st', 'nd', 'rd'][ipCount % 10 - 1] || 'th'; counter = $.el('span', { className: 'ip-counter', textContent: "(" + ipCount + ")" }); post.nodes.nameBlock.title = "This is the " + ipCount + suffix + " IP in the thread."; $.add(post.nodes.nameBlock, [$.tn(' '), counter]); return $.addClass(post.nodes.root, 'new-ip'); }, markOld: function(post) { post.nodes.nameBlock.title = 'Not the first post from this IP.'; return $.addClass(post.nodes.root, 'old-ip'); } }; ThreadExcerpt = { init: function() { if (g.BOARD.ID !== 'f' || g.VIEW !== 'thread' || !Conf['Thread Excerpt']) { return; } return Thread.callbacks.push({ name: 'Thread Excerpt', cb: this.node }); }, node: function() { return d.title = Get.threadExcerpt(this); } }; ThreadStats = { init: function() { var sc, statsHTML, statsTitle; if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { return; } statsHTML = { innerHTML: "? / ?" + (Conf["IP Count in Stats"] ? " / ?" : "") + (Conf["Page Count in Stats"] && g.BOARD.ID !== "f" ? " / ?" : "") }; statsTitle = 'Posts / Files'; if (Conf['IP Count in Stats']) { statsTitle += ' / IPs'; } if (Conf['Page Count in Stats'] && g.BOARD.ID !== 'f') { statsTitle += ' / Page'; } if (Conf['Updater and Stats in Header']) { this.dialog = sc = $.el('span', { id: 'thread-stats', title: statsTitle }); $.extend(sc, statsHTML); $.ready(function() { return Header.addShortcut(sc); }); } else { this.dialog = sc = UI.dialog('thread-stats', 'bottom: 0px; right: 0px;', { innerHTML: "
" + statsHTML.innerHTML + "
" }); $.addClass(doc, 'float'); $.ready(function() { return $.add(d.body, sc); }); } this.postCountEl = $('#post-count', sc); this.fileCountEl = $('#file-count', sc); this.ipCountEl = $('#ip-count', sc); this.pageCountEl = $('#page-count', sc); if (this.pageCountEl) { $.on(this.pageCountEl, 'click', ThreadStats.fetchPage); } return Thread.callbacks.push({ name: 'Thread Stats', cb: this.node }); }, node: function() { var fileCount, postCount; postCount = 0; fileCount = 0; this.posts.forEach(function(post) { postCount++; if (post.file) { fileCount++; } if (ThreadStats.pageCountEl) { return ThreadStats.lastPost = post.info.date; } }); ThreadStats.thread = this; ThreadStats.fetchPage(); ThreadStats.update(postCount, fileCount, this.ipCount); return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); }, onUpdate: function(e) { var fileCount, ipCount, newPosts, postCount, ref, ref1; if (e.detail[404]) { return; } ref = e.detail, postCount = ref.postCount, fileCount = ref.fileCount, ipCount = ref.ipCount, newPosts = ref.newPosts; ThreadStats.update(postCount, fileCount, ipCount); if (!ThreadStats.pageCountEl) { return; } if (newPosts.length) { ThreadStats.lastPost = g.posts[newPosts[newPosts.length - 1]].info.date; } if (((ref1 = ThreadStats.pageCountEl) != null ? ref1.textContent : void 0) !== '1') { return ThreadStats.fetchPage(); } }, update: function(postCount, fileCount, ipCount) { var fileCountEl, ipCountEl, postCountEl, thread; thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl, ipCountEl = ThreadStats.ipCountEl; postCountEl.textContent = postCount; fileCountEl.textContent = fileCount; if ((ipCount != null) && ipCountEl) { ipCountEl.textContent = ipCount; } (thread.postLimit && !thread.isSticky ? $.addClass : $.rmClass)(postCountEl, 'warning'); return (thread.fileLimit && !thread.isSticky ? $.addClass : $.rmClass)(fileCountEl, 'warning'); }, fetchPage: function() { if (!ThreadStats.pageCountEl) { return; } clearTimeout(ThreadStats.timeout); if (ThreadStats.thread.isDead) { ThreadStats.pageCountEl.textContent = 'Dead'; $.addClass(ThreadStats.pageCountEl, 'warning'); return; } ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 2 * $.MINUTE); return $.ajax("//a.4cdn.org/" + ThreadStats.thread.board + "/threads.json", { onload: ThreadStats.onThreadsLoad }, { whenModified: 'ThreadStats' }); }, onThreadsLoad: function() { var k, len1, len2, page, q, ref, ref1, thread; if (this.status === 200) { ref = this.response; for (k = 0, len1 = ref.length; k < len1; k++) { page = ref[k]; ref1 = page.threads; for (q = 0, len2 = ref1.length; q < len2; q++) { thread = ref1[q]; if (!(thread.no === ThreadStats.thread.ID)) { continue; } ThreadStats.pageCountEl.textContent = page.page; (page.page === this.response.length ? $.addClass : $.rmClass)(ThreadStats.pageCountEl, 'warning'); ThreadStats.lastPageUpdate = new Date(thread.last_modified * $.SECOND); ThreadStats.retry(); return; } } } else if (this.status === 304) { return ThreadStats.retry(); } }, retry: function() { var ref; if (ThreadStats.lastPost > ThreadStats.lastPageUpdate && ((ref = ThreadStats.pageCountEl) != null ? ref.textContent : void 0) !== '1') { clearTimeout(ThreadStats.timeout); return ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 5 * $.SECOND); } } }; ThreadUpdater = { init: function() { var conf, el, input, name, ref, sc, subEntries, updateLink; if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { return; } if (Conf['Updater and Stats in Header']) { this.dialog = sc = $.el('span', { id: 'updater' }); $.extend(sc, { innerHTML: "" }); $.ready(function() { return Header.addShortcut(sc); }); } else { this.dialog = sc = UI.dialog('updater', 'bottom: 0px; left: 0px;', { innerHTML: "
" }); $.addClass(doc, 'float'); $.ready(function() { return $.add(d.body, sc); }); } this.checkPostCount = 0; this.timer = $('#update-timer', sc); this.status = $('#update-status', sc); $.on(this.timer, 'click', this.update); $.on(this.status, 'click', this.update); updateLink = $.el('span', { className: 'brackets-wrap updatelink' }); $.extend(updateLink, { innerHTML: "Update" }); Main.ready(function() { return $.add($('.navLinksBot'), [$.tn(' '), updateLink]); }); $.on(updateLink.firstElementChild, 'click', this.update); subEntries = []; ref = Config.updater.checkbox; for (name in ref) { conf = ref[name]; el = UI.checkbox(name, name); el.title = conf[1]; input = el.firstElementChild; $.on(input, 'change', $.cb.checked); if (input.name === 'Scroll BG') { $.on(input, 'change', this.cb.scrollBG); this.cb.scrollBG(); } else if (input.name === 'Auto Update') { $.on(input, 'change', this.setInterval); } subEntries.push({ el: el }); } this.settings = $.el('span', { innerHTML: "Interval" }); $.on(this.settings, 'click', this.intervalShortcut); subEntries.push({ el: this.settings }); Header.menu.addEntry(this.entry = { el: $.el('span', { textContent: 'Updater' }), order: 110, subEntries: subEntries }); return Thread.callbacks.push({ name: 'Thread Updater', cb: this.node }); }, node: function() { ThreadUpdater.thread = this; ThreadUpdater.root = this.OP.nodes.root.parentNode; ThreadUpdater.outdateCount = 0; ThreadUpdater.postIDs = []; ThreadUpdater.fileIDs = []; this.posts.forEach(function(post) { ThreadUpdater.postIDs.push(post.ID); if (post.file) { return ThreadUpdater.fileIDs.push(post.ID); } }); ThreadUpdater.cb.interval.call($.el('input', { value: Conf['Interval'] })); $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); ThreadUpdater.setInterval(); if (this.board.ID === 'f') { return ThreadUpdater.update(); } }, /* 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: { checkpost: function(e) { if (e.detail.threadID !== ThreadUpdater.thread.ID) { return; } ThreadUpdater.postID = e.detail.postID; ThreadUpdater.checkPostCount = 0; ThreadUpdater.outdateCount = 0; return ThreadUpdater.setInterval(); }, visibility: function() { if (d.hidden) { return; } ThreadUpdater.outdateCount = 0; if (ThreadUpdater.seconds > ThreadUpdater.interval) { return ThreadUpdater.setInterval(); } }, scrollBG: function() { return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() { return true; } : function() { return !d.hidden; }; }, interval: function(e) { var val; val = parseInt(this.value, 10); if (val < 1) { val = 1; } ThreadUpdater.interval = this.value = val; if (e) { return $.cb.value.call(this); } }, load: function() { var req; req = ThreadUpdater.req; switch (req.status) { case 200: ThreadUpdater.parse(req); if (ThreadUpdater.thread.isArchived) { return ThreadUpdater.kill(); } else { return ThreadUpdater.setInterval(); } break; case 404: return $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", { onloadend: function() { var confirmed, k, len1, len2, page, q, ref, ref1, thread; if (this.status === 200) { confirmed = true; ref = this.response; for (k = 0, len1 = ref.length; k < len1; k++) { page = ref[k]; ref1 = page.threads; for (q = 0, len2 = ref1.length; q < len2; q++) { thread = ref1[q]; if (thread.no === ThreadUpdater.thread.ID) { confirmed = false; break; } } } } else { confirmed = false; } if (confirmed) { return ThreadUpdater.kill(); } else { return ThreadUpdater.error(req); } } }); default: return ThreadUpdater.error(req); } } }, kill: function() { ThreadUpdater.thread.kill(); ThreadUpdater.setInterval(); return $.event('ThreadUpdate', { 404: true, threadID: ThreadUpdater.thread.fullID }); }, error: function(req) { if (req.status === 304) { ThreadUpdater.set('status', ''); } ThreadUpdater.setInterval(); if (!req.status) { return ThreadUpdater.set('status', 'Connection Failed', 'warning'); } else if (req.status !== 304) { return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning'); } }, setInterval: function() { var cur, interval, j, limit; clearTimeout(ThreadUpdater.timeoutID); if (ThreadUpdater.thread.isDead) { ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning'); ThreadUpdater.set('timer', ''); return; } if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) { ThreadUpdater.set('timer', '...', 'loading'); ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND); return; } if (!Conf['Auto Update']) { ThreadUpdater.set('timer', 'Update'); return; } interval = ThreadUpdater.interval; if (Conf['Optional Increase']) { limit = d.hidden ? 10 : 5; j = Math.min(ThreadUpdater.outdateCount, limit); cur = (Math.floor(interval * 0.1) || 1) * j * j; ThreadUpdater.seconds = $.minmax(cur, interval, 300); } else { ThreadUpdater.seconds = interval; } return ThreadUpdater.timeout(); }, 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; } return el.className = klass != null ? klass : (text === '' ? 'empty' : ''); }, timeout: function() { if (ThreadUpdater.seconds) { ThreadUpdater.set('timer', ThreadUpdater.seconds); ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); } else { ThreadUpdater.outdateCount++; ThreadUpdater.update(); } return ThreadUpdater.seconds--; }, update: function() { var ref; clearTimeout(ThreadUpdater.timeoutID); ThreadUpdater.set('timer', '...', 'loading'); if ((ref = ThreadUpdater.req) != null) { ref.abort(); } return ThreadUpdater.req = $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/thread/" + ThreadUpdater.thread + ".json", { onloadend: ThreadUpdater.cb.load, timeout: $.MINUTE }, { whenModified: 'ThreadUpdater' }); }, updateThreadStatus: function(type, status) { var change, hasChanged; if (!(hasChanged = ThreadUpdater.thread["is" + type] !== status)) { return; } ThreadUpdater.thread.setStatus(type, status); if (type === 'Closed' && ThreadUpdater.thread.isArchived) { return; } change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore'; return new Notice('info', "The thread is " + change + ".", 30); }, parse: function(req) { var ID, OP, board, deletedFiles, deletedPosts, files, firstPost, index, ipCountEl, k, lastPost, len1, len2, len3, len4, newPosts, node, post, postObject, postObjects, posts, q, ref, ref1, ref2, ref3, ref4, ref5, scroll, thread, u, unreadCount, v; postObjects = req.response.posts; OP = postObjects[0]; thread = ThreadUpdater.thread; board = thread.board; ref = ThreadUpdater.postIDs, lastPost = ref[ref.length - 1]; if (postObjects[postObjects.length - 1].no < lastPost && new Date(req.getResponseHeader('Last-Modified')) - thread.posts[lastPost].info.date < 30 * $.SECOND) { return; } Build.spoilerRange[board] = OP.custom_spoiler; thread.setStatus('Archived', !!OP.archived); ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); ThreadUpdater.updateThreadStatus('Closed', !!OP.closed); thread.postLimit = !!OP.bumplimit; thread.fileLimit = !!OP.imagelimit; if (OP.unique_ips != null) { thread.ipCount = OP.unique_ips; } posts = []; index = []; files = []; newPosts = []; for (k = 0, len1 = postObjects.length; k < len1; k++) { postObject = postObjects[k]; ID = postObject.no; index.push(ID); if (postObject.fsize) { files.push(ID); } if (board.ID === 'f' && postObject.fsize && (post = thread.posts[ID]) && !post.file) { node = Build.postFromObject(postObject, board.ID); $.after(post.nodes.info, $('.file', node)); post.parseFile(); Post.callbacks.execute(post, ['Filter', 'File Info Formatting', 'Fappe Tyme', 'Sauce']); } if (ID <= lastPost) { continue; } if ((post = thread.posts[ID]) && !post.isFetchedQuote) { post.resurrect(); continue; } newPosts.push(board + "." + ID); node = Build.postFromObject(postObject, board.ID); posts.push(new Post(node, thread, board)); if (ThreadUpdater.postID === ID) { delete ThreadUpdater.postID; } } deletedPosts = []; ref1 = ThreadUpdater.postIDs; for (q = 0, len2 = ref1.length; q < len2; q++) { ID = ref1[q]; if (!(indexOf.call(index, ID) < 0)) { continue; } thread.posts[ID].kill(); deletedPosts.push(board + "." + ID); } ThreadUpdater.postIDs = index; deletedFiles = []; ref2 = ThreadUpdater.fileIDs; for (u = 0, len3 = ref2.length; u < len3; u++) { ID = ref2[u]; if (!(!(indexOf.call(files, ID) >= 0 || (ref3 = board + "." + ID, indexOf.call(deletedPosts, ref3) >= 0)))) { continue; } thread.posts[ID].kill(true); deletedFiles.push(board + "." + ID); } ThreadUpdater.fileIDs = files; if (!posts.length) { ThreadUpdater.set('status', ''); } else { ThreadUpdater.set('status', "+" + posts.length, 'new'); ThreadUpdater.outdateCount = 0; unreadCount = (ref4 = Unread.posts) != null ? ref4.size : void 0; Main.callbackNodes(Post, posts); if (Conf['Beep'] && d.hidden && unreadCount === 0 && ((ref5 = Unread.posts) != null ? ref5.size : void 0)) { if (!ThreadUpdater.audio) { ThreadUpdater.audio = $.el('audio', { src: ThreadUpdater.beep }); } ThreadUpdater.audio.play(); } scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25; firstPost = null; for (v = 0, len4 = posts.length; v < len4; v++) { post = posts[v]; if (!QuoteThreading.insert(post)) { firstPost || (firstPost = post.nodes.root); $.add(ThreadUpdater.root, post.nodes.root); } } $.event('PostsInserted'); if (scroll) { if (Conf['Bottom Scroll']) { window.scrollTo(0, d.body.clientHeight); } else { if (firstPost) { Header.scrollTo(firstPost); } } } } if ((OP.unique_ips != null) && (ipCountEl = $.id('unique-ips'))) { ipCountEl.textContent = OP.unique_ips; ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are'); ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters'); } return $.event('ThreadUpdate', { 404: false, threadID: thread.fullID, newPosts: newPosts, deletedPosts: deletedPosts, deletedFiles: deletedFiles, postCount: OP.replies + 1, fileCount: OP.images + !!OP.fsize, ipCount: OP.unique_ips }); } }; ThreadWatcher = { init: function() { var sc; if (!Conf['Thread Watcher']) { return; } this.shortcut = sc = $.el('a', { id: 'watcher-link', textContent: 'Watcher', title: 'Thread Watcher', href: 'javascript:;', className: 'disabled fa fa-eye' }); this.db = new DataBoard('watchedThreads', this.refresh, true); this.dialog = UI.dialog('thread-watcher', 'top: 50px; left: 0px;', { innerHTML: "
Thread Watcher ×
" }); this.status = $('#watcher-status', this.dialog); this.list = this.dialog.lastElementChild; this.refreshButton = $('.refresh', this.dialog); this.closeButton = $('.move > .close', this.dialog); this.unreaddb = Unread.db || new DataBoard('lastReadPosts'); $.on(d, 'QRPostSuccessful', this.cb.post); $.on(sc, 'click', this.toggleWatcher); $.on(this.refreshButton, 'click', this.buttonFetchAll); $.on(this.closeButton, 'click', this.toggleWatcher); $.on(d, '4chanXInitFinished', this.ready); switch (g.VIEW) { case 'index': $.on(d, 'IndexRefresh', this.cb.onIndexRefresh); break; case 'thread': $.on(d, 'ThreadUpdate', this.cb.onThreadRefresh); } if (Conf['Fixed Thread Watcher']) { $.addClass(doc, 'fixed-watcher'); } if (Conf['Toggleable Thread Watcher']) { this.dialog.hidden = true; Header.addShortcut(sc); $.addClass(doc, 'toggleable-watcher'); } ThreadWatcher.fetchAuto(); if (g.VIEW === 'index' && Conf['JSON Navigation'] && Conf['Menu'] && g.BOARD.ID !== 'f') { Menu.menu.addEntry({ el: $.el('a', { href: 'javascript:;' }), order: 6, open: function(arg) { var thread; thread = arg.thread; if (Conf['Index Mode'] !== 'catalog') { return false; } this.el.textContent = ThreadWatcher.isWatched(thread) ? 'Unwatch thread' : 'Watch thread'; if (this.cb) { $.off(this.el, 'click', this.cb); } this.cb = function() { $.event('CloseMenu'); return ThreadWatcher.toggle(thread); }; $.on(this.el, 'click', this.cb); return true; } }); } Post.callbacks.push({ name: 'Thread Watcher', cb: this.node }); return CatalogThread.callbacks.push({ name: 'Thread Watcher', cb: this.catalogNode }); }, isWatched: function(thread) { var ref; return (ref = ThreadWatcher.db) != null ? ref.get({ boardID: thread.board.ID, threadID: thread.ID }) : void 0; }, node: function() { var toggler; if (this.isReply) { return; } if (this.isClone) { toggler = $('.watch-thread-link', this.nodes.post); } else { toggler = $.el('a', { href: 'javascript:;', className: 'watch-thread-link' }); $.before($('input', this.nodes.post), toggler); } return $.on(toggler, 'click', ThreadWatcher.cb.toggle); }, catalogNode: function() { if (ThreadWatcher.isWatched(this.thread)) { $.addClass(this.nodes.root, 'watched'); } $.on(this.nodes.thumb.parentNode, 'click', (function(_this) { return function(e) { if (!(e.button === 0 && e.altKey)) { return; } ThreadWatcher.toggle(_this.thread); return e.preventDefault(); }; })(this)); return $.on(this.nodes.thumb.parentNode, 'mousedown', function(e) { if (e.button === 0 && e.altKey) { return e.preventDefault(); } }); }, ready: function() { $.off(d, '4chanXInitFinished', ThreadWatcher.ready); if (!Main.isThisPageLegit()) { return; } ThreadWatcher.refresh(); $.add(d.body, ThreadWatcher.dialog); 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, k, len1, ref; if ($.hasClass(this, 'disabled')) { return; } ref = $$('a[title]', ThreadWatcher.list); for (k = 0, len1 = ref.length; k < len1; k++) { a = ref[k]; $.open(a.href); } return $.event('CloseMenu'); }, pruneDeads: function() { var boardID, data, k, len1, ref, ref1, threadID; if ($.hasClass(this, 'disabled')) { return; } ThreadWatcher.db.forceSync(); ref = ThreadWatcher.getAll(); for (k = 0, len1 = ref.length; k < len1; k++) { ref1 = ref[k], 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() { var thread; thread = Get.postFromNode(this).thread; Index.followedThreadID = thread.ID; ThreadWatcher.toggle(thread); return delete Index.followedThreadID; }, rm: function() { var boardID, ref, threadID; ref = this.parentNode.dataset.fullID.split('.'), boardID = ref[0], threadID = ref[1]; return ThreadWatcher.rm(boardID, +threadID); }, post: function(e) { var boardID, postID, ref, threadID; ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; if (postID === threadID) { if (Conf['Auto Watch']) { return $.set('AutoWatch', threadID); } } else if (Conf['Auto Watch Reply']) { return ThreadWatcher.add(g.threads[boardID + '.' + threadID]); } }, onIndexRefresh: function() { var boardID, data, db, ref, threadID; db = ThreadWatcher.db; boardID = g.BOARD.ID; db.forceSync(); ref = db.data.boards[boardID]; for (threadID in ref) { data = ref[threadID]; if (!(data != null ? data.isDead : void 0) && !(threadID in g.BOARD.threads)) { if (Conf['Auto Prune'] || !(data && typeof data === 'object')) { db["delete"]({ boardID: boardID, threadID: threadID }); } else { if (Conf['Show Unread Count']) { ThreadWatcher.fetchStatus({ boardID: boardID, threadID: threadID, data: data }); } data.isDead = true; db.set({ boardID: boardID, threadID: threadID, val: data }); } } } return ThreadWatcher.refresh(); }, onThreadRefresh: function(e) { var thread; thread = g.threads[e.detail.threadID]; if (!(e.detail[404] && ThreadWatcher.db.get({ boardID: thread.board.ID, threadID: thread.ID }))) { return; } return ThreadWatcher.add(thread); } }, requests: [], fetched: 0, clearRequests: function() { ThreadWatcher.requests = []; ThreadWatcher.fetched = 0; ThreadWatcher.status.textContent = ''; return $.rmClass(ThreadWatcher.refreshButton, 'fa-spin'); }, abort: function() { var k, len1, ref, req; ref = ThreadWatcher.requests; for (k = 0, len1 = ref.length; k < len1; k++) { req = ref[k]; if (req.readyState !== 4) { req.abort(); } } return ThreadWatcher.clearRequests(); }, fetchAuto: function() { var db, interval, now; clearTimeout(ThreadWatcher.timeout); if (!Conf['Auto Update Thread Watcher']) { return; } db = ThreadWatcher.db; interval = Conf['Show Unread Count'] ? 5 * $.MINUTE : 2 * $.HOUR; now = Date.now(); if (now >= (db.data.lastChecked || 0) + interval) { db.data.lastChecked = now; ThreadWatcher.fetchAllStatus(); db.save(); } return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval); }, buttonFetchAll: function() { if (ThreadWatcher.requests.length) { return ThreadWatcher.abort(); } else { return ThreadWatcher.fetchAllStatus(); } }, fetchAllStatus: function() { var k, len1, ref, thread, threads; ThreadWatcher.db.forceSync(); ThreadWatcher.unreaddb.forceSync(); if ((ref = QR.db) != null) { ref.forceSync(); } if (!(threads = ThreadWatcher.getAll()).length) { return; } for (k = 0, len1 = threads.length; k < len1; k++) { thread = threads[k]; ThreadWatcher.fetchStatus(thread); } }, fetchStatus: function(thread, force) { var boardID, data, req, threadID; boardID = thread.boardID, threadID = thread.threadID, data = thread.data; if (data.isDead && !force) { return; } if (ThreadWatcher.requests.length === 0) { ThreadWatcher.status.textContent = '...'; $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); } req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", { onloadend: function() { return ThreadWatcher.parseStatus.call(this, thread); }, timeout: $.MINUTE }, { whenModified: force ? false : 'ThreadWatcher' }); return ThreadWatcher.requests.push(req); }, parseStatus: function(arg) { var boardID, data, isDead, k, lastReadPost, len1, match, postObj, quotesYou, quotingYou, ref, ref1, regexp, threadID, unread; boardID = arg.boardID, threadID = arg.threadID, data = arg.data; ThreadWatcher.fetched++; if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { ThreadWatcher.clearRequests(); } else { ThreadWatcher.status.textContent = (Math.round(ThreadWatcher.fetched / ThreadWatcher.requests.length * 100)) + "%"; } if (this.status === 200 && this.response) { isDead = !!this.response.posts[0].archived; if (isDead && Conf['Auto Prune']) { ThreadWatcher.db["delete"]({ boardID: boardID, threadID: threadID }); ThreadWatcher.refresh(); return; } lastReadPost = ThreadWatcher.unreaddb.get({ boardID: boardID, threadID: threadID, defaultValue: 0 }); unread = quotingYou = 0; ref = this.response.posts; for (k = 0, len1 = ref.length; k < len1; k++) { postObj = ref[k]; if (!(postObj.no > lastReadPost)) { continue; } if ((ref1 = QR.db) != null ? ref1.get({ boardID: boardID, threadID: threadID, postID: postObj.no }) : void 0) { continue; } unread++; if (!(QR.db && postObj.com)) { continue; } quotesYou = false; regexp = /]*\bhref="(?:\/([^\/]+)\/thread\/)?(\d+)?(?:#p(\d+))?"/g; while (match = regexp.exec(postObj.com)) { if (QR.db.get({ boardID: match[1] || boardID, threadID: match[2] || threadID, postID: match[3] || match[2] || threadID })) { quotesYou = true; break; } } if (quotesYou && !Filter.isHidden(Build.parseJSON(postObj, boardID))) { quotingYou++; } } if (isDead !== data.isDead || unread !== data.unread || quotingYou !== data.quotingYou) { data.isDead = isDead; data.unread = unread; data.quotingYou = quotingYou; ThreadWatcher.db.set({ boardID: boardID, threadID: threadID, val: data }); return ThreadWatcher.refresh(); } } else if (this.status === 404) { if (Conf['Auto Prune']) { ThreadWatcher.db["delete"]({ boardID: boardID, threadID: threadID }); } else { data.isDead = true; delete data.unread; delete data.quotingYou; ThreadWatcher.db.set({ boardID: boardID, threadID: threadID, val: data }); } return ThreadWatcher.refresh(); } }, getAll: function() { var all, boardID, data, ref, threadID, threads; 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]; if (data && typeof data === 'object') { all.push({ boardID: boardID, threadID: threadID, data: data }); } } } return all; }, makeLine: function(boardID, threadID, data) { var count, div, fullID, link, title, x; x = $.el('a', { className: 'fa fa-times', href: 'javascript:;' }); $.on(x, 'click', ThreadWatcher.cb.rm); link = $.el('a', { href: "/" + boardID + "/thread/" + threadID, title: data.excerpt, className: 'watcher-link' }); if (Conf['Show Unread Count'] && (data.unread != null)) { count = $.el('span', { textContent: "(" + data.unread + ")", className: 'watcher-unread' }); $.add(link, count); } title = $.el('span', { textContent: data.excerpt, className: 'watcher-title' }); $.add(link, title); 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'); } if (Conf['Show Unread Count']) { if (data.unread === 0) { $.addClass(div, 'replies-read'); } if (data.unread) { $.addClass(div, 'replies-unread'); } if (data.quotingYou) { $.addClass(div, 'replies-quoting-you'); } } $.add(div, [x, $.tn(' '), link]); return div; }, refresh: function() { var boardID, data, k, len1, len2, list, nodes, q, ref, ref1, ref2, refresher, threadID; nodes = []; ref = ThreadWatcher.getAll(); for (k = 0, len1 = ref.length; k < len1; k++) { ref1 = ref[k], boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; nodes.push(ThreadWatcher.makeLine(boardID, threadID, data)); } list = ThreadWatcher.list; $.rmAll(list); $.add(list, nodes); g.threads.forEach(function(thread) { var helper, len2, post, q, ref2, toggler; helper = ThreadWatcher.isWatched(thread) ? ['addClass', 'Unwatch'] : ['rmClass', 'Watch']; if (thread.OP) { ref2 = [thread.OP].concat(slice.call(thread.OP.clones)); for (q = 0, len2 = ref2.length; q < len2; q++) { post = ref2[q]; toggler = $('.watch-thread-link', post.nodes.post); $[helper[0]](toggler, 'watched'); toggler.title = helper[1] + " Thread"; } } if (thread.catalogView) { return $[helper[0]](thread.catalogView.nodes.root, 'watched'); } }); ThreadWatcher.refreshIcon(); ref2 = ThreadWatcher.menu.refreshers; for (q = 0, len2 = ref2.length; q < len2; q++) { refresher = ref2[q]; refresher(); } if (Index.nodes && Conf['Pin Watched Threads']) { Index.sort(); return Index.buildIndex(); } }, refreshIcon: function() { var className, k, len1, ref; ref = ['replies-unread', 'replies-quoting-you']; for (k = 0, len1 = ref.length; k < len1; k++) { className = ref[k]; ThreadWatcher.shortcut.classList.toggle(className, !!$("." + className, ThreadWatcher.dialog)); } }, update: function(boardID, threadID, newData) { var data, key, line, n, newLine, ref, val; if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ boardID: boardID, threadID: threadID }) : void 0)) { return; } if (newData.isDead && Conf['Auto Prune']) { ThreadWatcher.db["delete"]({ boardID: boardID, threadID: threadID }); ThreadWatcher.refresh(); return; } n = 0; for (key in newData) { val = newData[key]; if (data[key] !== val) { n++; } } if (!n) { return; } ThreadWatcher.db.forceSync(); if (!(data = ThreadWatcher.db.get({ boardID: boardID, threadID: threadID }))) { return; } $.extend(data, newData); ThreadWatcher.db.set({ boardID: boardID, threadID: threadID, val: data }); if (line = $("#watched-threads > [data-full-i-d='" + boardID + "." + threadID + "']", ThreadWatcher.dialog)) { newLine = ThreadWatcher.makeLine(boardID, threadID, data); $.replace(line, newLine); return ThreadWatcher.refreshIcon(); } else { return ThreadWatcher.refresh(); } }, set404: function(boardID, threadID, cb) { var data, ref; if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ boardID: boardID, threadID: threadID }) : void 0)) { return cb(); } if (Conf['Auto Prune']) { ThreadWatcher.db["delete"]({ boardID: boardID, threadID: threadID }); return cb(); } if (data.isDead && !((data.unread != null) || (data.quotingYou != null))) { return cb(); } data.isDead = true; delete data.unread; delete data.quotingYou; return ThreadWatcher.db.set({ boardID: boardID, threadID: threadID, val: data }, cb); }, 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 }); ThreadWatcher.refresh(); if (Conf['Show Unread Count']) { return ThreadWatcher.fetchStatus({ boardID: boardID, threadID: threadID, data: data }, true); } }, rm: function(boardID, threadID) { ThreadWatcher.db["delete"]({ boardID: boardID, threadID: threadID }); return ThreadWatcher.refresh(); }, menu: { refreshers: [], init: function() { var menu; if (!Conf['Thread Watcher']) { return; } menu = this.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:;' }); Header.menu.addEntry({ el: entryEl, order: 60 }); $.on(entryEl, 'click', function() { return ThreadWatcher.toggle(g.threads[g.BOARD + "." + g.THREADID]); }); return this.refreshers.push(function() { var addClass, ref, rmClass, text; 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, k, len1, name, ref, ref1, refresh, subEntries; entries = []; entries.push({ cb: ThreadWatcher.cb.openAll, entry: { el: $.el('a', { textContent: 'Open all threads' }) }, refresh: function() { return (ThreadWatcher.list.firstElementChild ? $.rmClass : $.addClass)(this.el, 'disabled'); } }); entries.push({ cb: ThreadWatcher.cb.pruneDeads, entry: { el: $.el('a', { textContent: 'Prune dead 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: { el: $.el('span', { textContent: 'Settings' }), subEntries: subEntries } }); for (k = 0, len1 = entries.length; k < len1; k++) { ref1 = entries[k], 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)); } this.menu.addEntry(entry); } }, createSubEntry: function(name, desc) { var entry, input; entry = { type: 'thread watcher', el: UI.checkbox(name, name.replace(' Thread Watcher', '')) }; entry.el.title = desc; input = entry.el.firstElementChild; $.on(input, 'change', $.cb.checked); if (name === 'Current Board' || name === 'Show Unread Count') { $.on(input, 'change', ThreadWatcher.refresh); } if (name === 'Show Unread Count' || name === 'Auto Update Thread Watcher') { $.on(input, 'change', ThreadWatcher.fetchAuto); } return entry; } } }; Unread = { init: function() { if (!(g.VIEW === 'thread' && (Conf['Unread Count'] || Conf['Unread Favicon'] || Conf['Unread Line'] || Conf['Scroll to Last Read Post'] || Conf['Thread Watcher'] || Conf['Desktop Notifications'] || Conf['Quote Threading']))) { return; } this.db = new DataBoard('lastReadPosts', this.sync); this.hr = $.el('hr', { id: 'unread-line' }); this.posts = new Set(); this.postsQuotingYou = new Set(); this.order = new RandomAccessList(); this.position = null; Thread.callbacks.push({ name: 'Unread', cb: this.node }); return Post.callbacks.push({ name: 'Unread', cb: this.addPost }); }, node: function() { var ID, k, len1, ref; Unread.thread = this; Unread.title = d.title; Unread.lastReadPost = Unread.db.get({ boardID: this.board.ID, threadID: this.ID, defaultValue: 0 }); Unread.readCount = 0; ref = this.posts.keys; for (k = 0, len1 = ref.length; k < len1; k++) { ID = ref[k]; if (+ID <= Unread.lastReadPost) { Unread.readCount++; } } $.one(d, '4chanXInitFinished', Unread.ready); return $.on(d, 'ThreadUpdate', Unread.onUpdate); }, ready: function() { Unread.setLine(true); Unread.read(); Unread.update(); if (Conf['Scroll to Last Read Post']) { Unread.scroll(); } $.on(d, 'scroll visibilitychange', Unread.read); if (Conf['Unread Line']) { return $.on(d, 'visibilitychange', Unread.setLine); } }, positionPrev: function() { if (Unread.position) { return Unread.position.prev; } else { return Unread.order.last; } }, scroll: function() { var hash, position, root; if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } position = Unread.positionPrev(); while (position) { root = position.data.nodes.root; if (!root.getBoundingClientRect().height) { position = position.prev; } else { Header.scrollToIfNeeded(root, true); break; } } }, sync: function() { var ID, i, k, lastReadPost, postIDs, ref, ref1; if (Unread.lastReadPost == null) { return; } lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, defaultValue: 0 }); if (!(Unread.lastReadPost < lastReadPost)) { return; } Unread.lastReadPost = lastReadPost; postIDs = Unread.thread.posts.keys; for (i = k = ref = Unread.readCount, ref1 = postIDs.length; k < ref1; i = k += 1) { ID = +postIDs[i]; if (!Unread.thread.posts[ID].isFetchedQuote) { if (ID > Unread.lastReadPost) { break; } Unread.posts["delete"](ID); Unread.postsQuotingYou["delete"](ID); } Unread.readCount++; } Unread.updatePosition(); Unread.setLine(); return Unread.update(); }, addPost: function() { var ref; if (this.isFetchedQuote || this.isClone) { return; } Unread.order.push(this); if (this.ID <= Unread.lastReadPost || this.isHidden || ((ref = QR.db) != null ? ref.get({ boardID: this.board.ID, threadID: this.thread.ID, postID: this.ID }) : void 0)) { return; } Unread.posts.add(this.ID); Unread.addPostQuotingYou(this); return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID]; }, addPostQuotingYou: function(post) { var k, len1, quotelink, ref, ref1; ref = post.nodes.quotelinks; for (k = 0, len1 = ref.length; k < len1; k++) { quotelink = ref[k]; if (!((ref1 = QR.db) != null ? ref1.get(Get.postDataFromLink(quotelink)) : void 0)) { continue; } Unread.postsQuotingYou.add(post.ID); Unread.openNotification(post); return; } }, openNotification: function(post) { var notif; if (!Header.areNotificationsEnabled) { return; } try { notif = new Notification(post.info.nameBlock + " replied to you", { body: post.info.commentDisplay, icon: Favicon.logo }); notif.onclick = function() { Header.scrollToIfNeeded(post.nodes.root, true); return window.focus(); }; return notif.onshow = function() { return setTimeout(function() { return notif.close(); }, 7 * $.SECOND); }; } catch (_error) {} }, onUpdate: function(e) { if (!e.detail[404]) { Unread.setLine(); Unread.read(); } return Unread.update(); }, readSinglePost: function(post) { var ID; ID = post.ID; if (!Unread.posts.has(ID)) { return; } Unread.posts["delete"](ID); Unread.postsQuotingYou["delete"](ID); Unread.updatePosition(); Unread.saveLastReadPost(); return Unread.update(); }, read: $.debounce(100, function(e) { var ID, count, data, height, ref, ref1, root; if (!Unread.posts.size && Unread.readCount !== Unread.thread.posts.keys.length) { Unread.saveLastReadPost(); } if (d.hidden || !Unread.posts.size) { return; } height = doc.clientHeight; count = 0; while (Unread.position) { ref = Unread.position, ID = ref.ID, data = ref.data; root = data.nodes.root; if (!(!root.getBoundingClientRect().height || Header.getBottomOf(root) > -1)) { break; } count++; Unread.posts["delete"](ID); Unread.postsQuotingYou["delete"](ID); if (Conf['Mark Quotes of You'] && ((ref1 = QR.db) != null ? ref1.get({ boardID: data.board.ID, threadID: data.thread.ID, postID: ID }) : void 0)) { QuoteYou.lastRead = root; } Unread.position = Unread.position.next; } if (!count) { return; } Unread.updatePosition(); Unread.saveLastReadPost(); if (e) { return Unread.update(); } }), updatePosition: function() { while (Unread.position && !Unread.posts.has(Unread.position.ID)) { Unread.position = Unread.position.next; } }, saveLastReadPost: $.debounce(2 * $.SECOND, function() { var ID, i, k, postIDs, ref, ref1; postIDs = Unread.thread.posts.keys; for (i = k = ref = Unread.readCount, ref1 = postIDs.length; k < ref1; i = k += 1) { ID = +postIDs[i]; if (!Unread.thread.posts[ID].isFetchedQuote) { if (Unread.posts.has(ID)) { break; } Unread.lastReadPost = ID; } Unread.readCount++; } if (Unread.thread.isDead && !Unread.thread.isArchived) { return; } Unread.db.forceSync(); return Unread.db.set({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, val: Unread.lastReadPost }); }), setLine: function(force) { if (!Conf['Unread Line']) { return; } if (Unread.hr.hidden || d.hidden || (force === true)) { if (Unread.linePosition = Unread.positionPrev()) { $.after(Unread.linePosition.data.nodes.root, Unread.hr); } else { $.rm(Unread.hr); } } return Unread.hr.hidden = Unread.linePosition === Unread.order.last; }, update: function() { var count, countQuotingYou, isDead, titleCount, titleDead, titleQuotingYou; count = Unread.posts.size; countQuotingYou = Unread.postsQuotingYou.size; if (Conf['Unread Count']) { titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : ''; titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : ''; titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title; d.title = "" + titleQuotingYou + titleCount + titleDead; } if (!(Unread.thread.isDead && !Unread.thread.isArchived)) { ThreadWatcher.update(Unread.thread.board.ID, Unread.thread.ID, { isDead: Unread.thread.isDead, unread: count, quotingYou: countQuotingYou }); } if (Conf['Unread Favicon']) { isDead = Unread.thread.isDead; Favicon.el.href = countQuotingYou ? Favicon[isDead ? 'unreadDeadY' : 'unreadY'] : count ? Favicon[isDead ? 'unreadDead' : 'unread'] : Favicon[isDead ? 'dead' : 'default']; return $.add(d.head, Favicon.el); } } }; Redirect = { init: function() { var archive, archives, boardID, boards, data, files, id, k, len1, len2, name, o, q, record, ref, ref1, software, type, uid, withCredentials; o = { thread: {}, post: {}, file: {}, report: {} }; archives = {}; ref = Redirect.archives; for (k = 0, len1 = ref.length; k < len1; k++) { data = ref[k]; uid = data.uid, name = data.name, boards = data.boards, files = data.files, software = data.software, withCredentials = data.withCredentials; archives[JSON.stringify(uid != null ? uid : name)] = data; for (q = 0, len2 = boards.length; q < len2; q++) { boardID = boards[q]; if (!withCredentials) { if (!(boardID in o.thread)) { o.thread[boardID] = data; } if (!(boardID in o.post || software !== 'foolfuuka')) { o.post[boardID] = data; } if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) { o.file[boardID] = data; } } if (name === 'fgts') { o.report[boardID] = data; } } } ref1 = Conf['selectedArchives']; for (boardID in ref1) { record = ref1[boardID]; for (type in record) { id = record[type]; if (id === null) { delete o[type][boardID]; } else if (archive = archives[JSON.stringify(id)]) { boards = type === 'file' ? archive.files : archive.boards; if (indexOf.call(boards, boardID) >= 0) { o[type][boardID] = archive; } } } } return Redirect.data = o; }, archives: [{"uid":3,"name":"4plebs","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","sp","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","sp","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u"],"files":["c","d","e","i","lgbt","t","u"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","gd","h","hc","hm","n","out","p","po","qa","r","s","soc","toy","vp","y"],"files":["asp","b","cm","gd","h","hc","hm","n","out","p","po","qa","r","s","soc","toy","vp","y"]},{"uid":23,"name":"Desustorage","domain":"desustorage.org","http":true,"https":true,"software":"foolfuuka","boards":["a","aco","an","c","co","d","fit","his","int","k","m","mlp","qa","r9k","tg","trash","vr","wsg"],"files":["a","aco","an","c","co","d","fit","his","int","k","m","mlp","qa","r9k","tg","trash","vr","wsg"]},{"uid":24,"name":"fireden.net","domain":"boards.fireden.net","http":false,"https":true,"software":"foolfuuka","boards":["a","cm","ic","sci","tg","v","vg","y"],"files":["a","cm","ic","sci","tg","v","vg","y"]},{"uid":25,"name":"arch.b4k.co","domain":"arch.b4k.co","http":true,"https":true,"software":"foolfuuka","boards":["g","mlp","v"],"files":[]},{"uid":27,"name":"4ch.be","domain":"4ch.be","http":false,"https":true,"software":"foolfuuka","boards":["3","a","aco","adv","an","asp","b","biz","c","cgl","ck","cm","co","d","diy","e","f","fa","fit","g","gd","gif","h","hc","his","hm","hr","i","ic","int","jp","k","lgbt","lit","m","mlp","mu","n","news","o","out","p","po","pol","qa","r","r9k","s","s4s","sci","soc","sp","t","tg","toy","trash","trv","tv","u","v","vg","vp","vr","w","wg","wsg","x","y"],"files":[],"search":["a","aco","adv","an","asp","b","biz","c","cgl","ck","cm","co","d","diy","e","f","fa","fit","g","gd","gif","h","hc","his","hm","hr","i","ic","int","jp","k","lgbt","lit","m","mlp","mu","n","news","o","out","p","po","pol","qa","r","r9k","s","s4s","sci","soc","sp","t","tg","toy","trash","trv","tv","u","v","vg","vp","vr","w","wg","wsg","x","y"]}], to: function(dest, data) { var archive; archive = (dest === 'search' || dest === 'board' ? 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 boardID, postID, protocol, url; boardID = arg.boardID, postID = arg.postID; protocol = Redirect.protocol(archive); url = "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; if (!Redirect.securityCheck(url)) { return ''; } 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; }, board: function(archive, arg) { var boardID; boardID = arg.boardID; return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/"; }, 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; if (type === 'capcode') { value = { 'Developer': 'dev' }[value] || value.toLowerCase(); } 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; }, report: function(archive, arg) { var boardID, postID; boardID = arg.boardID, postID = arg.postID; return "https://so.fgts.jp/report/?board=" + boardID + "&no=" + postID; }, securityCheck: function(url) { return /^https:\/\//.test(url) || location.protocol === 'http:' || Conf['Exempt Archives from Encryption']; }, navigate: function(dest, data, alternative) { var url; if (!Redirect.data) { Redirect.init(); } url = Redirect.to(dest, data); if (url && (Redirect.securityCheck(url) || confirm("Redirect to " + url + "?\n\nYour connection will not be encrypted."))) { return location.replace(url); } else if (alternative) { return location.replace(alternative); } } }; PSAHiding = { init: function() { if (!Conf['Announcement Hiding']) { return; } $.addClass(doc, 'hide-announcement'); return $.one(d, '4chanXInitFinished', this.setup); }, setup: function() { var btn, entry, hr, psa, ref; if (!(psa = PSAHiding.psa = $.id('globalMessage'))) { $.rmClass(doc, 'hide-announcement'); return; } if ((hr = (ref = $.id('globalToggle')) != null ? ref.previousElementSibling : void 0) && hr.nodeName === 'HR') { PSAHiding.hr = hr; } entry = { el: $.el('a', { textContent: 'Show announcement', className: 'show-announcement', href: 'javascript:;' }), order: 50, open: function() { return PSAHiding.hidden; } }; Header.menu.addEntry(entry); $.on(entry.el, 'click', PSAHiding.toggle); PSAHiding.btn = btn = $.el('span', { title: 'Mark announcement as read and hide.', className: 'hide-announcement' }); $.extend(btn, { innerHTML: "[Dismiss]" }); $.on(btn, 'click', PSAHiding.toggle); $.get('hiddenPSA', 0, function(arg) { var hiddenPSA; hiddenPSA = arg.hiddenPSA; PSAHiding.sync(hiddenPSA); $.add(psa, btn); return $.rmClass(doc, 'hide-announcement'); }); return $.sync('hiddenPSA', PSAHiding.sync); }, toggle: function() { 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 psa, ref; psa = PSAHiding.psa; PSAHiding.hidden = PSAHiding.btn.hidden = (UTC != null) && UTC >= +psa.dataset.utc; if (PSAHiding.hidden) { $.rm(psa); } else { $.after($.id('globalToggle'), psa); } if ((ref = PSAHiding.hr) != null) { ref.hidden = PSAHiding.hidden; } } }; AntiAutoplay = { init: function() { var audio, k, len1, ref; if (!Conf['Disable Autoplaying Sounds']) { return; } $.addClass(doc, 'anti-autoplay'); ref = $$('audio[autoplay]', doc); for (k = 0, len1 = ref.length; k < len1; k++) { audio = ref[k]; this.stop(audio); } window.addEventListener('loadstart', ((function(_this) { return function(e) { return _this.stop(e.target); }; })(this)), true); Post.callbacks.push({ name: 'Disable Autoplaying Sounds', cb: this.node }); CatalogThread.callbacks.push({ name: 'Disable Autoplaying Sounds', cb: this.node }); return $.ready((function(_this) { return function() { return _this.process(d.body); }; })(this)); }, stop: function(audio) { if (!audio.autoplay) { return; } audio.pause(); audio.autoplay = false; if (audio.controls) { return; } audio.controls = true; return $.addClass(audio, 'controls-added'); }, node: function() { return AntiAutoplay.process(this.nodes.root); }, process: function(root) { var iframe, k, len1, len2, object, q, ref, ref1; ref = $$('iframe[src*="youtube"][src*="autoplay=1"]', root); for (k = 0, len1 = ref.length; k < len1; k++) { iframe = ref[k]; iframe.src = iframe.src.replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', ''); $.addClass(iframe, 'autoplay-removed'); } ref1 = $$('object[data*="youtube"][data*="autoplay=1"]', root); for (q = 0, len2 = ref1.length; q < len2; q++) { object = ref1[q]; object.data = object.data.replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', ''); $.addClass(object, 'autoplay-removed'); } } }; Banner = { banners: ["0.jpg","1.jpg","2.jpg","4.jpg","6.jpg","7.jpg","8.jpg","9.jpg","10.jpg","11.jpg","12.jpg","13.jpg","14.jpg","16.jpg","17.jpg","18.jpg","19.jpg","20.jpg","21.jpg","22.jpg","24.jpg","25.jpg","26.jpg","28.jpg","29.jpg","33.jpg","38.jpg","39.jpg","43.jpg","44.jpg","45.jpg","46.jpg","47.jpg","52.jpg","54.jpg","57.jpg","59.jpg","60.jpg","61.jpg","64.jpg","66.jpg","67.jpg","69.jpg","71.jpg","72.jpg","76.jpg","77.jpg","81.jpg","82.jpg","83.jpg","84.jpg","88.jpg","90.jpg","91.jpg","96.jpg","98.jpg","99.jpg","100.jpg","104.jpg","106.jpg","116.jpg","119.jpg","137.jpg","140.jpg","148.jpg","149.jpg","150.jpg","154.jpg","156.jpg","157.jpg","158.jpg","159.jpg","161.jpg","162.jpg","164.jpg","165.jpg","166.jpg","167.jpg","168.jpg","169.jpg","170.jpg","171.jpg","172.jpg","173.jpg","174.jpg","175.jpg","176.jpg","178.jpg","179.jpg","180.jpg","181.jpg","182.jpg","183.jpg","186.jpg","189.jpg","190.jpg","192.jpg","193.jpg","194.jpg","197.jpg","198.jpg","200.jpg","201.jpg","202.jpg","203.jpg","205.jpg","206.jpg","207.jpg","208.jpg","210.jpg","213.jpg","214.jpg","215.jpg","216.jpg","218.jpg","219.jpg","220.jpg","221.jpg","222.jpg","223.jpg","224.jpg","227.jpg","0.png","1.png","2.png","3.png","5.png","6.png","9.png","10.png","11.png","12.png","14.png","16.png","19.png","20.png","21.png","22.png","23.png","24.png","26.png","27.png","28.png","29.png","30.png","31.png","32.png","33.png","34.png","37.png","39.png","40.png","41.png","42.png","43.png","44.png","45.png","48.png","49.png","50.png","51.png","52.png","53.png","57.png","58.png","59.png","64.png","66.png","67.png","68.png","69.png","70.png","71.png","72.png","76.png","78.png","79.png","81.png","82.png","85.png","86.png","87.png","89.png","95.png","98.png","100.png","101.png","102.png","105.png","106.png","107.png","109.png","110.png","111.png","112.png","113.png","114.png","115.png","116.png","118.png","119.png","120.png","121.png","122.png","123.png","126.png","128.png","130.png","134.png","136.png","138.png","139.png","140.png","142.png","145.png","146.png","149.png","150.png","151.png","152.png","153.png","154.png","155.png","156.png","157.png","158.png","159.png","160.png","163.png","164.png","165.png","166.png","167.png","168.png","169.png","170.png","171.png","172.png","173.png","174.png","178.png","179.png","180.png","181.png","182.png","184.png","186.png","188.png","190.png","192.png","193.png","194.png","195.png","196.png","197.png","198.png","200.png","202.png","203.png","205.png","206.png","207.png","209.png","212.png","213.png","214.png","216.png","217.png","218.png","219.png","220.png","221.png","222.png","223.png","224.png","225.png","226.png","229.png","231.png","232.png","233.png","234.png","235.png","237.png","238.png","239.png","240.png","241.png","242.png","244.png","245.png","246.png","247.png","248.png","249.png","250.png","253.png","254.png","255.png","256.png","257.png","258.png","259.png","260.png","262.png","268.png","0.gif","1.gif","2.gif","3.gif","4.gif","5.gif","6.gif","7.gif","8.gif","9.gif","10.gif","12.gif","13.gif","14.gif","15.gif","16.gif","18.gif","19.gif","20.gif","21.gif","22.gif","23.gif","24.gif","28.gif","29.gif","30.gif","33.gif","34.gif","35.gif","36.gif","37.gif","39.gif","40.gif","42.gif","44.gif","45.gif","46.gif","48.gif","50.gif","52.gif","54.gif","55.gif","57.gif","58.gif","59.gif","60.gif","61.gif","63.gif","64.gif","66.gif","67.gif","68.gif","69.gif","70.gif","72.gif","73.gif","75.gif","76.gif","77.gif","78.gif","80.gif","81.gif","82.gif","83.gif","86.gif","87.gif","88.gif","92.gif","93.gif","94.gif","95.gif","96.gif","97.gif","98.gif","99.gif","100.gif","101.gif","102.gif","103.gif","104.gif","105.gif","106.gif","108.gif","109.gif","110.gif","111.gif","112.gif","113.gif","115.gif","116.gif","117.gif","118.gif","119.gif","120.gif","122.gif","123.gif","124.gif","127.gif","129.gif","130.gif","131.gif","134.gif","135.gif","136.gif","138.gif","139.gif","141.gif","144.gif","146.gif","148.gif","149.gif","153.gif","154.gif","155.gif","157.gif","158.gif","159.gif","160.gif","161.gif","162.gif","164.gif","166.gif","167.gif","168.gif","169.gif","170.gif","171.gif","172.gif","173.gif","174.gif","175.gif","176.gif","177.gif","178.gif","181.gif","182.gif","183.gif","185.gif","186.gif","187.gif","188.gif","189.gif","190.gif","191.gif","192.gif","193.gif","195.gif","196.gif","197.gif","200.gif","201.gif","202.gif","203.gif","204.gif","205.gif","206.gif","207.gif","208.gif","209.gif","210.gif","211.gif","212.gif","213.gif","214.gif","215.gif","216.gif","217.gif","219.gif","220.gif","221.gif","222.gif","224.gif","225.gif","226.gif","227.gif","228.gif","230.gif","232.gif","233.gif","234.gif","235.gif","238.gif","240.gif","241.gif","243.gif","244.gif","245.gif","246.gif","247.gif","249.gif","250.gif","251.gif","253.gif"], init: function() { if (Conf['Custom Board Titles']) { this.db = new DataBoard('customTitles', null, true); } $.asap((function() { return d.body; }), function() { return $.asap((function() { return $('hr'); }), Banner.ready); }); if (g.BOARD.ID !== 'f') { return Main.ready(function() { return $.queueTask(Banner.load); }); } }, ready: function() { var banner, children; banner = $(".boardBanner"); children = banner.children; if (g.BOARD.ID !== 'f' && g.VIEW === 'thread' && Conf['Remove Thread Excerpt']) { Banner.setTitle(children[1].textContent); } children[0].title = "Click to change"; $.on(children[0], 'click', Banner.cb.toggle); if (Conf['Custom Board Titles']) { Banner.custom(children[1]); if (children[2]) { return Banner.custom(children[2]); } } }, load: function() { var bannerCnt, img; bannerCnt = $.id('bannerCnt'); if (!bannerCnt.firstChild) { img = $.el('img', { alt: '4chan', src: '//s.4cdn.org/image/title/' + bannerCnt.dataset.src }); return $.add(bannerCnt, img); } }, setTitle: function(title) { if (Unread.title != null) { Unread.title = title; return Unread.update(); } else { return d.title = title; } }, cb: { toggle: function() { var banner, i, ref; if (!((ref = Banner.choices) != null ? ref.length : void 0)) { Banner.choices = Banner.banners.slice(); } i = Math.floor(Banner.choices.length * Math.random()); banner = Banner.choices.splice(i, 1); return $('img', this.parentNode).src = "//s.4cdn.org/image/title/" + banner; }, click: function(e) { var base1, br, k, len1, name1, ref; if (!(e.ctrlKey || e.metaKey)) { return; } if ((base1 = Banner.original)[name1 = this.className] == null) { base1[name1] = this.cloneNode(true); } this.contentEditable = true; ref = $$('br', this); for (k = 0, len1 = ref.length; k < len1; k++) { br = ref[k]; $.replace(br, $.tn('\n')); } return this.focus(); }, keydown: function(e) { e.stopPropagation(); if (!e.shiftKey && e.keyCode === 13) { return this.blur(); } }, blur: function() { var br, k, len1, ref; ref = $$('br', this); for (k = 0, len1 = ref.length; k < len1; k++) { br = ref[k]; $.replace(br, $.tn('\n')); } if (this.textContent = this.textContent.replace(/\n*$/, '')) { this.contentEditable = false; return Banner.db.set({ boardID: g.BOARD.ID, threadID: this.className, val: { title: this.textContent, orig: Banner.original[this.className].textContent } }); } else { $.rmAll(this); $.add(this, slice.call(Banner.original[this.className].cloneNode(true).childNodes)); return Banner.db["delete"]({ boardID: g.BOARD.ID, threadID: this.className }); } } }, original: {}, custom: function(child) { var className, data, event, items, k, len1, ref, string, string2; className = child.className; child.title = "Ctrl/\u2318+click to edit board " + (className.slice(5).toLowerCase()); child.spellcheck = false; ref = ['click', 'keydown', 'blur']; for (k = 0, len1 = ref.length; k < len1; k++) { event = ref[k]; $.on(child, event, Banner.cb[event]); } string = g.BOARD + "." + className; string2 = string + ".orig"; items = {}; items[string] = ''; items[string2] = child.textContent; $.get(items, function(items) { if (items[string]) { Banner.db.set({ boardID: g.BOARD.ID, threadID: className, val: { title: items[string], orig: items[string2] } }); } return $["delete"]([string, string2]); }); if (data = Banner.db.get({ boardID: g.BOARD.ID, threadID: className })) { if (Conf['Persistent Custom Board Titles'] || data.orig === child.textContent) { Banner.original[className] = child.cloneNode(true); return child.textContent = data.title; } else { return Banner.db["delete"]({ boardID: g.BOARD.ID, threadID: className }); } } } }; CatalogLinks = { init: function() { var el, input, selector; if ((Conf['External Catalog'] || Conf['JSON Navigation']) && !(Conf['JSON Navigation'] && g.VIEW === 'index')) { selector = (function() { switch (g.VIEW) { case 'thread': case 'archive': return '.navLinks.desktop > a'; case 'catalog': return '.navLinks > :first-child > a'; case 'index': return '#ctrl-top > a, .cataloglink > a'; } })(); $.ready(function() { var catalogLink, k, len1, link, ref; ref = $$(selector); for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; switch (link.pathname.replace(/\/+/g, '/')) { case "/" + g.BOARD + "/": if (Conf['JSON Navigation']) { link.textContent = 'Index'; } link.href = CatalogLinks.index(); break; case "/" + g.BOARD + "/catalog": link.href = CatalogLinks.catalog(); } if (g.VIEW === 'catalog' && Conf['JSON Navigation'] && Conf['Use 4chan X Catalog']) { catalogLink = link.parentNode.cloneNode(true); catalogLink.firstElementChild.textContent = '4chan X Catalog'; catalogLink.firstElementChild.href = CatalogLinks.catalog(); $.after(link.parentNode, [$.tn(' '), catalogLink]); } } }); } if (Conf['JSON Navigation'] && Conf['Use 4chan X Catalog']) { Post.callbacks.push({ name: 'Catalog Link Rewrite', cb: this.node }); CatalogThread.callbacks.push({ name: 'Catalog Link Rewrite', cb: this.node }); } if (Conf['Catalog Links']) { CatalogLinks.el = el = UI.checkbox('Header catalog links', 'Catalog Links'); el.id = 'toggleCatalog'; input = $('input', el); $.on(input, 'change', this.toggle); $.sync('Header catalog links', CatalogLinks.set); return Header.menu.addEntry({ el: el, order: 95 }); } }, node: function() { var a, k, len1, m, ref; ref = $$('a', this.nodes.comment); for (k = 0, len1 = ref.length; k < len1; k++) { a = ref[k]; if (m = a.href.match(/^https?:\/\/boards\.4chan\.org\/([^\/]+)\/catalog(#s=.*)?/)) { a.href = "//boards.4chan.org/" + m[1] + "/" + (m[2] || '#catalog'); } } }, initBoardList: function() { if (!Conf['Catalog Links']) { return; } return CatalogLinks.set(Conf['Header catalog links']); }, toggle: function() { $.event('CloseMenu'); $.set('Header catalog links', this.checked); return CatalogLinks.set(this.checked); }, set: function(useCatalog) { var a, board, k, len1, ref, ref1; ref = $$('a:not([data-only])', Header.boardList).concat($$('a', Header.bottomBoardList)); for (k = 0, len1 = ref.length; k < len1; k++) { a = ref[k]; if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { continue; } a.href = useCatalog ? CatalogLinks.catalog(board) : "/" + board + "/"; } CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; return $('input', CatalogLinks.el).checked = useCatalog; }, catalog: function(board) { if (board == null) { board = g.BOARD.ID; } if (Conf['External Catalog'] && (board === 'a' || board === 'c' || board === 'g' || board === 'biz' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'vr' || board === 'w' || board === 'wg' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'asp' || board === 'cgl' || board === 'ck' || board === 'co' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'gd' || board === 'int' || board === 'jp' || board === 'lit' || board === 'mlp' || board === 'mu' || board === 'n' || board === 'out' || board === 'po' || board === 'sci' || board === 'sp' || board === 'tg' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'wsg' || board === 'x' || board === 'f' || board === 'pol' || board === 's4s' || board === 'lgbt')) { return "http://catalog.neet.tv/" + board + "/"; } else if (Conf['JSON Navigation'] && Conf['Use 4chan X Catalog']) { if (g.BOARD.ID === board && g.VIEW === 'index') { return '#catalog'; } else { return "/" + board + "/#catalog"; } } else { return "/" + board + "/catalog"; } }, index: function(board) { if (board == null) { board = g.BOARD.ID; } if (Conf['JSON Navigation'] && board !== 'f') { if (g.BOARD.ID === board && g.VIEW === 'index') { return '#index'; } else { return "/" + board + "/#index"; } } else { return "/" + board + "/"; } } }; CustomCSS = { init: function() { if (!Conf['Custom CSS']) { return; } return this.addStyle(); }, addStyle: function() { return this.style = $.addStyle(Conf['usercss'], 'custom-css', function() { return $.id('fourchanx-css'); }); }, rmStyle: function() { if (this.style) { $.rm(this.style); return delete this.style; } }, update: function() { if (!this.style) { return this.addStyle(); } return this.style.textContent = Conf['usercss']; } }; ExpandComment = { init: function() { if (g.VIEW !== 'index' || !Conf['Comment Expansion'] || Conf['JSON Navigation']) { return; } if (g.BOARD.ID === 'g') { this.callbacks.push(Fourchan.code); } if (g.BOARD.ID === 'sci') { this.callbacks.push(Fourchan.math); } return Post.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("//a.4cdn.org" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + ".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, k, len1, len2, len3, postObj, posts, q, quote, ref, ref1, spoilerRange, status, u; status = req.status; if (status !== 200 && status !== 304) { a.textContent = "Error " + req.statusText + " (" + status + ")"; return; } posts = req.response.posts; if (spoilerRange = posts[0].custom_spoiler) { Build.spoilerRange[g.BOARD] = spoilerRange; } for (k = 0, len1 = posts.length; k < len1; k++) { postObj = posts[k]; 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 (q = 0, len2 = ref.length; q < len2; q++) { quote = ref[q]; href = quote.getAttribute('href'); if (href[0] === '/') { continue; } if (href[0] === '#') { quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; } else { quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; } } post.nodes.shortComment = comment; $.replace(comment, clone); post.nodes.comment = post.nodes.longComment = clone; post.parseComment(); post.parseQuotes(); ref1 = ExpandComment.callbacks; for (u = 0, len3 = ref1.length; u < len3; u++) { callback = ref1[u]; callback.call(post); } } }; ExpandThread = { statuses: {}, init: function() { if (g.VIEW === 'thread' || !Conf['Thread Expansion']) { return; } if (Conf['JSON Navigation']) { return $.on(d, 'IndexRefresh', this.onIndexRefresh); } else { return Thread.callbacks.push({ name: 'Expand Thread', cb: function() { return ExpandThread.setButton(this); } }); } }, setButton: function(thread) { var a; if (!(a = $.x('following-sibling::*[contains(@class,"summary")][1]', thread.OP.nodes.root))) { return; } a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); a.style.cursor = 'pointer'; return $.on(a, 'click', ExpandThread.cbToggle); }, disconnect: function(refresh) { var ref, ref1, status, threadID; if (g.VIEW === 'thread' || !Conf['Thread Expansion']) { return; } ref = ExpandThread.statuses; for (threadID in ref) { status = ref[threadID]; if ((ref1 = status.req) != null) { ref1.abort(); } delete ExpandThread.statuses[threadID]; } if (!refresh) { return $.off(d, 'IndexRefresh', this.onIndexRefresh); } }, onIndexRefresh: function() { ExpandThread.disconnect(true); return g.BOARD.threads.forEach(function(thread) { return ExpandThread.setButton(thread); }); }, 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(e) { if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } e.preventDefault(); return ExpandThread.toggle(Get.threadFromNode(this)); }, toggle: function(thread) { var a, threadRoot; threadRoot = thread.OP.nodes.root.parentNode; if (!(a = $('.summary', threadRoot))) { return; } if (thread.ID in ExpandThread.statuses) { return ExpandThread.contract(thread, a, threadRoot); } else { return ExpandThread.expand(thread, a); } }, expand: function(thread, a) { var status; ExpandThread.statuses[thread] = status = {}; a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(slice.call(a.textContent.match(/\d+/g)))); return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() { delete status.req; return ExpandThread.parse(this, thread, a); }); }, contract: function(thread, a, threadRoot) { var filesCount, inlined, k, len1, num, postsCount, replies, reply, status; status = ExpandThread.statuses[thread]; delete ExpandThread.statuses[thread]; if (status.req) { status.req.abort(); if (a) { a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); } return; } replies = $$('.thread > .replyContainer', threadRoot); if (!Conf['JSON Navigation'] || Conf['Show Replies']) { num = (function() { if (thread.isSticky) { return 1; } else { switch (g.BOARD.ID) { case 'b': case 'vg': return 3; case 't': return 1; default: return 5; } } })(); replies = replies.slice(0, -num); } postsCount = 0; filesCount = 0; for (k = 0, len1 = replies.length; k < len1; k++) { reply = replies[k]; if (Conf['Quote Inlining']) { while (inlined = $('.inlined', reply)) { inlined.click(); } } postsCount++; if ('file' in Get.postFromRoot(reply)) { filesCount++; } $.rm(reply); } return a.textContent = ExpandThread.text('+', postsCount, filesCount); }, parse: function(req, thread, a) { var filesCount, k, len1, post, postData, posts, postsCount, postsRoot, ref, ref1, root; if ((ref = req.status) !== 200 && ref !== 304) { a.textContent = "Error " + req.statusText + " (" + req.status + ")"; return; } Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler; posts = []; postsRoot = []; filesCount = 0; ref1 = req.response.posts; for (k = 0, len1 = ref1.length; k < len1; k++) { postData = ref1[k]; if (postData.no === thread.ID) { continue; } if ((post = thread.posts[postData.no]) && !post.isFetchedQuote) { if ('file' in post) { filesCount++; } postsRoot.push(post.nodes.root); continue; } root = Build.postFromObject(postData, thread.board.ID); post = new Post(root, thread, thread.board); if ('file' in post) { filesCount++; } posts.push(post); postsRoot.push(root); } Main.callbackNodes(Post, posts); $.after(a, postsRoot); $.event('PostsInserted'); postsCount = postsRoot.length; return a.textContent = ExpandThread.text('-', postsCount, filesCount); } }; FileInfo = { init: function() { var ref; if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['File Info Formatting']) { return; } return Post.callbacks.push({ name: 'File Info Formatting', cb: this.node }); }, node: function() { var info, oldInfo; if (!this.file || this.isClone) { return; } oldInfo = $.el('span', { className: 'fileText-original' }); $.prepend(this.file.link.parentNode, oldInfo); $.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling]); info = $.el('span', { className: 'file-info' }); FileInfo.format(Conf['fileInfo'], this, info); return $.prepend(this.file.text, info); }, format: function(formatString, post, outputNode) { var output; output = []; formatString.replace(/%(.)|[^%]+/g, function(s, c) { output.push(c in FileInfo.formatters ? FileInfo.formatters[c].call(post) : { innerHTML: E(s) }); return ''; }); return $.extend(outputNode, { innerHTML: E.cat(output) }); }, formatters: { t: function() { return { innerHTML: E(this.file.url.match(/[^/]*$/)[0]) }; }, T: function() { return { innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" }; }, l: function() { return { innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" }; }, L: function() { return { innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" }; }, n: function() { var fullname, shortname; fullname = this.file.name; shortname = Build.shortFilename(this.file.name, this.isReply); if (fullname === shortname) { return { innerHTML: E(fullname) }; } else { return { innerHTML: "" + E(shortname) + "" + E(fullname) + "" }; } }, N: function() { return { innerHTML: E(this.file.name) }; }, p: function() { return { innerHTML: (this.file.isSpoiler ? "Spoiler, " : "") }; }, s: function() { return { innerHTML: E(this.file.size) }; }, B: function() { return { innerHTML: E(Math.round(this.file.sizeInBytes)) + " Bytes" }; }, K: function() { return { innerHTML: E(Math.round(this.file.sizeInBytes/1024)) + " KB" }; }, M: function() { return { innerHTML: E(Math.round(this.file.sizeInBytes/1048576*100)/100) + " MB" }; }, r: function() { return { innerHTML: E(this.file.dimensions || "PDF") }; }, g: function() { return { innerHTML: (this.file.tag ? ", " + E(this.file.tag) : "") }; }, '%': function() { return { innerHTML: "%" }; } } }; Flash = { init: function() { if (g.BOARD.ID === 'f' && Conf['Enable Native Flash Embedding']) { return $.ready(Flash.initReady); } }, initReady: function() { if ($.hasStorage) { return $.global(function() { if (JSON.parse(localStorage['4chan-settings'] || '{}').disableAll) { return window.SWFEmbed.init(); } }); } else { if (g.VIEW === 'thread') { $.global(function() { return window.Main.tid = location.pathname.split(/\/+/)[3]; }); } return $.global(function() { return window.SWFEmbed.init(); }); } } }; Fourchan = { init: function() { var ref; if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { return; } if (g.BOARD.ID === 'g') { $.on(window, 'prettyprint:cb', function(e) { var post, pre; if (!(post = g.posts[e.detail.ID])) { return; } if (!(pre = $$('.prettyprint', post.nodes.comment)[e.detail.i])) { return; } if (!$.hasClass(pre, 'prettyprinted')) { pre.innerHTML = e.detail.html; return $.addClass(pre, 'prettyprinted'); } }); $.globalEval('window.addEventListener(\'prettyprint\', function(e) {\n window.dispatchEvent(new CustomEvent(\'prettyprint:cb\', {\n detail: {\n ID: e.detail.ID,\n i: e.detail.i,\n html: prettyPrintOne(e.detail.html)\n }\n }));\n}, false);'); Post.callbacks.push({ name: 'Parse /g/ code', cb: this.code }); } if (g.BOARD.ID === 'sci') { $.globalEval('window.addEventListener(\'mathjax\', function(e) {\n if (window.MathJax) {\n window.MathJax.Hub.Queue(function() {\n if (!e.target.querySelector(\'.MathJax\')) {\n window.MathJax.Hub.Typeset(e.target);\n }\n });\n } else {\n if (!document.querySelector(\'script[src^="//cdn.mathjax.org/"]\')) {\n window.loadMathJax();\n window.loadMathJax = function() {};\n if (!e.target.classList.contains(\'postMessage\')) {\n document.querySelector(\'script[src^="//cdn.mathjax.org/"]\').addEventListener(\'load\', function() {\n window.MathJax.Hub.Queue([\'Typeset\', window.MathJax.Hub, e.target]);\n }, false);\n }\n }\n }\n}, false);'); Post.callbacks.push({ name: 'Parse /sci/ math', cb: this.math }); CatalogThread.callbacks.push({ name: 'Parse /sci/ math', cb: this.math }); } return Main.ready(function() { return $.globalEval('(function() {\n window.clickable_ids = false;\n var nodes = document.querySelectorAll(\'.posteruid, .capcode\');\n for (var i = 0; i < nodes.length; i++) {\n nodes[i].removeEventListener("click", window.idClick, false);\n }\n window.removeEventListener("message", Report.onMessage, false);\n})();'); }); }, code: function() { if (this.isClone) { return; } return $.ready((function(_this) { return function() { var i, k, len1, pre, ref; ref = $$('.prettyprint', _this.nodes.comment); for (i = k = 0, len1 = ref.length; k < len1; i = ++k) { pre = ref[i]; if (!$.hasClass(pre, 'prettyprinted')) { $.event('prettyprint', { ID: _this.fullID, i: i, html: pre.innerHTML }, window); } } }; })(this)); }, math: function() { var cb; if (!(/\[(math|eqn)\]/.test(this.nodes.comment.textContent) || $('.math:not([id])', this.nodes.comment))) { return; } cb = (function(_this) { return function() { if (!doc.contains(_this.nodes.comment)) { return; } $.off(d, 'PostsInserted', cb); return $.event('mathjax', null, _this.nodes.comment); }; })(this); $.on(d, 'PostsInserted', cb); return cb(); } }; IDColor = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Color User IDs'])) { return; } this.ids = { Heaven: [0, 0, 0, '#fff'] }; return Post.callbacks.push({ name: 'Color User IDs', cb: this.node }); }, node: function() { var rgb, span, style, uid; if (this.isClone || !((uid = this.info.uniqueID) && (span = $('span.hand', this.nodes.uniqueID)))) { return; } rgb = IDColor.ids[uid] || IDColor.compute(uid); style = span.style; style.color = rgb[3]; style.backgroundColor = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; return $.addClass(span, 'painted'); }, compute: function(uid) { var hash, rgb; hash = IDColor.hash(uid); rgb = [(hash >> 24) & 0xFF, (hash >> 16) & 0xFF, (hash >> 8) & 0xFF]; rgb.push((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; } }; IDHighlight = { init: function() { var ref; if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { return; } return Post.callbacks.push({ name: 'Highlight by User ID', cb: this.node }); }, uniqueID: null, node: function() { if (this.nodes.uniqueID) { $.on(this.nodes.uniqueID, 'click', IDHighlight.click(this)); } if (this.nodes.capcode) { $.on(this.nodes.capcode, 'click', IDHighlight.click(this)); } if (!this.isClone) { return IDHighlight.set(this); } }, set: function(post) { var match; match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID; return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight'); }, click: function(post) { return function() { var uniqueID; uniqueID = post.info.uniqueID || post.info.capcode; IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID; return g.posts.forEach(IDHighlight.set); }; } }; Keybinds = { init: function() { var hotkey, init; if (!Conf['Keybinds']) { return; } for (hotkey in Config.hotkeys) { $.sync(hotkey, Keybinds.sync); } init = function() { var k, len1, node, ref; $.off(d, '4chanXInitFinished', init); $.on(d, 'keydown', Keybinds.keydown); ref = $$('[accesskey]'); for (k = 0, len1 = ref.length; k < len1; k++) { node = ref[k]; node.removeAttribute('accesskey'); } }; return $.on(d, '4chanXInitFinished', init); }, sync: function(key, hotkey) { return Conf[hotkey] = key; }, keydown: function(e) { var form, k, key, len1, notification, notifications, op, ref, ref1, ref2, ref3, ref4, ref5, searchInput, target, thread, threadRoot; if (!(key = Keybinds.keyCode(e))) { return; } target = e.target; if ((ref = target.nodeName) === 'INPUT' || ref === 'TEXTAREA') { if (!(/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key) && !/^Alt\+(\d|Up|Down|Left|Right)$/.test(key))) { return; } } if (!(((ref1 = g.VIEW) !== 'index' && ref1 !== 'thread') || g.VIEW === 'index' && Conf['JSON Navigation'] && Conf['Index Mode'] === 'catalog' || g.VIEW === 'index' && g.BOARD.ID === 'f')) { threadRoot = Nav.getThread(); if (op = $('.op', threadRoot)) { thread = Get.postFromNode(op).thread; } } switch (key) { case Conf['Toggle board list']: if (!Conf['Custom Board Navigation']) { return; } Header.toggleBoardList(); break; case Conf['Toggle header']: Header.toggleBarVisibility(); break; case Conf['Open empty QR']: if (!QR.postingIsEnabled) { return; } Keybinds.qr(); break; case Conf['Open QR']: if (!(QR.postingIsEnabled && threadRoot)) { return; } Keybinds.qr(threadRoot); break; case Conf['Open settings']: Settings.open(); break; case Conf['Close']: if (Settings.dialog) { Settings.close(); } else if ((notifications = $$('.notification')).length) { for (k = 0, len1 = notifications.length; k < len1; k++) { notification = notifications[k]; $('.close', notification).click(); } } else if (QR.nodes && !(QR.nodes.el.hidden || window.getComputedStyle(QR.nodes.form).display === 'none')) { if (Conf['Persistent QR']) { QR.hide(); } else { QR.close(); } } else if (Embedding.lastEmbed) { Embedding.closeFloat(); } else { return; } 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['SJIS tags']: if (target.nodeName !== 'TEXTAREA') { return; } Keybinds.tags('sjis', target); break; case Conf['Toggle sage']: if (!(QR.nodes && !QR.nodes.el.hidden)) { return; } Keybinds.sage(); break; case Conf['Submit QR']: if (!(QR.nodes && !QR.nodes.el.hidden)) { return; } if (!QR.status()) { QR.submit(); } break; case Conf['Update']: switch (g.VIEW) { case 'thread': if (!Conf['Thread Updater']) { return; } ThreadUpdater.update(); break; case 'index': if (!(Conf['JSON Navigation'] && g.BOARD.ID !== 'f')) { return; } Index.update(); break; default: return; } break; case Conf['Watch']: if (!thread) { return; } ThreadWatcher.toggle(thread); break; case Conf['Expand image']: if (!(ImageExpand.enabled && threadRoot)) { return; } Keybinds.img(threadRoot); break; case Conf['Expand images']: if (!(ImageExpand.enabled && threadRoot)) { return; } Keybinds.img(threadRoot, true); break; case Conf['Open Gallery']: if (!Gallery.enabled) { return; } Gallery.cb.toggle(); break; case Conf['fappeTyme']: if (!(Conf['Fappe Tyme'] && ((ref2 = g.VIEW) === 'index' || ref2 === 'thread'))) { return; } FappeTyme.toggle('fappe'); break; case Conf['werkTyme']: if (!(Conf['Werk Tyme'] && ((ref3 = g.VIEW) === 'index' || ref3 === 'thread'))) { return; } FappeTyme.toggle('werk'); break; case Conf['Front page']: if (Conf['JSON Navigation'] && g.VIEW === 'index' && g.BOARD.ID !== 'f') { Index.userPageNav(1); } else { window.location = "/" + g.BOARD + "/"; } break; case Conf['Open front page']: $.open("/" + g.BOARD + "/"); break; case Conf['Next page']: if (!(g.VIEW === 'index' && g.BOARD.ID !== 'f')) { return; } if (Conf['JSON Navigation']) { if ((ref4 = Conf['Index Mode']) !== 'paged' && ref4 !== 'infinite') { return; } $('.next button', Index.pagelist).click(); } else { if (form = $('.next form')) { window.location = form.action; } } break; case Conf['Previous page']: if (!(g.VIEW === 'index' && g.BOARD.ID !== 'f')) { return; } if (Conf['JSON Navigation']) { if ((ref5 = Conf['Index Mode']) !== 'paged' && ref5 !== 'infinite') { return; } $('.prev button', Index.pagelist).click(); } else { if (form = $('.prev form')) { window.location = form.action; } } break; case Conf['Search form']: if (!(g.VIEW === 'index' && g.BOARD.ID !== 'f')) { return; } searchInput = Conf['JSON Navigation'] ? Index.searchInput : $.id('search-box'); Header.scrollToIfNeeded(searchInput); searchInput.focus(); break; case Conf['Paged mode']: if (!(Conf['JSON Navigation'] && g.BOARD.ID !== 'f')) { return; } window.location = g.VIEW === 'index' ? '#paged' : "/" + g.BOARD + "/#paged"; break; case Conf['Infinite scrolling mode']: if (!(Conf['JSON Navigation'] && g.BOARD.ID !== 'f')) { return; } window.location = g.VIEW === 'index' ? '#infinite' : "/" + g.BOARD + "/#infinite"; break; case Conf['All pages mode']: if (!(Conf['JSON Navigation'] && g.BOARD.ID !== 'f')) { return; } window.location = g.VIEW === 'index' ? '#all-pages' : "/" + g.BOARD + "/#all-pages"; break; case Conf['Open catalog']: if (g.BOARD.ID === 'f') { return; } window.location = CatalogLinks.catalog(); break; case Conf['Cycle sort type']: if (!(Conf['JSON Navigation'] && g.VIEW === 'index' && g.BOARD.ID !== 'f')) { return; } Index.cycleSortType(); break; case Conf['Next thread']: if (!(g.VIEW === 'index' && threadRoot)) { return; } Nav.scroll(+1); break; case Conf['Previous thread']: if (!(g.VIEW === 'index' && threadRoot)) { return; } Nav.scroll(-1); break; case Conf['Expand thread']: if (!(g.VIEW === 'index' && threadRoot)) { return; } ExpandThread.toggle(thread); break; case Conf['Open thread']: if (!(g.VIEW === 'index' && threadRoot)) { return; } Keybinds.open(thread); break; case Conf['Open thread tab']: if (!(g.VIEW === 'index' && threadRoot)) { return; } Keybinds.open(thread, true); break; case Conf['Next reply']: if (!threadRoot) { return; } Keybinds.hl(+1, threadRoot); break; case Conf['Previous reply']: if (!threadRoot) { return; } Keybinds.hl(-1, threadRoot); break; case Conf['Deselect reply']: if (!threadRoot) { return; } Keybinds.hl(0, threadRoot); break; case Conf['Hide']: if (!thread) { return; } if (ThreadHiding.db) { ThreadHiding.toggle(thread); } break; case Conf['Previous Post Quoting You']: if (!threadRoot) { return; } QuoteYou.cb.seek('preceding'); break; case Conf['Next Post Quoting You']: if (!threadRoot) { return; } 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 32: return 'Space'; case 37: return 'Left'; case 38: return 'Up'; case 39: return 'Right'; case 40: return 'Down'; case 188: return 'Comma'; case 190: return 'Period'; case 191: return 'Slash'; case 59: case 186: return 'Semicolon'; default: if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { return String.fromCharCode(kc).toLowerCase(); } else if ((96 <= kc && kc <= 105)) { return String.fromCharCode(kc - 48).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) { QR.open(); if (thread != null) { QR.quote.call($('input', $('.post.highlight', thread) || thread)); } return QR.nodes.com.focus(); }, tags: function(tag, ta) { var range, selEnd, selStart, supported, value; supported = (function() { switch (tag) { case 'spoiler': return !!$('.postForm input[name=spoiler]'); case 'code': return g.BOARD.ID === 'g'; case 'math': case 'eqn': return g.BOARD.ID === 'sci'; case 'sjis': return g.BOARD.ID === 'jp'; } })(); if (!supported) { new Notice('warning', "[" + tag + "] tags are not supported on /" + g.BOARD + "/.", 20); } 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 + "/thread/" + thread; if (tab) { return $.open(url); } else { return location.href = url; } }, hl: function(delta, thread) { var axis, height, k, len1, next, postEl, replies, reply, root; postEl = $('.reply.highlight', thread); if (!delta) { if (postEl) { $.rmClass(postEl, 'highlight'); } return; } if (postEl) { height = postEl.getBoundingClientRect().height; if (Header.getTopOf(postEl) >= -height && Header.getBottomOf(postEl) >= -height) { root = postEl.parentNode; axis = delta === +1 ? 'following' : 'preceding'; if (!(next = $.x(axis + "-sibling::div[contains(@class,'replyContainer') and not(@hidden) and not(child::div[@class='stub'])][1]/child::div[contains(@class,'reply')]", root))) { return; } Header.scrollToIfNeeded(next, delta === +1); this.focus(next); $.rmClass(postEl, 'highlight'); return; } $.rmClass(postEl, 'highlight'); } replies = $$('.reply', thread); if (delta === -1) { replies.reverse(); } for (k = 0, len1 = replies.length; k < len1; k++) { reply = replies[k]; if (delta === +1 && Header.getTopOf(reply) > 0 || delta === -1 && Header.getBottomOf(reply) > 0) { 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() { var k, len1, ref, thread, threadRoot; ref = $$('.thread'); for (k = 0, len1 = ref.length; k < len1; k++) { threadRoot = ref[k]; thread = Get.threadFromRoot(threadRoot); if (thread.isHidden && !thread.stub) { continue; } if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { return threadRoot; } } return $('.board'); }, scroll: function(delta) { var axis, extra, next, ref, thread, top; if ((ref = d.activeElement) != null) { ref.blur(); } thread = Nav.getThread(); axis = delta === +1 ? 'following' : 'preceding'; if (next = $.x(axis + "-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread)) { top = Header.getTopOf(thread); if (delta === +1 && top < 5 || delta === -1 && top > -5) { thread = next; } } extra = Header.getTopOf(thread) + doc.clientHeight - d.body.getBoundingClientRect().bottom; if (extra > 0) { d.body.style.marginBottom = extra + "px"; } Header.scrollTo(thread); if (extra > 0 && !Nav.haveExtra) { Nav.haveExtra = true; return $.on(d, 'scroll', Nav.removeExtra); } }, removeExtra: function() { var extra; extra = doc.clientHeight - d.body.getBoundingClientRect().bottom; if (extra > 0) { return d.body.style.marginBottom = extra + "px"; } else { d.body.style.marginBottom = null; delete Nav.haveExtra; return $.off(d, 'scroll', Nav.removeExtra); } } }; NormalizeURL = { init: function() { var pathname; if (!Conf['Normalize URL']) { return; } pathname = location.pathname.split(/\/+/); switch (g.VIEW) { case 'thread': pathname[2] = 'thread'; pathname = pathname.slice(0, 4); break; case 'index': pathname = pathname.slice(0, 3); } pathname = pathname.join('/'); if (location.pathname !== pathname) { return history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); } } }; RelativeDates = { INTERVAL: $.MINUTE / 2, init: function() { var ref; if (((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Relative Post Dates'] && !Conf['Relative Date Title'] || g.VIEW === 'index' && Conf['JSON Navigation'] && g.BOARD.ID !== 'f') { this.flush(); $.on(d, 'visibilitychange ThreadUpdate', this.flush); } if (Conf['Relative Post Dates']) { return Post.callbacks.push({ name: 'Relative Post Dates', cb: this.node }); } }, node: function() { var dateEl; dateEl = this.nodes.date; if (Conf['Relative Date Title']) { $.on(dateEl, 'mouseover', (function(_this) { return function() { return RelativeDates.hover(_this); }; })(this)); return; } if (this.isClone) { return; } dateEl.title = dateEl.textContent; return RelativeDates.update(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 * years) > 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 data, k, len1, now, ref; if (d.hidden) { return; } now = new Date(); ref = RelativeDates.stale; for (k = 0, len1 = ref.length; k < len1; k++) { data = ref[k]; RelativeDates.update(data, now); } RelativeDates.stale = []; clearTimeout(RelativeDates.timeout); return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); }, hover: function(post) { var date, diff, now; date = post.info.date; now = new Date(); diff = now - date; return post.nodes.date.title = RelativeDates.relative(diff, now, date); }, update: function(data, now) { var date, diff, isPost, k, len1, ref, relative, singlePost; isPost = data instanceof Post; date = isPost ? data.info.date : new Date(+data.dataset.utc); now || (now = new Date()); diff = now - date; relative = RelativeDates.relative(diff, now, date); if (isPost) { ref = [data].concat(data.clones); for (k = 0, len1 = ref.length; k < len1; k++) { singlePost = ref[k]; singlePost.nodes.date.firstChild.textContent = relative; } } else { data.firstChild.textContent = relative; } return RelativeDates.setOwnTimeout(diff, data); }, setOwnTimeout: function(diff, data) { 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(RelativeDates.markStale, delay, data); }, markStale: function(data) { if (indexOf.call(RelativeDates.stale, data) >= 0) { return; } if (data instanceof Post && !g.posts[data.fullID]) { return; } return RelativeDates.stale.push(data); } }; RemoveSpoilers = { init: function() { if (Conf['Reveal Spoilers']) { $.addClass(doc, 'reveal-spoilers'); } if (!Conf['Remove Spoilers']) { return; } Post.callbacks.push({ name: 'Reveal Spoilers', cb: this.node }); CatalogThread.callbacks.push({ name: 'Reveal Spoilers', cb: this.node }); if (g.VIEW === 'archive') { return $.ready(function() { return RemoveSpoilers.unspoiler($.id('arc-list')); }); } }, node: function() { return RemoveSpoilers.unspoiler(this.nodes.comment); }, unspoiler: function(el) { var k, len1, span, spoiler, spoilers; spoilers = $$('s', el); for (k = 0, len1 = spoilers.length; k < len1; k++) { spoiler = spoilers[k]; span = $.el('span', { className: 'removed-spoiler' }); $.replace(spoiler, span); $.add(span, slice.call(spoiler.childNodes)); } } }; Report = { css: ":root:not(.js-enabled) #captchaContainerAlt {\n" + " height: auto;\n" + "}\n" + "#captchaContainerAlt td:nth-child(2) {\n" + " display: table-cell !important;\n" + "}", init: function() { var match; if (!(match = location.search.match(/\bno=(\d+)/))) { return; } Captcha.replace.init(); this.postID = +match[1]; return $.ready(this.ready); }, ready: function() { var passAd, prev, ref; $.addStyle(Report.css); if (Conf['Archive Report']) { Report.archive(); } if ((passAd = $('a[href="https://www.4chan.org/pass"]'))) { $.extend(passAd, { textContent: 'Complain', href: 'https://www.4chan-x.net/captchas.html' }); passAd.parentNode.normalize(); if (((ref = (prev = passAd.previousSibling)) != null ? ref.nodeType : void 0) === Node.TEXT_NODE) { prev.nodeValue = prev.nodeValue.replace(/4chan Pass[^\.]*\./i, 'reCAPTCHA malfunctioning?'); } $.after(passAd, [ $.tn('] ['), $.el('a', { href: 'mailto:4chanpass@4chan.org', textContent: 'Email 4chan', target: '_blank' }) ]); } if (Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled')) { new MutationObserver(function() { Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); return Report.fit('body'); }).observe(d.body, { childList: true, attributes: true, subtree: true }); } else { Report.fit('body'); } if (!Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled') && d.cookie.indexOf('pass_enabled=1') < 0) { $.onExists(d.body, '#recaptcha_image', true, function(image) { $.global(function() { return document.getElementById('recaptcha_image').removeEventListener('click', window.onAltCaptchaClick, false); }); return $.on(image, 'click', function() { if ($.id('recaptcha_challenge_image')) { return $.global(function() { return window.Recaptcha.reload(); }); } }); }); return $.onExists(d.body, '#recaptcha_response_field', true, function(field) { return $.on(field, 'keydown', function(e) { if (e.keyCode === 8 && !field.value) { return $.global(function() { return window.Recaptcha.reload(); }); } }); }); } }, fit: function(selector) { var dy, el; if (!((el = $(selector, doc)) && getComputedStyle(el).visibility !== 'hidden')) { return; } dy = el.getBoundingClientRect().bottom - doc.clientHeight + 8; if (dy > 0) { return window.resizeBy(0, dy); } }, archive: function() { var link, message, types, url; Redirect.init(); if (!(url = Redirect.to('report', { boardID: g.BOARD.ID, postID: Report.postID }))) { return; } if ((message = $('h3')) && /Report submitted!/.test(message.textContent)) { if (location.hash === '#redirect') { $.globalEval('self.close = function(){};'); window.resizeBy(0, 350 - doc.clientHeight); location.replace(url); } return; } link = $.el('a', { href: url, textContent: 'Report to archive' }); $.on(link, 'click', function(e) { if (!(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0)) { return window.resizeBy(0, 350 - doc.clientHeight); } }); $.add(d.body, [$.tn(' ['), link, $.tn(']')]); if (types = $.id('reportTypes')) { return $.on(types, 'change', function(e) { return $('form').action = e.target.value === 'illegal' ? '#redirect' : ''; }); } } }; ThreadLinks = { init: function() { if (!(g.VIEW === 'index' && Conf['Open Threads in New Tab'])) { return; } Post.callbacks.push({ name: 'Thread Links', cb: this.node }); return CatalogThread.callbacks.push({ name: 'Thread Links', cb: this.catalogNode }); }, node: function() { if (this.isReply || this.isClone) { return; } return ThreadLinks.process($('.replylink', this.nodes.info)); }, catalogNode: function() { return ThreadLinks.process(this.nodes.thumb.parentNode); }, process: function(link) { return link.target = '_blank'; } }; Time = { init: function() { var ref; if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Time Formatting'])) { return; } return Post.callbacks.push({ name: 'Time Formatting', cb: this.node }); }, node: function() { if (this.isClone) { return; } return this.nodes.date.textContent = Time.format(Conf['time'], this.info.date); }, format: function(formatString, date) { return formatString.replace(/%(.)/g, function(s, c) { if (c in Time.formatters) { return Time.formatters[c].call(date); } else { return s; } }); }, 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(); }, '%': function() { return '%'; } } }; Settings = { init: function() { var add, link, settings; link = $.el('a', { className: 'settings-link fa fa-wrench', textContent: 'Settings', title: '4chan X Settings', href: 'javascript:;' }); $.on(link, 'click', Settings.open); Header.addShortcut(link); add = this.addSection; add('Main', this.main); add('Filter', this.filter); add('Sauce', this.sauce); add('Advanced', this.advanced); add('Keybinds', this.keybinds); $.on(d, 'AddSettingsSection', Settings.addSection); $.on(d, 'OpenSettings', function(e) { return Settings.open(e.detail); }); if (Conf['Disable Native Extension']) { if ($.hasStorage) { settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; if (settings.disableAll) { return; } settings.disableAll = true; return localStorage.setItem('4chan-settings', JSON.stringify(settings)); } else { return $.onExists(doc, 'body', false, function() { return $.global(function() { return window.Config.disableAll = true; }); }); } } }, open: function(openSection) { var dialog, k, len1, link, links, overlay, ref, section, sectionToOpen; if (Settings.overlay) { return; } $.event('CloseMenu'); Settings.dialog = dialog = $.el('div', { id: 'fourchanx-settings', className: 'dialog' }); $.extend(dialog, { innerHTML: "
" }); Settings.overlay = overlay = $.el('div', { id: 'overlay' }); $.on($('.export', dialog), 'click', Settings["export"]); $.on($('.import', dialog), 'click', Settings["import"]); $.on($('.reset', dialog), 'click', Settings.reset); $.on($('input', dialog), 'change', Settings.onImport); links = []; ref = Settings.sections; for (k = 0, len1 = ref.length; k < len1; k++) { section = ref[k]; 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); if (openSection !== 'none') { (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() { var ref; if (!Settings.dialog) { return; } if ((ref = d.activeElement) != null) { ref.blur(); } $.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, container, containers, description, div, fs, input, inputs, items, key, level, obj, ref; items = {}; inputs = {}; ref = Config.main; for (key in ref) { obj = ref[key]; fs = $.el('fieldset', { innerHTML: "" + E(key) + "" }); containers = [fs]; for (key in obj) { arr = obj[key]; description = arr[1]; div = $.el('div', { innerHTML: ": " + E(description) + "" }); if ($.engine !== 'gecko' && key === 'Remember QR Size') { div.hidden = true; } input = $('input', div); $.on(input, 'change', function() { this.parentNode.parentNode.dataset.checked = this.checked; return $.cb.checked.call(this); }); items[key] = Conf[key]; inputs[key] = input; level = arr[2] || 0; if (containers.length <= level) { container = $.el('div', { className: 'suboption-list' }); $.add(containers[containers.length - 1].lastElementChild, container); containers[level] = container; } else if (containers.length > level + 1) { containers.splice(level + 1, containers.length - (level + 1)); } $.add(containers[level], div); } $.add(section, fs); } $.get(items, function(items) { var val; for (key in items) { val = items[key]; inputs[key].checked = val; inputs[key].parentNode.parentNode.dataset.checked = val; } }); div = $.el('div', { innerHTML: ": Clear manually-hidden threads and posts on all boards. Reload the page to apply." }); button = $('button', div); $.get({ hiddenThreads: {}, hiddenPosts: {} }, function(arg) { var ID, board, hiddenNum, hiddenPosts, hiddenThreads, ref1, ref2, thread; hiddenThreads = arg.hiddenThreads, hiddenPosts = arg.hiddenPosts; hiddenNum = 0; ref1 = hiddenThreads.boards; for (ID in ref1) { board = ref1[ID]; hiddenNum += Object.keys(board).length; } ref2 = hiddenPosts.boards; for (ID in ref2) { board = ref2[ID]; for (ID in board) { thread = board[ID]; hiddenNum += Object.keys(thread).length; } } return button.textContent = "Hidden: " + hiddenNum; }); $.on(button, 'click', function() { this.textContent = 'Hidden: 0'; return $.get('hiddenThreads', {}, function(arg) { var boardID, hiddenThreads; hiddenThreads = arg.hiddenThreads; if ($.hasStorage) { for (boardID in hiddenThreads.boards) { localStorage.removeItem("4chan-hide-t-" + boardID); } } return $["delete"](['hiddenThreads', 'hiddenPosts']); }); }); return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div); }, "export": function() { return $.get(Conf, function(Conf) { delete Conf['archives']; return Settings.downloadExport({ version: g.VERSION, date: Date.now(), Conf: Conf }); }); }, downloadExport: function(data) { var a, p; a = $.el('a', { download: "4chan X v" + g.VERSION + "-" + data.date + ".json", href: "data:application/json;base64," + (btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))))) }); p = $('.imp-exp-result', Settings.dialog); $.rmAll(p); $.add(p, a); return a.click(); }, "import": function() { return $('input[type=file]', this.parentNode).click(); }, onImport: function() { var file, output, reader; if (!(file = this.files[0])) { return; } this.value = null; 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 err; try { return Settings.loadSettings(JSON.parse(e.target.result), function(err) { if (err) { return output.textContent = 'Import failed due to an error.'; } else if (confirm('Import successful. Reload 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); }, convertFrom: { loadletter: function(data) { var base1, boardID, convertSettings, key, ref, ref1, threadData, threadID, threads, val; 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; }; data = convertSettings(data, { 'Disable 4chan\'s extension': 'Disable Native Extension', 'Comment Auto-Expansion': '', 'Remove Slug': '', 'Check for Updates': '', 'Recursive Filtering': 'Recursive Hiding', 'Reply Hiding': 'Reply Hiding Buttons', 'Thread Hiding': 'Thread Hiding Buttons', 'Show Stubs': 'Stubs', 'Image Auto-Gif': 'Replace GIF', 'Reveal Spoilers': 'Reveal Spoiler Thumbnails', 'Expand From Current': 'Expand from here', 'Post in Title': 'Thread Excerpt', 'Current Page': 'Page Count in Stats', 'Current Page Position': '', 'Alternative captcha': 'Use Recaptcha v1', 'Auto Submit': 'Post on Captcha Completion', 'Open Reply in New Tab': 'Open Post in New Tab', 'Remember QR size': 'Remember QR Size', 'Remember Subject': '', 'Quote Inline': 'Quote Inlining', 'Quote Preview': 'Quote Previewing', 'Indicate OP quote': 'Mark OP Quotes', 'Indicate You quote': 'Mark Quotes of You', 'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes', 'uniqueid': 'uniqueID', 'mod': 'capcode', 'email': '', 'country': 'flag', 'md5': 'MD5', 'openEmptyQR': 'Open empty QR', 'openQR': 'Open QR', 'openOptions': 'Open settings', 'close': 'Close', 'spoiler': 'Spoiler tags', 'sageru': 'Toggle sage', '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()); }); } } if (data.WatchedThreads) { data.Conf['watchedThreads'] = { boards: {} }; ref1 = data.WatchedThreads; for (boardID in ref1) { threads = ref1[boardID]; for (threadID in threads) { threadData = threads[threadID]; ((base1 = data.Conf['watchedThreads'].boards)[boardID] || (base1[boardID] = {}))[threadID] = { excerpt: threadData.textContent }; } } } return data; } }, upgrade: function(data, version) { var boardID, changes, compareString, k, key, len1, name, record, ref, ref1, ref2, ref3, rice, type, uids; changes = {}; compareString = version.replace(/\d+/g, function(x) { return ('0000' + x).slice(-5); }); if (compareString < '00001.00011.00008.00000') { if (data['Fixed Thread Watcher'] == null) { changes['Fixed Thread Watcher'] = (ref = data['Toggleable Thread Watcher']) != null ? ref : true; } if (data['Exempt Archives from Encryption'] == null) { changes['Exempt Archives from Encryption'] = (ref1 = data['Except Archives from Encryption']) != null ? ref1 : false; } } if (compareString < '00001.00011.00010.00001') { if (data['selectedArchives'] != null) { uids = { "Moe": 0, "4plebs Archive": 3, "Nyafuu Archive": 4, "Love is Over": 5, "Rebecca Black Tech": 8, "warosu": 10, "fgts": 15, "not4plebs": 22, "DesuStorage": 23, "fireden.net": 24, "disabled": null }; changes['selectedArchives'] = data['selectedArchives']; ref2 = changes['selectedArchives']; for (boardID in ref2) { record = ref2[boardID]; for (type in record) { name = record[type]; if (name in uids) { record[type] = uids[name]; } } } } } if (compareString < '00001.00011.00016.00000') { if ((rice = Config['usercss'].match(/\/\* Board title rice \*\/(?:\n.+)*/)[0])) { if ((data['usercss'] != null) && data['usercss'].indexOf(rice) < 0) { changes['usercss'] = rice + '\n\n' + data['usercss']; } } } if (compareString < '00001.00011.00017.00000') { ref3 = ['Persistent QR', 'Color User IDs', 'Fappe Tyme', 'Werk Tyme', 'Highlight Posts Quoting You', 'Highlight Own Posts']; for (k = 0, len1 = ref3.length; k < len1; k++) { key = ref3[k]; if (data[key] == null) { changes[key] = key === 'Persistent QR'; } } } if (compareString < '00001.00011.00017.00006') { if (data['sauces'] != null) { changes['sauces'] = data['sauces'].replace(/(#?\s*)http:\/\/iqdb\.org\//g, '$1//iqdb.org/'); } } return changes; }, loadSettings: function(data, cb) { if (data.version.split('.')[0] === '2') { data = Settings.convertFrom.loadletter(data); } else if (data.version !== g.VERSION) { $.extend(data.Conf, Settings.upgrade(data.Conf, data.version)); } return $.clear(function(err) { if (err) { return cb(err); } return $.set(data.Conf, cb); }); }, reset: function() { if (confirm('Your current settings will be entirely wiped, are you sure?')) { return $.clear(function(err) { if (err) { return $('.imp-exp-result').textContent = 'Import failed due to an error.'; } else if (confirm('Reset successful. Reload now?')) { return window.location.reload(); } }); } }, filter: function(section) { var select; $.extend(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; } $.extend(div, { innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

    You can use these settings with each regular expression, separate them with semicolons:
  • Per boards, separate them with commas. It is global if not specified.
    For example: boards:a,jp;.
  • Filter OPs only along with their threads (\`only\`), replies only (\`no\`), or both (\`yes\`, this is default).
    For example: op:only;, op:no; or op:yes;.
  • Overrule the \`Show Stubs\` setting if specified: create a stub (\`yes\`) or not (\`no\`).
    For example: stub:yes; or stub:no;.
  • Highlight instead of hiding. You can specify a class name to use with a userstyle.
    For example: highlight; or highlight:wallpaper;.
  • Highlighted OPs will have their threads put on top of the board index by default.
    For example: top:yes; or top:no;.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" }); return $('.warning', div).hidden = Conf['Filter']; }, sauce: function(section) { var ta; $.extend(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.
You can specify the applicable boards by appending ;boards:[board1],[board2].
You can specify the applicable file types by appending ;types:[extension1],[extension2].
You can open links with scripts and popups disabled by appending ;sandbox.
    These parameters will be replaced by their corresponding values:
  • %TURL: Thumbnail URL.
  • %URL: Full image URL.
  • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
  • %MD5: MD5 hash.
  • %name: Original file name.
  • %board: Current board.
  • %%, %semi: Literal % and ;.
" }); $('.warning', section).hidden = Conf['Sauce']; ta = $('textarea', section); $.get('sauces', Conf['sauces'], function(item) { return ta.value = item['sauces']; }); return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { var aa, ab, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, z; $.extend(section, { innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Captcha Language
Choose from list of language codes. Leave blank to autoselect.
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 Twitter link (@).
Board link: g
Archive link: g-archive
Internal archive link: g-expired
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"]
will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
if you are on /g/.
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
Literal %: %%
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (4chan filename)
Filename: %n (truncated), %N (untruncated), %t (4chan filename)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Tag: %g
Literal %: %%
Quick Reply Personas

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

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
Unread Favicon is disabled.
Thread Updater is disabled.
Interval: seconds
Custom Cooldown Time
Seconds:
" }); ref = $$('.warning', section); for (k = 0, len1 = ref.length; k < len1; k++) { warning = ref[k]; warning.hidden = Conf[warning.dataset.feature]; } items = {}; inputs = {}; ref1 = ['captchaLanguage', 'boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss', 'customCooldown']; for (q = 0, len2 = ref1.length; q < len2; q++) { name = ref1[q]; input = $("[name='" + name + "']", section); items[name] = Conf[name]; inputs[name] = input; if (name === 'usercss') { $.on(input, 'change', $.cb.value); } else if (name === 'favicon') { $.on(input, 'change', $.cb.value); $.on(input, 'change', Settings[name]); } else { $.on(input, 'input', $.cb.value); if (name in Settings) { $.on(input, 'input', Settings[name]); } } } 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]; input = inputs[key]; input.value = val; if (key in Settings && key !== 'usercss') { Settings[key].call(input); } } }); interval = $('input[name="Interval"]', section); customCSS = $('input[name="Custom CSS"]', section); applyCSS = $('#apply-css', section); interval.value = Conf['Interval']; customCSS.checked = Conf['Custom CSS']; inputs['usercss'].disabled = !Conf['Custom CSS']; applyCSS.disabled = !Conf['Custom CSS']; $.on(interval, 'change', ThreadUpdater.cb.interval); $.on(customCSS, 'change', Settings.togglecss); $.on(applyCSS, 'click', Settings.usercss); archBoards = {}; ref2 = Redirect.archives; for (u = 0, len3 = ref2.length; u < len3; u++) { ref3 = ref2[u], uid = ref3.uid, name = ref3.name, boards = ref3.boards, files = ref3.files, software = ref3.software, withCredentials = ref3.withCredentials; for (v = 0, len4 = boards.length; v < len4; v++) { boardID = boards[v]; o = archBoards[boardID] || (archBoards[boardID] = { thread: [[], []], post: [[], []], file: [[], []] }); i = +(!!withCredentials); archive = [uid != null ? uid : name, name]; o.thread[i].push(archive); if (software === 'foolfuuka') { o.post[i].push(archive); } if (indexOf.call(files, boardID) >= 0) { o.file[i].push(archive); } } } for (boardID in archBoards) { o = archBoards[boardID]; ref4 = ['thread', 'post', 'file']; for (z = 0, len5 = ref4.length; z < len5; z++) { item = ref4[z]; i = o[item][0].length ? 1 : 0; o[item][i].push([null, 'disabled']); o[item] = o[item][0].concat(o[item][1]); } } rows = []; boardOptions = []; ref5 = Object.keys(archBoards).sort(); for (aa = 0, len6 = ref5.length; aa < len6; aa++) { boardID = ref5[aa]; 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 })); o = archBoards[boardID]; ref6 = ['thread', 'post', 'file']; for (ab = 0, len7 = ref6.length; ab < len7; ab++) { item = ref6[ab]; $.add(row, Settings.addArchiveCell(boardID, o, item)); } rows.push(row); } if (!(g.BOARD.ID in archBoards)) { rows[0].hidden = false; } $.add($('tbody', section), rows); boardSelect = $('#archive-board-select', section); $.add(boardSelect, boardOptions); table = $('#archive-table', section); $.on(boardSelect, 'change', function() { $('tbody > :not([hidden])', table).hidden = true; return $("tbody > ." + this.value, table).hidden = false; }); $.get('selectedArchives', Conf['selectedArchives'], function(arg) { var data, id, select, selectedArchives, type; selectedArchives = arg.selectedArchives; for (boardID in selectedArchives) { data = selectedArchives[boardID]; for (type in data) { id = data[type]; if (select = $("select[data-boardid='" + boardID + "'][data-type='" + type + "']", section)) { select.value = JSON.stringify(id); } } } }); }, 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', { value: JSON.stringify(archive[0]), textContent: archive[1] })); } $.extend(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() { return $.get('selectedArchives', Conf['selectedArchives'], (function(_this) { return function(arg) { var name1, selectedArchives; selectedArchives = arg.selectedArchives; (selectedArchives[name1 = _this.dataset.boardid] || (selectedArchives[name1] = {}))[_this.dataset.type] = JSON.parse(_this.value); return $.set('selectedArchives', selectedArchives); }; })(this)); }, boardnav: function() { return Header.generateBoardList(this.value); }, time: function() { return this.nextElementSibling.textContent = Time.format(this.value, new Date()); }, backlink: function() { return this.nextElementSibling.textContent = this.value.replace(/%(?:id|%)/g, function(x) { return { '%id': '123456789', '%%': '%' }[x]; }); }, fileInfo: function() { var data; data = { isReply: true, file: { url: '//i.4cdn.org/g/1334437723720.jpg', name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', size: '276 KB', sizeInBytes: 276 * 1024, dimensions: '1280x720', isImage: true, isVideo: false, isSpoiler: true, tag: 'Loop' } }; return FileInfo.format(this.value, data, this.nextElementSibling); }, favicon: function() { var img; Favicon["switch"](); if (g.VIEW === 'thread' && Conf['Unread Favicon']) { Unread.update(); } img = this.nextElementSibling.children; img[0].src = Favicon["default"]; img[1].src = Favicon.unreadSFW; img[2].src = Favicon.unreadNSFW; return img[3].src = Favicon.unreadDead; }, togglecss: function() { if ($('textarea[name=usercss]', $.x('ancestor::fieldset[1]', this)).disabled = $.id('apply-css').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, ref, tbody, tr; $.extend(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
" }); $('.warning', section).hidden = Conf['Keybinds']; tbody = $('tbody', section); items = {}; inputs = {}; ref = Config.hotkeys; for (key in ref) { arr = ref[key]; tr = $.el('tr', { innerHTML: "" + E(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, items, k, key, len1, ref; if (d.body && !$('title', d.head)) { return; } if (window['4chan X antidup']) { return; } window['4chan X antidup'] = true; if (location.hostname === 'www.google.com') { if (location.pathname === '/recaptcha/api/fallback') { $.ready(function() { return Captcha.v2.initFrame(); }); } $.get('Captcha Fixes', true, function(arg) { var enabled; enabled = arg['Captcha Fixes']; if (enabled) { return $.ready(function() { return Captcha.fixes.init(); }); } }); return; } 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 (k = 0, len1 = ref.length; k < len1; k++) { db = ref[k]; Conf[db] = { boards: {} }; } Conf['selectedArchives'] = {}; Conf['cooldowns'] = {}; Conf['Except Archives from Encryption'] = false; items = {}; for (key in Conf) { items[key] = void 0; } items['previousversion'] = void 0; return $.get(items, function(items) { return $.asap((function() { return doc = d.documentElement; }), function() { var ref1, val; if ($.cantSet) { } else if (items.previousversion == null) { Main.ready(function() { $.set('previousversion', g.VERSION); return Settings.open(); }); } else if (items.previousversion !== g.VERSION) { Main.upgrade(items); } for (key in Conf) { val = Conf[key]; Conf[key] = (ref1 = items[key]) != null ? ref1 : val; } return Main.initFeatures(); }); }); }, upgrade: function(items) { var changes, previousversion; previousversion = items.previousversion; changes = { previousversion: g.VERSION }; $.extend(changes, Settings.upgrade(items, previousversion)); $.extend(items, changes); return $.set(changes, function() { var el, ref; if ((ref = items['Show Updated Notifications']) != null ? ref : true) { el = $.el('span', { innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "." }); return new Notice('info', el, 15); } }); }, initFeatures: function() { var err, feature, hostname, k, len1, match, name, pathname, ref, ref1, ref2, ref3, search; hostname = location.hostname, search = location.search; pathname = location.pathname.split(/\/+/); if (hostname !== 'www.4chan.org') { g.BOARD = new Board(pathname[1]); } if (hostname === 'boards.4chan.org' || hostname === 'sys.4chan.org' || hostname === 'www.4chan.org') { $.global(function() { document.documentElement.classList.add('js-enabled'); return window.FCX = {}; }); } switch (hostname) { case 'www.4chan.org': $.onExists(doc, 'body', false, function() { return $.addStyle(Main.cssWWW); }); Captcha.replace.init(); return; case 'sys.4chan.org': if (pathname[2] === 'imgboard.php') { if (/\bmode=report\b/.test(search)) { Report.init(); } else if ((match = search.match(/\bres=(\d+)/))) { $.ready(function() { var ref; if (Conf['404 Redirect'] && ((ref = $.id('errmsg')) != null ? ref.textContent : void 0) === 'Error: Specified thread does not exist.') { return Redirect.navigate('thread', { boardID: g.BOARD.ID, postID: +match[1] }); } }); } } else if (pathname[2] === 'post') { PostSuccessful.init(); } return; case 'i.4cdn.org': if (!(pathname[2] && !/s\.jpg$/.test(pathname[2]))) { return; } $.asap((function() { return d.readyState !== 'loading'; }), function() { var ref, video; if (Conf['404 Redirect'] && ((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found')) { return Redirect.navigate('file', { boardID: g.BOARD.ID, filename: pathname[pathname.length - 1] }); } else if (video = $('video')) { if (Conf['Volume in New Tab']) { Volume.setup(video); } if (Conf['Loop in New Tab']) { video.loop = true; video.controls = false; video.play(); return ImageCommon.addControls(video); } } }); return; } if ((ref = pathname[2]) === 'thread' || ref === 'res') { g.VIEW = 'thread'; g.THREADID = +pathname[3]; } else if ((ref1 = pathname[2]) === 'catalog' || ref1 === 'archive') { g.VIEW = pathname[2]; } else if (pathname[2].match(/^\d*$/)) { g.VIEW = 'index'; } else { return; } g.threads = new SimpleDict(); g.posts = new SimpleDict(); $.onExists(doc, 'body', false, Main.initStyle); ref2 = Main.features; for (k = 0, len1 = ref2.length; k < len1; k++) { ref3 = ref2[k], name = ref3[0], feature = ref3[1]; try { feature.init(); } catch (_error) { err = _error; Main.handleErrors({ message: "\"" + name + "\" initialization crashed.", error: err }); } } return $.ready(Main.initReady); }, initStyle: function() { var keyboard, ref; if (!Main.isThisPageLegit() || $.hasClass(doc, 'fourchan-x')) { return; } if ((ref = $('link[href*=mobile]', d.head)) != null) { ref.disabled = true; } $.addClass(doc, 'fourchan-x', 'seaweedchan'); $.addClass(doc, g.VIEW === 'thread' ? 'thread-view' : g.VIEW); if ($.engine) { $.addClass(doc, $.engine); } $.addStyle(Main.css, 'fourchanx-css'); keyboard = false; $.on(d, 'mousedown', function() { return keyboard = false; }); $.on(d, 'keydown', function(e) { if (e.keyCode === 9) { return keyboard = true; } }); window.addEventListener('focus', (function() { return doc.classList.toggle('keyboard-focus', keyboard); }), true); return Main.setClass(); }, setClass: function() { var mainStyleSheet, setStyle, style, styleSheets; 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 k, len1, styleSheet; $.rmClass(doc, style); for (k = 0, len1 = styleSheets.length; k < len1; k++) { styleSheet = styleSheets[k]; if (styleSheet.href === (mainStyleSheet != null ? mainStyleSheet.href : void 0)) { 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 ref, ref1, why; if (g.VIEW === 'thread' && (((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found') || ($('.board') && !$('.opContainer')))) { ThreadWatcher.set404(g.BOARD.ID, g.THREADID, function() { if (Conf['404 Redirect']) { return Redirect.navigate('thread', { boardID: g.BOARD.ID, threadID: g.THREADID, postID: +location.hash.match(/\d+/) }, "/" + g.BOARD + "/"); } }); return; } if ((ref1 = d.title) === '4chan - Temporarily Offline' || ref1 === '4chan - 404 Not Found') { return; } if (!(Conf['JSON Navigation'] && g.VIEW === 'index')) { Main.initThread(); } else { $.event('4chanXInitFinished'); } if (Conf['Show Support Message']) { if ($.cantSync) { why = $.cantSet ? 'save your settings' : 'synchronize settings between tabs'; return new Notice('warning', "4chan X needs local storage to " + why + ".\nEnable it on boards.4chan.org in your browser's privacy settings\n(may be listed as part of \"local data\" or \"cookies\")."); } } }, initThread: function() { var board, err, errors, k, len1, len2, m, postRoot, posts, q, ref, ref1, scriptData, thread, threadRoot, threads; if (board = $('.board')) { threads = []; posts = []; ref = $$('.board > .thread', board); for (k = 0, len1 = ref.length; k < len1; k++) { threadRoot = ref[k]; thread = new Thread(+threadRoot.id.slice(1), g.BOARD); threads.push(thread); ref1 = $$('.thread > .postContainer', threadRoot); for (q = 0, len2 = ref1.length; q < len2; q++) { postRoot = ref1[q]; 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); } if (g.VIEW === 'thread') { scriptData = Get.scriptData(); threads[0].postLimit = /\bbumplimit *= *1\b/.test(scriptData); threads[0].fileLimit = /\bimagelimit *= *1\b/.test(scriptData); threads[0].ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : void 0; } Main.callbackNodes(Thread, threads); return Main.callbackNodesDB(Post, posts, function() { var len3, post, u; for (u = 0, len3 = posts.length; u < len3; u++) { post = posts[u]; QuoteThreading.insert(post); } return $.event('4chanXInitFinished'); }); } else { return $.event('4chanXInitFinished'); } }, callbackNodes: function(klass, nodes) { var cb, i, node; i = 0; cb = klass.callbacks; while (node = nodes[i++]) { cb.execute(node); } }, callbackNodesDB: function(klass, nodes, cb) { var cbs, fn, i, softTask; i = 0; cbs = klass.callbacks; fn = function() { var node; if (!(node = nodes[i])) { return false; } cbs.execute(node); return ++i % 25; }; softTask = function() { while (fn()) { continue; } if (!nodes[i]) { if (cb) { cb(); } return; } return setTimeout(softTask, 0); }; return softTask(); }, handleErrors: function(errors) { var div, error, k, len1, logs; if (!(errors instanceof Array)) { error = errors; } else if (errors.length === 1) { error = errors[0]; } if (error) { new Notice('error', Main.parseError(error, Main.reportLink([error])), 15); return; } div = $.el('div', { innerHTML: E(errors.length) + " errors occurred." + Main.reportLink(errors).innerHTML + " [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 (k = 0, len1 = errors.length; k < len1; k++) { error = errors[k]; $.add(logs, Main.parseError(error)); } return new Notice('error', [div, logs], 30); }, parseError: function(data, reportLink) { var context, error, lines, message, ref, ref1; c.error(data.message, data.error.stack); message = $.el('div', { innerHTML: E(data.message) + (reportLink ? reportLink.innerHTML : "") }); error = $.el('div', { textContent: (data.error.name || 'Error') + ": " + (data.error.message || 'see console for details') }); lines = ((ref = data.error.stack) != null ? (ref1 = ref.match(/\d+(?=:\d+\)?$)/mg)) != null ? ref1.join().replace(/^/, ' at ') : void 0 : void 0) || ''; context = $.el('div', { textContent: "(4chan X ccd0 v" + g.VERSION + " userscript on " + $.engine + lines + ")" }); return [message, error, context]; }, reportLink: function(errors) { var data, details, ref, title, url; data = errors[0]; title = data.message; if (errors.length > 1) { title += " (+" + (errors.length - 1) + " other errors)"; } details = "[Please describe the steps needed to reproduce this error.]\n\nScript: 4chan X ccd0 v" + g.VERSION + " userscript\nUser agent: " + navigator.userAgent + "\nURL: " + location.href + "\n\n" + data.error + "\n" + (((ref = data.error.stack) != null ? ref.replace(data.error.toString(), '').trim() : void 0) || ''); details = details.replace(/file:\/{3}.+\//g, ''); url = "https://gitreports.com/issue/ccd0/4chan-x?issue_title=" + (encodeURIComponent(title)) + "&details=" + (encodeURIComponent(details)); return { innerHTML: " [report]" }; }, 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; }, ready: function(cb) { return $.ready(function() { if (Main.isThisPageLegit()) { return cb(); } }); }, css: "/*!\n" + " * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome\n" + " * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n" + " */\n" + "@font-face {\n" + " font-family: FontAwesome;\n" + " src: url('data:application/font-woff;base64,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') format('woff');\n" + " font-weight: 400;\n" + " font-style: normal;\n" + "}\n" + ".fa::before {\n" + " font-family: FontAwesome;\n" + " font-weight: 400;\n" + " font-style: normal;\n" + " -webkit-font-smoothing: antialiased;\n" + " text-decoration: inherit;\n" + " speak: none;\n" + " display: inline-block;\n" + " font-size: 13px;\n" + " visibility: visible;\n" + "}\n" + ":root:not(.shortcut-icons) #shortcuts .fa::before {\n" + " display: none;\n" + "}\n" + ":root.shortcut-icons #shortcuts .fa::before {\n" + " font-size: 15px !important;\n" + " margin-top: -3px !important;\n" + " position: relative;\n" + " top: 1px;\n" + "}\n" + ":root.shortcut-icons #shortcuts .fa, .menu-button .fa {\n" + " font-size: 0;\n" + " visibility: hidden;\n" + "}\n" + ":root.shortcut-icons .shortcut.brackets-wrap::after,\n" + ":root.shortcut-icons .shortcut.brackets-wrap::before {\n" + " display: none;\n" + "}\n" + ":root.shortcut-icons #shortcuts a .fa,\n" + ".menu-button .fa,\n" + ".hide-reply-button .fa,\n" + ".hide-thread-button .fa {\n" + " display: inline;\n" + "}\n" + ".fa-glass:before {content: \"\\f000\";}\n" + ".fa-music:before {content: \"\\f001\";}\n" + ".fa-search:before {content: \"\\f002\";}\n" + ".fa-envelope-o:before {content: \"\\f003\";}\n" + ".fa-heart:before {content: \"\\f004\";}\n" + ".fa-star:before {content: \"\\f005\";}\n" + ".fa-star-o:before {content: \"\\f006\";}\n" + ".fa-user:before {content: \"\\f007\";}\n" + ".fa-film:before {content: \"\\f008\";}\n" + ".fa-th-large:before {content: \"\\f009\";}\n" + ".fa-th:before {content: \"\\f00a\";}\n" + ".fa-th-list:before {content: \"\\f00b\";}\n" + ".fa-check:before {content: \"\\f00c\";}\n" + ".fa-remove:before, .fa-close:before, .fa-times:before {content: \"\\f00d\";}\n" + ".fa-search-plus:before {content: \"\\f00e\";}\n" + ".fa-search-minus:before {content: \"\\f010\";}\n" + ".fa-power-off:before {content: \"\\f011\";}\n" + ".fa-signal:before {content: \"\\f012\";}\n" + ".fa-gear:before, .fa-cog:before {content: \"\\f013\";}\n" + ".fa-trash-o:before {content: \"\\f014\";}\n" + ".fa-home:before {content: \"\\f015\";}\n" + ".fa-file-o:before {content: \"\\f016\";}\n" + ".fa-clock-o:before {content: \"\\f017\";}\n" + ".fa-road:before {content: \"\\f018\";}\n" + ".fa-download:before {content: \"\\f019\";}\n" + ".fa-arrow-circle-o-down:before {content: \"\\f01a\";}\n" + ".fa-arrow-circle-o-up:before {content: \"\\f01b\";}\n" + ".fa-inbox:before {content: \"\\f01c\";}\n" + ".fa-play-circle-o:before {content: \"\\f01d\";}\n" + ".fa-rotate-right:before, .fa-repeat:before {content: \"\\f01e\";}\n" + ".fa-refresh:before {content: \"\\f021\";}\n" + ".fa-list-alt:before {content: \"\\f022\";}\n" + ".fa-lock:before {content: \"\\f023\";}\n" + ".fa-flag:before {content: \"\\f024\";}\n" + ".fa-headphones:before {content: \"\\f025\";}\n" + ".fa-volume-off:before {content: \"\\f026\";}\n" + ".fa-volume-down:before {content: \"\\f027\";}\n" + ".fa-volume-up:before {content: \"\\f028\";}\n" + ".fa-qrcode:before {content: \"\\f029\";}\n" + ".fa-barcode:before {content: \"\\f02a\";}\n" + ".fa-tag:before {content: \"\\f02b\";}\n" + ".fa-tags:before {content: \"\\f02c\";}\n" + ".fa-book:before {content: \"\\f02d\";}\n" + ".fa-bookmark:before {content: \"\\f02e\";}\n" + ".fa-print:before {content: \"\\f02f\";}\n" + ".fa-camera:before {content: \"\\f030\";}\n" + ".fa-font:before {content: \"\\f031\";}\n" + ".fa-bold:before {content: \"\\f032\";}\n" + ".fa-italic:before {content: \"\\f033\";}\n" + ".fa-text-height:before {content: \"\\f034\";}\n" + ".fa-text-width:before {content: \"\\f035\";}\n" + ".fa-align-left:before {content: \"\\f036\";}\n" + ".fa-align-center:before {content: \"\\f037\";}\n" + ".fa-align-right:before {content: \"\\f038\";}\n" + ".fa-align-justify:before {content: \"\\f039\";}\n" + ".fa-list:before {content: \"\\f03a\";}\n" + ".fa-dedent:before, .fa-outdent:before {content: \"\\f03b\";}\n" + ".fa-indent:before {content: \"\\f03c\";}\n" + ".fa-video-camera:before {content: \"\\f03d\";}\n" + ".fa-photo:before, .fa-image:before, .fa-picture-o:before {content: \"\\f03e\";}\n" + ".fa-pencil:before {content: \"\\f040\";}\n" + ".fa-map-marker:before {content: \"\\f041\";}\n" + ".fa-adjust:before {content: \"\\f042\";}\n" + ".fa-tint:before {content: \"\\f043\";}\n" + ".fa-edit:before, .fa-pencil-square-o:before {content: \"\\f044\";}\n" + ".fa-share-square-o:before {content: \"\\f045\";}\n" + ".fa-check-square-o:before {content: \"\\f046\";}\n" + ".fa-arrows:before {content: \"\\f047\";}\n" + ".fa-step-backward:before {content: \"\\f048\";}\n" + ".fa-fast-backward:before {content: \"\\f049\";}\n" + ".fa-backward:before {content: \"\\f04a\";}\n" + ".fa-play:before {content: \"\\f04b\";}\n" + ".fa-pause:before {content: \"\\f04c\";}\n" + ".fa-stop:before {content: \"\\f04d\";}\n" + ".fa-forward:before {content: \"\\f04e\";}\n" + ".fa-fast-forward:before {content: \"\\f050\";}\n" + ".fa-step-forward:before {content: \"\\f051\";}\n" + ".fa-eject:before {content: \"\\f052\";}\n" + ".fa-chevron-left:before {content: \"\\f053\";}\n" + ".fa-chevron-right:before {content: \"\\f054\";}\n" + ".fa-plus-circle:before {content: \"\\f055\";}\n" + ".fa-minus-circle:before {content: \"\\f056\";}\n" + ".fa-times-circle:before {content: \"\\f057\";}\n" + ".fa-check-circle:before {content: \"\\f058\";}\n" + ".fa-question-circle:before {content: \"\\f059\";}\n" + ".fa-info-circle:before {content: \"\\f05a\";}\n" + ".fa-crosshairs:before {content: \"\\f05b\";}\n" + ".fa-times-circle-o:before {content: \"\\f05c\";}\n" + ".fa-check-circle-o:before {content: \"\\f05d\";}\n" + ".fa-ban:before {content: \"\\f05e\";}\n" + ".fa-arrow-left:before {content: \"\\f060\";}\n" + ".fa-arrow-right:before {content: \"\\f061\";}\n" + ".fa-arrow-up:before {content: \"\\f062\";}\n" + ".fa-arrow-down:before {content: \"\\f063\";}\n" + ".fa-mail-forward:before, .fa-share:before {content: \"\\f064\";}\n" + ".fa-expand:before {content: \"\\f065\";}\n" + ".fa-compress:before {content: \"\\f066\";}\n" + ".fa-plus:before {content: \"\\f067\";}\n" + ".fa-minus:before {content: \"\\f068\";}\n" + ".fa-asterisk:before {content: \"\\f069\";}\n" + ".fa-exclamation-circle:before {content: \"\\f06a\";}\n" + ".fa-gift:before {content: \"\\f06b\";}\n" + ".fa-leaf:before {content: \"\\f06c\";}\n" + ".fa-fire:before {content: \"\\f06d\";}\n" + ".fa-eye:before {content: \"\\f06e\";}\n" + ".fa-eye-slash:before {content: \"\\f070\";}\n" + ".fa-warning:before, .fa-exclamation-triangle:before {content: \"\\f071\";}\n" + ".fa-plane:before {content: \"\\f072\";}\n" + ".fa-calendar:before {content: \"\\f073\";}\n" + ".fa-random:before {content: \"\\f074\";}\n" + ".fa-comment:before {content: \"\\f075\";}\n" + ".fa-magnet:before {content: \"\\f076\";}\n" + ".fa-chevron-up:before {content: \"\\f077\";}\n" + ".fa-chevron-down:before {content: \"\\f078\";}\n" + ".fa-retweet:before {content: \"\\f079\";}\n" + ".fa-shopping-cart:before {content: \"\\f07a\";}\n" + ".fa-folder:before {content: \"\\f07b\";}\n" + ".fa-folder-open:before {content: \"\\f07c\";}\n" + ".fa-arrows-v:before {content: \"\\f07d\";}\n" + ".fa-arrows-h:before {content: \"\\f07e\";}\n" + ".fa-bar-chart-o:before, .fa-bar-chart:before {content: \"\\f080\";}\n" + ".fa-twitter-square:before {content: \"\\f081\";}\n" + ".fa-facebook-square:before {content: \"\\f082\";}\n" + ".fa-camera-retro:before {content: \"\\f083\";}\n" + ".fa-key:before {content: \"\\f084\";}\n" + ".fa-gears:before, .fa-cogs:before {content: \"\\f085\";}\n" + ".fa-comments:before {content: \"\\f086\";}\n" + ".fa-thumbs-o-up:before {content: \"\\f087\";}\n" + ".fa-thumbs-o-down:before {content: \"\\f088\";}\n" + ".fa-star-half:before {content: \"\\f089\";}\n" + ".fa-heart-o:before {content: \"\\f08a\";}\n" + ".fa-sign-out:before {content: \"\\f08b\";}\n" + ".fa-linkedin-square:before {content: \"\\f08c\";}\n" + ".fa-thumb-tack:before {content: \"\\f08d\";}\n" + ".fa-external-link:before {content: \"\\f08e\";}\n" + ".fa-sign-in:before {content: \"\\f090\";}\n" + ".fa-trophy:before {content: \"\\f091\";}\n" + ".fa-github-square:before {content: \"\\f092\";}\n" + ".fa-upload:before {content: \"\\f093\";}\n" + ".fa-lemon-o:before {content: \"\\f094\";}\n" + ".fa-phone:before {content: \"\\f095\";}\n" + ".fa-square-o:before {content: \"\\f096\";}\n" + ".fa-bookmark-o:before {content: \"\\f097\";}\n" + ".fa-phone-square:before {content: \"\\f098\";}\n" + ".fa-twitter:before {content: \"\\f099\";}\n" + ".fa-facebook-f:before, .fa-facebook:before {content: \"\\f09a\";}\n" + ".fa-github:before {content: \"\\f09b\";}\n" + ".fa-unlock:before {content: \"\\f09c\";}\n" + ".fa-credit-card:before {content: \"\\f09d\";}\n" + ".fa-feed:before, .fa-rss:before {content: \"\\f09e\";}\n" + ".fa-hdd-o:before {content: \"\\f0a0\";}\n" + ".fa-bullhorn:before {content: \"\\f0a1\";}\n" + ".fa-bell:before {content: \"\\f0f3\";}\n" + ".fa-certificate:before {content: \"\\f0a3\";}\n" + ".fa-hand-o-right:before {content: \"\\f0a4\";}\n" + ".fa-hand-o-left:before {content: \"\\f0a5\";}\n" + ".fa-hand-o-up:before {content: \"\\f0a6\";}\n" + ".fa-hand-o-down:before {content: \"\\f0a7\";}\n" + ".fa-arrow-circle-left:before {content: \"\\f0a8\";}\n" + ".fa-arrow-circle-right:before {content: \"\\f0a9\";}\n" + ".fa-arrow-circle-up:before {content: \"\\f0aa\";}\n" + ".fa-arrow-circle-down:before {content: \"\\f0ab\";}\n" + ".fa-globe:before {content: \"\\f0ac\";}\n" + ".fa-wrench:before {content: \"\\f0ad\";}\n" + ".fa-tasks:before {content: \"\\f0ae\";}\n" + ".fa-filter:before {content: \"\\f0b0\";}\n" + ".fa-briefcase:before {content: \"\\f0b1\";}\n" + ".fa-arrows-alt:before {content: \"\\f0b2\";}\n" + ".fa-group:before, .fa-users:before {content: \"\\f0c0\";}\n" + ".fa-chain:before, .fa-link:before {content: \"\\f0c1\";}\n" + ".fa-cloud:before {content: \"\\f0c2\";}\n" + ".fa-flask:before {content: \"\\f0c3\";}\n" + ".fa-cut:before, .fa-scissors:before {content: \"\\f0c4\";}\n" + ".fa-copy:before, .fa-files-o:before {content: \"\\f0c5\";}\n" + ".fa-paperclip:before {content: \"\\f0c6\";}\n" + ".fa-save:before, .fa-floppy-o:before {content: \"\\f0c7\";}\n" + ".fa-square:before {content: \"\\f0c8\";}\n" + ".fa-navicon:before, .fa-reorder:before, .fa-bars:before {content: \"\\f0c9\";}\n" + ".fa-list-ul:before {content: \"\\f0ca\";}\n" + ".fa-list-ol:before {content: \"\\f0cb\";}\n" + ".fa-strikethrough:before {content: \"\\f0cc\";}\n" + ".fa-underline:before {content: \"\\f0cd\";}\n" + ".fa-table:before {content: \"\\f0ce\";}\n" + ".fa-magic:before {content: \"\\f0d0\";}\n" + ".fa-truck:before {content: \"\\f0d1\";}\n" + ".fa-pinterest:before {content: \"\\f0d2\";}\n" + ".fa-pinterest-square:before {content: \"\\f0d3\";}\n" + ".fa-google-plus-square:before {content: \"\\f0d4\";}\n" + ".fa-google-plus:before {content: \"\\f0d5\";}\n" + ".fa-money:before {content: \"\\f0d6\";}\n" + ".fa-caret-down:before {content: \"\\f0d7\";}\n" + ".fa-caret-up:before {content: \"\\f0d8\";}\n" + ".fa-caret-left:before {content: \"\\f0d9\";}\n" + ".fa-caret-right:before {content: \"\\f0da\";}\n" + ".fa-columns:before {content: \"\\f0db\";}\n" + ".fa-unsorted:before, .fa-sort:before {content: \"\\f0dc\";}\n" + ".fa-sort-down:before, .fa-sort-desc:before {content: \"\\f0dd\";}\n" + ".fa-sort-up:before, .fa-sort-asc:before {content: \"\\f0de\";}\n" + ".fa-envelope:before {content: \"\\f0e0\";}\n" + ".fa-linkedin:before {content: \"\\f0e1\";}\n" + ".fa-rotate-left:before, .fa-undo:before {content: \"\\f0e2\";}\n" + ".fa-legal:before, .fa-gavel:before {content: \"\\f0e3\";}\n" + ".fa-dashboard:before, .fa-tachometer:before {content: \"\\f0e4\";}\n" + ".fa-comment-o:before {content: \"\\f0e5\";}\n" + ".fa-comments-o:before {content: \"\\f0e6\";}\n" + ".fa-flash:before, .fa-bolt:before {content: \"\\f0e7\";}\n" + ".fa-sitemap:before {content: \"\\f0e8\";}\n" + ".fa-umbrella:before {content: \"\\f0e9\";}\n" + ".fa-paste:before, .fa-clipboard:before {content: \"\\f0ea\";}\n" + ".fa-lightbulb-o:before {content: \"\\f0eb\";}\n" + ".fa-exchange:before {content: \"\\f0ec\";}\n" + ".fa-cloud-download:before {content: \"\\f0ed\";}\n" + ".fa-cloud-upload:before {content: \"\\f0ee\";}\n" + ".fa-user-md:before {content: \"\\f0f0\";}\n" + ".fa-stethoscope:before {content: \"\\f0f1\";}\n" + ".fa-suitcase:before {content: \"\\f0f2\";}\n" + ".fa-bell-o:before {content: \"\\f0a2\";}\n" + ".fa-coffee:before {content: \"\\f0f4\";}\n" + ".fa-cutlery:before {content: \"\\f0f5\";}\n" + ".fa-file-text-o:before {content: \"\\f0f6\";}\n" + ".fa-building-o:before {content: \"\\f0f7\";}\n" + ".fa-hospital-o:before {content: \"\\f0f8\";}\n" + ".fa-ambulance:before {content: \"\\f0f9\";}\n" + ".fa-medkit:before {content: \"\\f0fa\";}\n" + ".fa-fighter-jet:before {content: \"\\f0fb\";}\n" + ".fa-beer:before {content: \"\\f0fc\";}\n" + ".fa-h-square:before {content: \"\\f0fd\";}\n" + ".fa-plus-square:before {content: \"\\f0fe\";}\n" + ".fa-angle-double-left:before {content: \"\\f100\";}\n" + ".fa-angle-double-right:before {content: \"\\f101\";}\n" + ".fa-angle-double-up:before {content: \"\\f102\";}\n" + ".fa-angle-double-down:before {content: \"\\f103\";}\n" + ".fa-angle-left:before {content: \"\\f104\";}\n" + ".fa-angle-right:before {content: \"\\f105\";}\n" + ".fa-angle-up:before {content: \"\\f106\";}\n" + ".fa-angle-down:before {content: \"\\f107\";}\n" + ".fa-desktop:before {content: \"\\f108\";}\n" + ".fa-laptop:before {content: \"\\f109\";}\n" + ".fa-tablet:before {content: \"\\f10a\";}\n" + ".fa-mobile-phone:before, .fa-mobile:before {content: \"\\f10b\";}\n" + ".fa-circle-o:before {content: \"\\f10c\";}\n" + ".fa-quote-left:before {content: \"\\f10d\";}\n" + ".fa-quote-right:before {content: \"\\f10e\";}\n" + ".fa-spinner:before {content: \"\\f110\";}\n" + ".fa-circle:before {content: \"\\f111\";}\n" + ".fa-mail-reply:before, .fa-reply:before {content: \"\\f112\";}\n" + ".fa-github-alt:before {content: \"\\f113\";}\n" + ".fa-folder-o:before {content: \"\\f114\";}\n" + ".fa-folder-open-o:before {content: \"\\f115\";}\n" + ".fa-smile-o:before {content: \"\\f118\";}\n" + ".fa-frown-o:before {content: \"\\f119\";}\n" + ".fa-meh-o:before {content: \"\\f11a\";}\n" + ".fa-gamepad:before {content: \"\\f11b\";}\n" + ".fa-keyboard-o:before {content: \"\\f11c\";}\n" + ".fa-flag-o:before {content: \"\\f11d\";}\n" + ".fa-flag-checkered:before {content: \"\\f11e\";}\n" + ".fa-terminal:before {content: \"\\f120\";}\n" + ".fa-code:before {content: \"\\f121\";}\n" + ".fa-mail-reply-all:before, .fa-reply-all:before {content: \"\\f122\";}\n" + ".fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before {content: \"\\f123\";}\n" + ".fa-location-arrow:before {content: \"\\f124\";}\n" + ".fa-crop:before {content: \"\\f125\";}\n" + ".fa-code-fork:before {content: \"\\f126\";}\n" + ".fa-unlink:before, .fa-chain-broken:before {content: \"\\f127\";}\n" + ".fa-question:before {content: \"\\f128\";}\n" + ".fa-info:before {content: \"\\f129\";}\n" + ".fa-exclamation:before {content: \"\\f12a\";}\n" + ".fa-superscript:before {content: \"\\f12b\";}\n" + ".fa-subscript:before {content: \"\\f12c\";}\n" + ".fa-eraser:before {content: \"\\f12d\";}\n" + ".fa-puzzle-piece:before {content: \"\\f12e\";}\n" + ".fa-microphone:before {content: \"\\f130\";}\n" + ".fa-microphone-slash:before {content: \"\\f131\";}\n" + ".fa-shield:before {content: \"\\f132\";}\n" + ".fa-calendar-o:before {content: \"\\f133\";}\n" + ".fa-fire-extinguisher:before {content: \"\\f134\";}\n" + ".fa-rocket:before {content: \"\\f135\";}\n" + ".fa-maxcdn:before {content: \"\\f136\";}\n" + ".fa-chevron-circle-left:before {content: \"\\f137\";}\n" + ".fa-chevron-circle-right:before {content: \"\\f138\";}\n" + ".fa-chevron-circle-up:before {content: \"\\f139\";}\n" + ".fa-chevron-circle-down:before {content: \"\\f13a\";}\n" + ".fa-html5:before {content: \"\\f13b\";}\n" + ".fa-css3:before {content: \"\\f13c\";}\n" + ".fa-anchor:before {content: \"\\f13d\";}\n" + ".fa-unlock-alt:before {content: \"\\f13e\";}\n" + ".fa-bullseye:before {content: \"\\f140\";}\n" + ".fa-ellipsis-h:before {content: \"\\f141\";}\n" + ".fa-ellipsis-v:before {content: \"\\f142\";}\n" + ".fa-rss-square:before {content: \"\\f143\";}\n" + ".fa-play-circle:before {content: \"\\f144\";}\n" + ".fa-ticket:before {content: \"\\f145\";}\n" + ".fa-minus-square:before {content: \"\\f146\";}\n" + ".fa-minus-square-o:before {content: \"\\f147\";}\n" + ".fa-level-up:before {content: \"\\f148\";}\n" + ".fa-level-down:before {content: \"\\f149\";}\n" + ".fa-check-square:before {content: \"\\f14a\";}\n" + ".fa-pencil-square:before {content: \"\\f14b\";}\n" + ".fa-external-link-square:before {content: \"\\f14c\";}\n" + ".fa-share-square:before {content: \"\\f14d\";}\n" + ".fa-compass:before {content: \"\\f14e\";}\n" + ".fa-toggle-down:before, .fa-caret-square-o-down:before {content: \"\\f150\";}\n" + ".fa-toggle-up:before, .fa-caret-square-o-up:before {content: \"\\f151\";}\n" + ".fa-toggle-right:before, .fa-caret-square-o-right:before {content: \"\\f152\";}\n" + ".fa-euro:before, .fa-eur:before {content: \"\\f153\";}\n" + ".fa-gbp:before {content: \"\\f154\";}\n" + ".fa-dollar:before, .fa-usd:before {content: \"\\f155\";}\n" + ".fa-rupee:before, .fa-inr:before {content: \"\\f156\";}\n" + ".fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before {content: \"\\f157\";}\n" + ".fa-ruble:before, .fa-rouble:before, .fa-rub:before {content: \"\\f158\";}\n" + ".fa-won:before, .fa-krw:before {content: \"\\f159\";}\n" + ".fa-bitcoin:before, .fa-btc:before {content: \"\\f15a\";}\n" + ".fa-file:before {content: \"\\f15b\";}\n" + ".fa-file-text:before {content: \"\\f15c\";}\n" + ".fa-sort-alpha-asc:before {content: \"\\f15d\";}\n" + ".fa-sort-alpha-desc:before {content: \"\\f15e\";}\n" + ".fa-sort-amount-asc:before {content: \"\\f160\";}\n" + ".fa-sort-amount-desc:before {content: \"\\f161\";}\n" + ".fa-sort-numeric-asc:before {content: \"\\f162\";}\n" + ".fa-sort-numeric-desc:before {content: \"\\f163\";}\n" + ".fa-thumbs-up:before {content: \"\\f164\";}\n" + ".fa-thumbs-down:before {content: \"\\f165\";}\n" + ".fa-youtube-square:before {content: \"\\f166\";}\n" + ".fa-youtube:before {content: \"\\f167\";}\n" + ".fa-xing:before {content: \"\\f168\";}\n" + ".fa-xing-square:before {content: \"\\f169\";}\n" + ".fa-youtube-play:before {content: \"\\f16a\";}\n" + ".fa-dropbox:before {content: \"\\f16b\";}\n" + ".fa-stack-overflow:before {content: \"\\f16c\";}\n" + ".fa-instagram:before {content: \"\\f16d\";}\n" + ".fa-flickr:before {content: \"\\f16e\";}\n" + ".fa-adn:before {content: \"\\f170\";}\n" + ".fa-bitbucket:before {content: \"\\f171\";}\n" + ".fa-bitbucket-square:before {content: \"\\f172\";}\n" + ".fa-tumblr:before {content: \"\\f173\";}\n" + ".fa-tumblr-square:before {content: \"\\f174\";}\n" + ".fa-long-arrow-down:before {content: \"\\f175\";}\n" + ".fa-long-arrow-up:before {content: \"\\f176\";}\n" + ".fa-long-arrow-left:before {content: \"\\f177\";}\n" + ".fa-long-arrow-right:before {content: \"\\f178\";}\n" + ".fa-apple:before {content: \"\\f179\";}\n" + ".fa-windows:before {content: \"\\f17a\";}\n" + ".fa-android:before {content: \"\\f17b\";}\n" + ".fa-linux:before {content: \"\\f17c\";}\n" + ".fa-dribbble:before {content: \"\\f17d\";}\n" + ".fa-skype:before {content: \"\\f17e\";}\n" + ".fa-foursquare:before {content: \"\\f180\";}\n" + ".fa-trello:before {content: \"\\f181\";}\n" + ".fa-female:before {content: \"\\f182\";}\n" + ".fa-male:before {content: \"\\f183\";}\n" + ".fa-gittip:before, .fa-gratipay:before {content: \"\\f184\";}\n" + ".fa-sun-o:before {content: \"\\f185\";}\n" + ".fa-moon-o:before {content: \"\\f186\";}\n" + ".fa-archive:before {content: \"\\f187\";}\n" + ".fa-bug:before {content: \"\\f188\";}\n" + ".fa-vk:before {content: \"\\f189\";}\n" + ".fa-weibo:before {content: \"\\f18a\";}\n" + ".fa-renren:before {content: \"\\f18b\";}\n" + ".fa-pagelines:before {content: \"\\f18c\";}\n" + ".fa-stack-exchange:before {content: \"\\f18d\";}\n" + ".fa-arrow-circle-o-right:before {content: \"\\f18e\";}\n" + ".fa-arrow-circle-o-left:before {content: \"\\f190\";}\n" + ".fa-toggle-left:before, .fa-caret-square-o-left:before {content: \"\\f191\";}\n" + ".fa-dot-circle-o:before {content: \"\\f192\";}\n" + ".fa-wheelchair:before {content: \"\\f193\";}\n" + ".fa-vimeo-square:before {content: \"\\f194\";}\n" + ".fa-turkish-lira:before, .fa-try:before {content: \"\\f195\";}\n" + ".fa-plus-square-o:before {content: \"\\f196\";}\n" + ".fa-space-shuttle:before {content: \"\\f197\";}\n" + ".fa-slack:before {content: \"\\f198\";}\n" + ".fa-envelope-square:before {content: \"\\f199\";}\n" + ".fa-wordpress:before {content: \"\\f19a\";}\n" + ".fa-openid:before {content: \"\\f19b\";}\n" + ".fa-institution:before, .fa-bank:before, .fa-university:before {content: \"\\f19c\";}\n" + ".fa-mortar-board:before, .fa-graduation-cap:before {content: \"\\f19d\";}\n" + ".fa-yahoo:before {content: \"\\f19e\";}\n" + ".fa-google:before {content: \"\\f1a0\";}\n" + ".fa-reddit:before {content: \"\\f1a1\";}\n" + ".fa-reddit-square:before {content: \"\\f1a2\";}\n" + ".fa-stumbleupon-circle:before {content: \"\\f1a3\";}\n" + ".fa-stumbleupon:before {content: \"\\f1a4\";}\n" + ".fa-delicious:before {content: \"\\f1a5\";}\n" + ".fa-digg:before {content: \"\\f1a6\";}\n" + ".fa-pied-piper:before {content: \"\\f1a7\";}\n" + ".fa-pied-piper-alt:before {content: \"\\f1a8\";}\n" + ".fa-drupal:before {content: \"\\f1a9\";}\n" + ".fa-joomla:before {content: \"\\f1aa\";}\n" + ".fa-language:before {content: \"\\f1ab\";}\n" + ".fa-fax:before {content: \"\\f1ac\";}\n" + ".fa-building:before {content: \"\\f1ad\";}\n" + ".fa-child:before {content: \"\\f1ae\";}\n" + ".fa-paw:before {content: \"\\f1b0\";}\n" + ".fa-spoon:before {content: \"\\f1b1\";}\n" + ".fa-cube:before {content: \"\\f1b2\";}\n" + ".fa-cubes:before {content: \"\\f1b3\";}\n" + ".fa-behance:before {content: \"\\f1b4\";}\n" + ".fa-behance-square:before {content: \"\\f1b5\";}\n" + ".fa-steam:before {content: \"\\f1b6\";}\n" + ".fa-steam-square:before {content: \"\\f1b7\";}\n" + ".fa-recycle:before {content: \"\\f1b8\";}\n" + ".fa-automobile:before, .fa-car:before {content: \"\\f1b9\";}\n" + ".fa-cab:before, .fa-taxi:before {content: \"\\f1ba\";}\n" + ".fa-tree:before {content: \"\\f1bb\";}\n" + ".fa-spotify:before {content: \"\\f1bc\";}\n" + ".fa-deviantart:before {content: \"\\f1bd\";}\n" + ".fa-soundcloud:before {content: \"\\f1be\";}\n" + ".fa-database:before {content: \"\\f1c0\";}\n" + ".fa-file-pdf-o:before {content: \"\\f1c1\";}\n" + ".fa-file-word-o:before {content: \"\\f1c2\";}\n" + ".fa-file-excel-o:before {content: \"\\f1c3\";}\n" + ".fa-file-powerpoint-o:before {content: \"\\f1c4\";}\n" + ".fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before {content: \"\\f1c5\";}\n" + ".fa-file-zip-o:before, .fa-file-archive-o:before {content: \"\\f1c6\";}\n" + ".fa-file-sound-o:before, .fa-file-audio-o:before {content: \"\\f1c7\";}\n" + ".fa-file-movie-o:before, .fa-file-video-o:before {content: \"\\f1c8\";}\n" + ".fa-file-code-o:before {content: \"\\f1c9\";}\n" + ".fa-vine:before {content: \"\\f1ca\";}\n" + ".fa-codepen:before {content: \"\\f1cb\";}\n" + ".fa-jsfiddle:before {content: \"\\f1cc\";}\n" + ".fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before {content: \"\\f1cd\";}\n" + ".fa-circle-o-notch:before {content: \"\\f1ce\";}\n" + ".fa-ra:before, .fa-rebel:before {content: \"\\f1d0\";}\n" + ".fa-ge:before, .fa-empire:before {content: \"\\f1d1\";}\n" + ".fa-git-square:before {content: \"\\f1d2\";}\n" + ".fa-git:before {content: \"\\f1d3\";}\n" + ".fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before {content: \"\\f1d4\";}\n" + ".fa-tencent-weibo:before {content: \"\\f1d5\";}\n" + ".fa-qq:before {content: \"\\f1d6\";}\n" + ".fa-wechat:before, .fa-weixin:before {content: \"\\f1d7\";}\n" + ".fa-send:before, .fa-paper-plane:before {content: \"\\f1d8\";}\n" + ".fa-send-o:before, .fa-paper-plane-o:before {content: \"\\f1d9\";}\n" + ".fa-history:before {content: \"\\f1da\";}\n" + ".fa-circle-thin:before {content: \"\\f1db\";}\n" + ".fa-header:before {content: \"\\f1dc\";}\n" + ".fa-paragraph:before {content: \"\\f1dd\";}\n" + ".fa-sliders:before {content: \"\\f1de\";}\n" + ".fa-share-alt:before {content: \"\\f1e0\";}\n" + ".fa-share-alt-square:before {content: \"\\f1e1\";}\n" + ".fa-bomb:before {content: \"\\f1e2\";}\n" + ".fa-soccer-ball-o:before, .fa-futbol-o:before {content: \"\\f1e3\";}\n" + ".fa-tty:before {content: \"\\f1e4\";}\n" + ".fa-binoculars:before {content: \"\\f1e5\";}\n" + ".fa-plug:before {content: \"\\f1e6\";}\n" + ".fa-slideshare:before {content: \"\\f1e7\";}\n" + ".fa-twitch:before {content: \"\\f1e8\";}\n" + ".fa-yelp:before {content: \"\\f1e9\";}\n" + ".fa-newspaper-o:before {content: \"\\f1ea\";}\n" + ".fa-wifi:before {content: \"\\f1eb\";}\n" + ".fa-calculator:before {content: \"\\f1ec\";}\n" + ".fa-paypal:before {content: \"\\f1ed\";}\n" + ".fa-google-wallet:before {content: \"\\f1ee\";}\n" + ".fa-cc-visa:before {content: \"\\f1f0\";}\n" + ".fa-cc-mastercard:before {content: \"\\f1f1\";}\n" + ".fa-cc-discover:before {content: \"\\f1f2\";}\n" + ".fa-cc-amex:before {content: \"\\f1f3\";}\n" + ".fa-cc-paypal:before {content: \"\\f1f4\";}\n" + ".fa-cc-stripe:before {content: \"\\f1f5\";}\n" + ".fa-bell-slash:before {content: \"\\f1f6\";}\n" + ".fa-bell-slash-o:before {content: \"\\f1f7\";}\n" + ".fa-trash:before {content: \"\\f1f8\";}\n" + ".fa-copyright:before {content: \"\\f1f9\";}\n" + ".fa-at:before {content: \"\\f1fa\";}\n" + ".fa-eyedropper:before {content: \"\\f1fb\";}\n" + ".fa-paint-brush:before {content: \"\\f1fc\";}\n" + ".fa-birthday-cake:before {content: \"\\f1fd\";}\n" + ".fa-area-chart:before {content: \"\\f1fe\";}\n" + ".fa-pie-chart:before {content: \"\\f200\";}\n" + ".fa-line-chart:before {content: \"\\f201\";}\n" + ".fa-lastfm:before {content: \"\\f202\";}\n" + ".fa-lastfm-square:before {content: \"\\f203\";}\n" + ".fa-toggle-off:before {content: \"\\f204\";}\n" + ".fa-toggle-on:before {content: \"\\f205\";}\n" + ".fa-bicycle:before {content: \"\\f206\";}\n" + ".fa-bus:before {content: \"\\f207\";}\n" + ".fa-ioxhost:before {content: \"\\f208\";}\n" + ".fa-angellist:before {content: \"\\f209\";}\n" + ".fa-cc:before {content: \"\\f20a\";}\n" + ".fa-shekel:before, .fa-sheqel:before, .fa-ils:before {content: \"\\f20b\";}\n" + ".fa-meanpath:before {content: \"\\f20c\";}\n" + ".fa-buysellads:before {content: \"\\f20d\";}\n" + ".fa-connectdevelop:before {content: \"\\f20e\";}\n" + ".fa-dashcube:before {content: \"\\f210\";}\n" + ".fa-forumbee:before {content: \"\\f211\";}\n" + ".fa-leanpub:before {content: \"\\f212\";}\n" + ".fa-sellsy:before {content: \"\\f213\";}\n" + ".fa-shirtsinbulk:before {content: \"\\f214\";}\n" + ".fa-simplybuilt:before {content: \"\\f215\";}\n" + ".fa-skyatlas:before {content: \"\\f216\";}\n" + ".fa-cart-plus:before {content: \"\\f217\";}\n" + ".fa-cart-arrow-down:before {content: \"\\f218\";}\n" + ".fa-diamond:before {content: \"\\f219\";}\n" + ".fa-ship:before {content: \"\\f21a\";}\n" + ".fa-user-secret:before {content: \"\\f21b\";}\n" + ".fa-motorcycle:before {content: \"\\f21c\";}\n" + ".fa-street-view:before {content: \"\\f21d\";}\n" + ".fa-heartbeat:before {content: \"\\f21e\";}\n" + ".fa-venus:before {content: \"\\f221\";}\n" + ".fa-mars:before {content: \"\\f222\";}\n" + ".fa-mercury:before {content: \"\\f223\";}\n" + ".fa-intersex:before, .fa-transgender:before {content: \"\\f224\";}\n" + ".fa-transgender-alt:before {content: \"\\f225\";}\n" + ".fa-venus-double:before {content: \"\\f226\";}\n" + ".fa-mars-double:before {content: \"\\f227\";}\n" + ".fa-venus-mars:before {content: \"\\f228\";}\n" + ".fa-mars-stroke:before {content: \"\\f229\";}\n" + ".fa-mars-stroke-v:before {content: \"\\f22a\";}\n" + ".fa-mars-stroke-h:before {content: \"\\f22b\";}\n" + ".fa-neuter:before {content: \"\\f22c\";}\n" + ".fa-genderless:before {content: \"\\f22d\";}\n" + ".fa-facebook-official:before {content: \"\\f230\";}\n" + ".fa-pinterest-p:before {content: \"\\f231\";}\n" + ".fa-whatsapp:before {content: \"\\f232\";}\n" + ".fa-server:before {content: \"\\f233\";}\n" + ".fa-user-plus:before {content: \"\\f234\";}\n" + ".fa-user-times:before {content: \"\\f235\";}\n" + ".fa-hotel:before, .fa-bed:before {content: \"\\f236\";}\n" + ".fa-viacoin:before {content: \"\\f237\";}\n" + ".fa-train:before {content: \"\\f238\";}\n" + ".fa-subway:before {content: \"\\f239\";}\n" + ".fa-medium:before {content: \"\\f23a\";}\n" + ".fa-yc:before, .fa-y-combinator:before {content: \"\\f23b\";}\n" + ".fa-optin-monster:before {content: \"\\f23c\";}\n" + ".fa-opencart:before {content: \"\\f23d\";}\n" + ".fa-expeditedssl:before {content: \"\\f23e\";}\n" + ".fa-battery-4:before, .fa-battery-full:before {content: \"\\f240\";}\n" + ".fa-battery-3:before, .fa-battery-three-quarters:before {content: \"\\f241\";}\n" + ".fa-battery-2:before, .fa-battery-half:before {content: \"\\f242\";}\n" + ".fa-battery-1:before, .fa-battery-quarter:before {content: \"\\f243\";}\n" + ".fa-battery-0:before, .fa-battery-empty:before {content: \"\\f244\";}\n" + ".fa-mouse-pointer:before {content: \"\\f245\";}\n" + ".fa-i-cursor:before {content: \"\\f246\";}\n" + ".fa-object-group:before {content: \"\\f247\";}\n" + ".fa-object-ungroup:before {content: \"\\f248\";}\n" + ".fa-sticky-note:before {content: \"\\f249\";}\n" + ".fa-sticky-note-o:before {content: \"\\f24a\";}\n" + ".fa-cc-jcb:before {content: \"\\f24b\";}\n" + ".fa-cc-diners-club:before {content: \"\\f24c\";}\n" + ".fa-clone:before {content: \"\\f24d\";}\n" + ".fa-balance-scale:before {content: \"\\f24e\";}\n" + ".fa-hourglass-o:before {content: \"\\f250\";}\n" + ".fa-hourglass-1:before, .fa-hourglass-start:before {content: \"\\f251\";}\n" + ".fa-hourglass-2:before, .fa-hourglass-half:before {content: \"\\f252\";}\n" + ".fa-hourglass-3:before, .fa-hourglass-end:before {content: \"\\f253\";}\n" + ".fa-hourglass:before {content: \"\\f254\";}\n" + ".fa-hand-grab-o:before, .fa-hand-rock-o:before {content: \"\\f255\";}\n" + ".fa-hand-stop-o:before, .fa-hand-paper-o:before {content: \"\\f256\";}\n" + ".fa-hand-scissors-o:before {content: \"\\f257\";}\n" + ".fa-hand-lizard-o:before {content: \"\\f258\";}\n" + ".fa-hand-spock-o:before {content: \"\\f259\";}\n" + ".fa-hand-pointer-o:before {content: \"\\f25a\";}\n" + ".fa-hand-peace-o:before {content: \"\\f25b\";}\n" + ".fa-trademark:before {content: \"\\f25c\";}\n" + ".fa-registered:before {content: \"\\f25d\";}\n" + ".fa-creative-commons:before {content: \"\\f25e\";}\n" + ".fa-gg:before {content: \"\\f260\";}\n" + ".fa-gg-circle:before {content: \"\\f261\";}\n" + ".fa-tripadvisor:before {content: \"\\f262\";}\n" + ".fa-odnoklassniki:before {content: \"\\f263\";}\n" + ".fa-odnoklassniki-square:before {content: \"\\f264\";}\n" + ".fa-get-pocket:before {content: \"\\f265\";}\n" + ".fa-wikipedia-w:before {content: \"\\f266\";}\n" + ".fa-safari:before {content: \"\\f267\";}\n" + ".fa-chrome:before {content: \"\\f268\";}\n" + ".fa-firefox:before {content: \"\\f269\";}\n" + ".fa-opera:before {content: \"\\f26a\";}\n" + ".fa-internet-explorer:before {content: \"\\f26b\";}\n" + ".fa-tv:before, .fa-television:before {content: \"\\f26c\";}\n" + ".fa-contao:before {content: \"\\f26d\";}\n" + ".fa-500px:before {content: \"\\f26e\";}\n" + ".fa-amazon:before {content: \"\\f270\";}\n" + ".fa-calendar-plus-o:before {content: \"\\f271\";}\n" + ".fa-calendar-minus-o:before {content: \"\\f272\";}\n" + ".fa-calendar-times-o:before {content: \"\\f273\";}\n" + ".fa-calendar-check-o:before {content: \"\\f274\";}\n" + ".fa-industry:before {content: \"\\f275\";}\n" + ".fa-map-pin:before {content: \"\\f276\";}\n" + ".fa-map-signs:before {content: \"\\f277\";}\n" + ".fa-map-o:before {content: \"\\f278\";}\n" + ".fa-map:before {content: \"\\f279\";}\n" + ".fa-commenting:before {content: \"\\f27a\";}\n" + ".fa-commenting-o:before {content: \"\\f27b\";}\n" + ".fa-houzz:before {content: \"\\f27c\";}\n" + ".fa-vimeo:before {content: \"\\f27d\";}\n" + ".fa-black-tie:before {content: \"\\f27e\";}\n" + ".fa-fonticons:before {content: \"\\f280\";}\n" + ".fa-spin::before {\n" + " -webkit-animation:spin 2s infinite linear;\n" + " -moz-animation:spin 2s infinite linear;\n" + " -o-animation:spin 2s infinite linear;\n" + " animation:spin 2s infinite linear;\n" + "}\n" + "@-moz-keyframes spin {\n" + " 0% {-moz-transform:rotate(0deg);}\n" + " 100% {-moz-transform:rotate(359deg);}\n" + "}\n" + "@-webkit-keyframes spin {\n" + " 0% {-webkit-transform:rotate(0deg);}\n" + " 100% {-webkit-transform:rotate(359deg);}\n" + "}\n" + "@keyframes spin {\n" + " 0% {transform:rotate(0deg);}\n" + " 100% {transform:rotate(359deg);}\n" + "}\n" + "/* General */\n" + ".dialog {\n" + " border: 1px solid;\n" + " display: block;\n" + "}\n" + ".dialog:not(#qr):not(#thread-watcher):not(#header-bar) {\n" + " box-shadow: 0 1px 2px rgba(0, 0, 0, .15);\n" + "}\n" + "#qr, \n" + "#thread-watcher {\n" + " box-shadow: -1px 2px 2px rgba(0, 0, 0, 0.25);\n" + "}\n" + ".captcha-img,\n" + ".field {\n" + " background-color: #FFF;\n" + " border: 1px solid #CCC;\n" + " -moz-box-sizing: border-box;\n" + " box-sizing: border-box;\n" + " color: #333;\n" + " font: 13px sans-serif;\n" + " outline: none;\n" + " transition: color .25s, border-color .25s;\n" + " transition: color .25s, border-color .25s;\n" + "}\n" + ".field::-moz-placeholder,\n" + ".field:hover::-moz-placeholder {\n" + " color: #AAA !important;\n" + " font-size: 13px !important;\n" + " opacity: 1.0 !important;\n" + "}\n" + ".captch-img:hover,\n" + ".field:hover {\n" + " border-color: #999;\n" + "}\n" + ".field:hover, .field:focus, .field.focus {\n" + " color: #000;\n" + "}\n" + ".field[disabled] {\n" + " background-color: #F2F2F2;\n" + " color: #888;\n" + "}\n" + ".field::-webkit-search-decoration {\n" + " display: none;\n" + "}\n" + ".move {\n" + " cursor: move;\n" + " overflow: hidden;\n" + "}\n" + "label {\n" + " cursor: pointer;\n" + "}\n" + "a[href=\"javascript:;\"] {\n" + " text-decoration: none;\n" + "}\n" + ".warning {\n" + " color: red;\n" + "}\n" + "#boardNavDesktop, #boardNavMobile {\n" + " display: none !important;\n" + "}\n" + ":root.hide-bottom-board-list #boardNavDesktopFoot {\n" + " display: none;\n" + "}\n" + "body.hasDropDownNav{\n" + " margin-top: 5px;\n" + "}\n" + ":root:not(.keyboard-focus) a {\n" + " outline: none;\n" + "}\n" + ".painted {\n" + " border-radius: 3px;\n" + " padding: 0px 2px;\n" + "}\n" + ".ad-plea {\n" + " display: none;\n" + "}\n" + "/* 4chan style fixes */\n" + ".opContainer, .op {\n" + " display: block !important;\n" + " overflow: visible !important;\n" + "}\n" + ".reply > .file > .fileText {\n" + " margin: 0 20px;\n" + "}\n" + ".hashlink::before {\n" + " content: ' ';\n" + " visibility: hidden;\n" + "}\n" + ".inline + .hashlink,\n" + "[hidden] {\n" + " display: none !important;\n" + "}\n" + "hr + div.center:not(.ad-cnt):not(.topad):not(.middlead):not(.bottomad) {\n" + " display: none !important;\n" + "}\n" + ".page-num {\n" + " margin-right: -8px;\n" + "}\n" + ".fileText a {\n" + " unicode-bidi: -moz-isolate;\n" + " unicode-bidi: -webkit-isolate;\n" + "}\n" + "#g-recaptcha {\n" + " min-height: 78px;\n" + " height: auto;\n" + "}\n" + ":root:not(.js-enabled) #postForm {\n" + " display: table;\n" + "}\n" + "#captchaContainerAlt td:nth-child(2) {\n" + " display: table-cell !important;\n" + "}\n" + "canvas#tegaki-canvas {\n" + " background: none;\n" + "}\n" + "/* Disable obnoxious captcha fade-in. */\n" + "body > div:last-of-type {\n" + " transition: none !important;\n" + "}\n" + "/* Anti-autoplay */\n" + "audio.controls-added {\n" + " display: block;\n" + " margin: auto;\n" + "}\n" + ":root.anti-autoplay div.embed {\n" + " position: static;\n" + " width: auto;\n" + " height: auto;\n" + " text-align: center;\n" + "}\n" + ":root.anti-autoplay .autoplay-removed {\n" + " display: block !important;\n" + " min-width: 640px;\n" + " min-height: 390px;\n" + "}\n" + "/* fixed, z-index */\n" + "#overlay,\n" + "#fourchanx-settings,\n" + "#qp, #ihover,\n" + "#navlinks, .fixed #header-bar,\n" + ":root.float #updater,\n" + ":root.float #thread-stats,\n" + "#qr {\n" + " position: fixed;\n" + "}\n" + "#fourchanx-settings {\n" + " z-index: 999;\n" + "}\n" + "#overlay {\n" + " z-index: 900;\n" + "}\n" + "#qp, #ihover {\n" + " z-index: 60;\n" + "}\n" + "#menu, .gal-buttons {\n" + " z-index: 50;\n" + "}\n" + "#updater, #thread-stats {\n" + " z-index: 40;\n" + "}\n" + ":root.fixed #header-bar, #notifications {\n" + " z-index: 35;\n" + "}\n" + "#a-gallery {\n" + " z-index: 30;\n" + "}\n" + "#navlinks {\n" + " z-index: 25;\n" + "}\n" + "#qr {\n" + " z-index: 20;\n" + "}\n" + "#embedding {\n" + " z-index: 11;\n" + "}\n" + ":root.fixed-watcher #thread-watcher {\n" + " z-index: 10;\n" + "}\n" + ":root.fixed:not(.gallery-open) #header-bar:not(:hover) {\n" + " z-index: 8;\n" + "}\n" + "#thread-watcher {\n" + " z-index: 5;\n" + "}\n" + "/* Header */\n" + ".fixed.top-header body {\n" + " padding-top: 2em;\n" + "}\n" + ".fixed.bottom-header body {\n" + " padding-bottom: 2em;\n" + "}\n" + ".fixed #header-bar {\n" + " right: 0;\n" + " left: 0;\n" + " padding: 3px 4px 4px;\n" + " font-size: 12px;\n" + "}\n" + ".fixed.top-header #header-bar {\n" + " top: 0;\n" + "}\n" + ".fixed.bottom-header #header-bar {\n" + " bottom: 0;\n" + "}\n" + "#header-bar {\n" + " border-width: 0;\n" + " transition: all .1s .05s ease-in-out;\n" + "}\n" + ":root.fixed #header-bar {\n" + " box-shadow: -5px 1px 10px rgba(0, 0, 0, 0.20);\n" + "}\n" + ":root.centered-links #shortcuts {\n" + " width: 300px;\n" + " text-align: right;\n" + "}\n" + ":root.centered-links #header-bar {\n" + " text-align: center;\n" + "}\n" + "#custom-board-list {\n" + " font-size: 13px;\n" + " vertical-align: middle;\n" + "}\n" + "#full-board-list {\n" + " vertical-align: middle;\n" + "}\n" + ":root.centered-links #custom-board-list {\n" + " position: relative;\n" + " left: 150px;\n" + "}\n" + ".fixed.top-header #header-bar {\n" + " border-bottom-width: 1px;\n" + "}\n" + ".fixed.bottom-header #header-bar {\n" + " box-shadow: 0 -1px 2px rgba(0, 0, 0, .15);\n" + " border-top-width: 1px;\n" + "}\n" + ".fixed.bottom-header #header-bar .menu-button i {\n" + " border-top: none;\n" + " border-bottom: 6px solid;\n" + "}\n" + ".fixed #header-bar.autohide:not(:hover) {\n" + " box-shadow: none;\n" + " transition: all .8s .6s cubic-bezier(.55, .055, .675, .19);\n" + "}\n" + ".fixed.top-header #header-bar.autohide:not(:hover) {\n" + " margin-bottom: -1em;\n" + " -webkit-transform: translateY(-100%);\n" + " transform: translateY(-100%);\n" + "}\n" + ".fixed.bottom-header #header-bar.autohide:not(:hover) {\n" + " -webkit-transform: translateY(100%);\n" + " transform: translateY(100%);\n" + "}\n" + "#scroll-marker {\n" + " left: 0;\n" + " right: 0;\n" + " height: 10px;\n" + " position: absolute;\n" + "}\n" + "#header-bar:not(.autohide) #scroll-marker {\n" + " pointer-events: none;\n" + "}\n" + "#header-bar #scroll-marker {\n" + " display: none;\n" + "}\n" + ".fixed #header-bar #scroll-marker {\n" + " display: block;\n" + "}\n" + ".fixed.top-header #header-bar #scroll-marker {\n" + " top: 100%;\n" + "}\n" + ".fixed.bottom-header #header-bar #scroll-marker {\n" + " bottom: 100%;\n" + "}\n" + "#header-bar a:not(.entry):not(.close) {\n" + " text-decoration: none;\n" + " padding: 1px;\n" + "}\n" + "#shortcuts:empty {\n" + " display: none;\n" + "}\n" + ".brackets-wrap::before {\n" + " content: \"\\00a0[\";\n" + "}\n" + ".brackets-wrap::after {\n" + " content: \"]\\00a0\";\n" + "}\n" + ".dead-thread,\n" + ".disabled:not(.replies-quoting-you) {\n" + " opacity: .45;\n" + "}\n" + "#shortcuts {\n" + " float: right;\n" + "}\n" + ".shortcut {\n" + " margin-left: 3px;\n" + " vertical-align: middle;\n" + "}\n" + "#navbotright,\n" + "#navtopright {\n" + " display: none;\n" + "}\n" + "#toggleMsgBtn {\n" + " display: none !important;\n" + "}\n" + ".current {\n" + " font-weight: bold;\n" + "}\n" + "@media (min-width: 1300px) {\n" + " :root.fixed:not(.centered-links) #header-bar {\n" + " white-space: nowrap;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: center;\n" + " align-items: center;\n" + " }\n" + " :root.fixed:not(.centered-links) #board-list {\n" + " -webkit-flex: auto;\n" + " flex: auto;\n" + " }\n" + " :root.fixed:not(.centered-links) #full-board-list {\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " }\n" + " :root.fixed:not(.centered-links) .hide-board-list-container {\n" + " -webkit-flex: none;\n" + " flex: none;\n" + " margin-right: 5px;\n" + " }\n" + " :root.fixed:not(.centered-links) #full-board-list > .boardList {\n" + " -webkit-flex: auto;\n" + " flex: auto;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " width: 0px; /* XXX Fixes Edge not shrinking the board list below default size when needed */\n" + " }\n" + " :root.fixed:not(.centered-links) #full-board-list > .boardList > a,\n" + " :root.fixed:not(.centered-links) #full-board-list > .boardList > span:not(.space):not(.spacer) {\n" + " -webkit-flex: none;\n" + " flex: none;\n" + " padding: .17em;\n" + " margin: -.17em -.32em;\n" + " }\n" + " :root.fixed:not(.centered-links) #full-board-list > .boardList > span {\n" + " pointer-events: none;\n" + " }\n" + " :root.fixed:not(.centered-links) #full-board-list > .boardList > span.space {\n" + " -webkit-flex: 0 .63 .63em;\n" + " flex: 0 .63 .63em;\n" + " }\n" + " :root.fixed:not(.centered-links) #full-board-list > .boardList > span.spacer {\n" + " -webkit-flex: 0 .38 .38em;\n" + " flex: 0 .38 .38em;\n" + " }\n" + " :root.fixed:not(.centered-links) #shortcuts {\n" + " float: initial;\n" + " -webkit-flex: none;\n" + " flex: none;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: center;\n" + " align-items: center;\n" + " }\n" + "}\n" + "/* 4chan X link brackets */\n" + ".brackets-wrap::before {\n" + " content: \"[\";\n" + "}\n" + ".brackets-wrap::after {\n" + " content: \"]\";\n" + "}\n" + "/* Notifications */\n" + "#notifications {\n" + " position: fixed;\n" + " top: 0;\n" + " height: 0;\n" + " text-align: center;\n" + " right: 0;\n" + " left: 0;\n" + " visibility: visible;\n" + "}\n" + ":root.fixed.top-header:not(.gallery-open) #header-bar #notifications,\n" + ":root.fixed.top-header #header-bar.autohide #notifications {\n" + " position: absolute;\n" + " top: 100%;\n" + "}\n" + ".notification {\n" + " color: #FFF;\n" + " font-weight: 700;\n" + " text-shadow: 0 1px 2px rgba(0, 0, 0, .5);\n" + " box-shadow: 0 1px 2px rgba(0, 0, 0, .15);\n" + " border-radius: 2px;\n" + " margin: 1px auto;\n" + " width: 500px;\n" + " max-width: 100%;\n" + " position: relative;\n" + " transition: all .25s ease-in-out;\n" + "}\n" + ".notification.error {\n" + " background-color: hsla(0, 100%, 38%, .9);\n" + "}\n" + ".notification.warning {\n" + " background-color: hsla(36, 100%, 38%, .9);\n" + "}\n" + ".notification.info {\n" + " background-color: hsla(200, 100%, 38%, .9);\n" + "}\n" + ".notification.success {\n" + " background-color: hsla(104, 100%, 38%, .9);\n" + "}\n" + ".notification a {\n" + " color: white;\n" + "}\n" + ".notification > .close {\n" + " padding: 7px;\n" + " top: 0px;\n" + " right: 5px;\n" + " position: absolute;\n" + "}\n" + ".notification > .fa-times::before {\n" + " font-size: 11px !important;\n" + "}\n" + ".message {\n" + " -moz-box-sizing: border-box;\n" + " box-sizing: border-box;\n" + " padding: 6px 20px;\n" + " max-height: 200px;\n" + " width: 100%;\n" + " overflow: auto;\n" + " white-space: pre-line;\n" + "}\n" + "/* Settings */\n" + ":root.fourchan-x body {\n" + " -moz-box-sizing: border-box;\n" + " box-sizing: border-box;\n" + "}\n" + "#overlay {\n" + " background-color: rgba(0, 0, 0, .5);\n" + " top: 0;\n" + " left: 0;\n" + " height: 100%;\n" + " width: 100%;\n" + "}\n" + "#fourchanx-settings {\n" + " -moz-box-sizing: border-box;\n" + " box-sizing: border-box;\n" + " box-shadow: 0 0 15px rgba(0, 0, 0, .15);\n" + " height: 600px;\n" + " max-height: 100%;\n" + " width: 900px;\n" + " max-width: 100%;\n" + " margin: auto;\n" + " padding: 3px;\n" + " top: 50%;\n" + " left: 50%;\n" + " -moz-transform: translate(-50%, -50%);\n" + " -webkit-transform: translate(-50%, -50%);\n" + " transform: translate(-50%, -50%);\n" + "}\n" + "#fourchanx-settings > nav {\n" + " padding: 2px 2px 0;\n" + " height: 15px;\n" + "}\n" + "#fourchanx-settings > nav a {\n" + " text-decoration: underline;\n" + "}\n" + "#fourchanx-settings > nav a.close {\n" + " text-decoration: none;\n" + " padding: 0 2px;\n" + " margin: 0;\n" + "}\n" + ".section-container {\n" + " overflow: auto;\n" + " position: absolute;\n" + " top: 2.1em;\n" + " right: 5px;\n" + " bottom: 5px;\n" + " left: 5px;\n" + " padding-right: 5px;\n" + "}\n" + ".sections-list {\n" + " padding: 0 3px;\n" + " float: left;\n" + "}\n" + ".credits {\n" + " float: right;\n" + "}\n" + ".tab-selected {\n" + " font-weight: 700;\n" + "}\n" + ".section-sauce ul,\n" + ".section-advanced ul {\n" + " list-style: none;\n" + " margin: 0;\n" + "}\n" + ".section-sauce ul {\n" + " padding: 8px;\n" + "}\n" + ".section-advanced ul {\n" + " padding: 0px;\n" + "}\n" + ".section-sauce li,\n" + ".section-advanced li {\n" + " padding-left: 4px;\n" + "}\n" + ".section-main label {\n" + " text-decoration: underline;\n" + "}\n" + "div[data-checked=\"false\"] > .suboption-list {\n" + " display: none;\n" + "}\n" + ".suboption-list {\n" + " position: relative;\n" + "}\n" + ".suboption-list::before {\n" + " content: \"\";\n" + " display: inline-block;\n" + " position: absolute;\n" + " left: .7em;\n" + " width: 0;\n" + " height: 100%;\n" + " border-left: 1px solid;\n" + "}\n" + ".suboption-list > div {\n" + " position: relative;\n" + " padding-left: 1.4em;\n" + "}\n" + ".suboption-list > div::before {\n" + " content: \"\";\n" + " display: inline-block;\n" + " position: absolute;\n" + " left: .7em;\n" + " width: .7em;\n" + " height: .6em;\n" + " border-left: 1px solid;\n" + " border-bottom: 1px solid;\n" + "}\n" + ".section-filter ul {\n" + " padding: 0;\n" + "}\n" + ".section-filter li {\n" + " margin: 10px 40px;\n" + " list-style: disc;\n" + "}\n" + ".section-filter textarea {\n" + " height: 500px;\n" + "}\n" + ".section-filter a, .section-advanced a {\n" + " text-decoration: underline;\n" + "}\n" + ".section-sauce textarea {\n" + " height: 350px;\n" + "}\n" + ".section-advanced .field[name=\"boardnav\"] {\n" + " width: 100%;\n" + "}\n" + ".section-advanced textarea {\n" + " height: 150px;\n" + "}\n" + ".section-advanced .archive-cell {\n" + " min-width: 160px;\n" + " text-align: center;\n" + "}\n" + ".section-advanced #archive-board-select {\n" + " position: absolute;\n" + "}\n" + ".section-advanced .note {\n" + " font-size: 0.8em;\n" + " font-style: italic;\n" + " margin-left: 10px;\n" + "}\n" + ".section-advanced .note code {\n" + " font-style: normal;\n" + " font-size: 11px;\n" + "}\n" + ".section-keybinds .field {\n" + " font-family: monospace;\n" + "}\n" + "#fourchanx-settings fieldset {\n" + " border: 1px solid;\n" + " border-radius: 3px;\n" + " padding: 0.35em 0.625em 0.75em;\n" + " margin: 0px 2px;\n" + "}\n" + "#fourchanx-settings legend {\n" + " font-weight: 700;\n" + " color: inherit;\n" + "}\n" + "#fourchanx-settings textarea {\n" + " font-family: monospace;\n" + " min-width: 100%;\n" + " max-width: 100%;\n" + "}\n" + "#fourchanx-settings code {\n" + " color: #000;\n" + " background-color: #FFF;\n" + " padding: 0 2px;\n" + "}\n" + "#fourchanx-settings th {\n" + " text-align: center;\n" + " font-weight: bold;\n" + "}\n" + "#fourchanx-settings p {\n" + " margin: 1em 0px;\n" + "}\n" + ".unscroll {\n" + " overflow: hidden;\n" + "}\n" + "/* Index */\n" + ":root.index-loading .navLinks,\n" + ":root.index-loading .board,\n" + ":root.index-loading .pagelist,\n" + ":root.infinite-mode .pagelist,\n" + ":root.all-pages-mode .pagelist,\n" + ":root.catalog-mode .pagelist,\n" + ":root:not(.catalog-mode) .indexlink,\n" + ":root.catalog-mode .cataloglink,\n" + ":root:not(.catalog-mode) #hidden-label,\n" + ":root:not(.catalog-mode) #index-size {\n" + " display: none;\n" + "}\n" + "#index-search {\n" + " padding-right: 1.5em;\n" + " width: 100px;\n" + " transition: color .25s, border-color .25s, width .25s;\n" + "}\n" + "#index-search:focus,\n" + "#index-search[data-searching] {\n" + " width: 200px;\n" + "}\n" + "#index-search-clear {\n" + " color: gray;\n" + " display: inline-block;\n" + " position: relative;\n" + " left: -1em;\n" + " width: 0;\n" + "}\n" + "/* \`\`::-webkit-*'' selectors break selector lists on Firefox. */\n" + "#index-search::-webkit-search-cancel-button {\n" + " display: none;\n" + "}\n" + "#index-search:not([data-searching]) + #index-search-clear {\n" + " display: none;\n" + "}\n" + "#index-mode, #index-sort, #index-size {\n" + " float: right;\n" + "}\n" + ".summary {\n" + " text-decoration: none;\n" + "}\n" + "/* Catalog */\n" + ":root.catalog-mode .board {\n" + " text-align: center;\n" + "}\n" + ".catalog-thread {\n" + " display: -webkit-inline-flex;\n" + " display: inline-flex;\n" + " text-align: left;\n" + " -webkit-flex-direction: column;\n" + " flex-direction: column;\n" + " -webkit-align-items: center;\n" + " align-items: center;\n" + " margin: 0 2px 5px;\n" + " word-wrap: break-word;\n" + " vertical-align: top;\n" + " position: relative;\n" + "}\n" + ".catalog-thread > a {\n" + " flex-shrink: 0;\n" + " -webkit-flex-shrink: 0;\n" + " position: relative;\n" + "}\n" + ".catalog-small .catalog-thread {\n" + " width: 165px;\n" + " max-height: 320px;\n" + "}\n" + ".catalog-large .catalog-thread {\n" + " width: 270px;\n" + " max-height: 410px;\n" + "}\n" + ".catalog-thumb {\n" + " border-radius: 2px;\n" + " box-shadow: 0 0 5px rgba(0, 0, 0, .25);\n" + "}\n" + ".catalog-thumb.spoiler-file {\n" + " width: 100px;\n" + " height: 100px;\n" + "}\n" + ".catalog-thumb.deleted-file {\n" + " width: 127px;\n" + " height: 13px;\n" + " padding: 20px 11px;\n" + "}\n" + ".catalog-thumb.no-file {\n" + " width: 77px;\n" + " height: 13px;\n" + " padding: 20px 36px;\n" + "}\n" + ".catalog-icons > img,\n" + ".catalog-stats > .menu-button {\n" + " width: 1em;\n" + " height: 1em;\n" + " margin: 0;\n" + " vertical-align: text-top;\n" + " padding-left: 2px;\n" + "}\n" + ".catalog-stats > .menu-button {\n" + " text-align: center;\n" + " font-weight: normal;\n" + "}\n" + ".catalog-stats > .menu-button > i::before {\n" + " line-height: 11px;\n" + "}\n" + ".catalog-stats {\n" + " -webkit-flex-shrink: 0;\n" + " flex-shrink: 0;\n" + " cursor: help;\n" + " font-size: 10px;\n" + " font-weight: 700;\n" + " margin-top: 2px;\n" + "}\n" + ".catalog-thread > .subject {\n" + " -webkit-flex-shrink: 0;\n" + " flex-shrink: 0;\n" + " -webkit-align-self: stretch;\n" + " align-self: stretch;\n" + " font-weight: 700;\n" + " line-height: 1;\n" + " text-align: center;\n" + "}\n" + ".catalog-thread > .comment {\n" + " -webkit-flex-shrink: 1;\n" + " flex-shrink: 1;\n" + " -webkit-align-self: stretch;\n" + " align-self: stretch;\n" + " overflow: hidden;\n" + " text-align: center;\n" + "}\n" + "/* /tg/ dice rolls */\n" + ".board_tg .catalog-thread > .comment > b {\n" + " font-weight: normal;\n" + "}\n" + ".catalog-code {\n" + " background-color: #FFF;\n" + " display: inline-block;\n" + " max-width: 100%;\n" + "}\n" + ":root.hats-enabled .catalog-thread::after {\n" + " content: '';\n" + " pointer-events: none;\n" + " position: absolute;\n" + " background-size: contain;\n" + "}\n" + ":root.hats-enabled .catalog-small .catalog-thread::after {\n" + " left: -10px;\n" + " top: -65px;\n" + " width: 100px;\n" + " height: 100px;\n" + "}\n" + ":root.hats-enabled .catalog-large .catalog-thread::after {\n" + " left: -15px;\n" + " top: -105px;\n" + " width: 160px;\n" + " height: 160px;\n" + "}\n" + "/* Announcement Hiding */\n" + ":root.hide-announcement #globalMessage {\n" + " display: none;\n" + "}\n" + "span.hide-announcement {\n" + " font-size: 11px;\n" + " position: relative;\n" + " bottom: 5px;\n" + "}\n" + ".globalMessage, h2, h3 {\n" + " color: inherit !important;\n" + " font-size: 13px;\n" + " font-weight: 100;\n" + "}\n" + "/* Unread */\n" + "#unread-line {\n" + " margin: 0;\n" + " border-color: rgb(255,0,0);\n" + "}\n" + "/* Thread Updater */\n" + "#updater {\n" + " background: none;\n" + " border: none;\n" + " box-shadow: none;\n" + "}\n" + "#updater > .move {\n" + " position: absolute;\n" + " left: 0;\n" + " top: -5px;\n" + " width: 100%;\n" + " height: 5px;\n" + "}\n" + "#updater > div:last-child {\n" + " text-align: center;\n" + "}\n" + "#updater input[type=\"number\"] {\n" + " width: 4em;\n" + "}\n" + ":root.float #updater {\n" + " padding: 0px 3px;\n" + "}\n" + ".new {\n" + " color: limegreen;\n" + "}\n" + "#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) {\n" + " margin-left: 5px;\n" + "}\n" + "#update-timer {\n" + " cursor: pointer;\n" + "}\n" + "/* Thread Watcher */\n" + "#thread-watcher {\n" + " position: absolute;\n" + "}\n" + "#thread-watcher {\n" + " padding-bottom: 3px;\n" + " padding-left: 3px;\n" + " white-space: nowrap;\n" + " min-width: 146px;\n" + "}\n" + "#watched-threads {\n" + " overflow-x: hidden;\n" + " overflow-y: auto;\n" + "}\n" + "#thread-watcher .refresh {\n" + " padding: 0px 3px;\n" + "}\n" + ":root.fixed-watcher #thread-watcher {\n" + " position: fixed;\n" + "}\n" + ":root.fixed-watcher #watched-threads {\n" + " /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n" + " max-height: 85vh;\n" + " max-height: calc(100vh - 75px);\n" + "}\n" + ":root:not(.fixed-watcher) #watched-threads:not(:hover) {\n" + " max-height: 210px;\n" + " overflow-y: hidden;\n" + "}\n" + "#thread-watcher > .move {\n" + " padding-top: 3px;\n" + "}\n" + "#watched-threads > div {\n" + " padding-left: 3px;\n" + " padding-right: 3px;\n" + "}\n" + "#watched-threads .watcher-link {\n" + " max-width: 250px;\n" + " display: -webkit-inline-flex;\n" + " display: inline-flex;\n" + " -webkit-flex-direction: row;\n" + " flex-direction: row;\n" + "}\n" + "#watched-threads .watcher-unread {\n" + " -webkit-flex: 0 0 auto;\n" + " flex: 0 0 auto;\n" + "}\n" + "#watched-threads .watcher-unread::after {\n" + " content: \"\\00a0\";\n" + "}\n" + "#watched-threads .watcher-title {\n" + " overflow: hidden;\n" + " text-overflow: ellipsis;\n" + " -webkit-flex: 0 1 auto;\n" + " flex: 0 1 auto;\n" + "}\n" + "#thread-watcher a {\n" + " text-decoration: none;\n" + "}\n" + ":root:not(.toggleable-watcher) #thread-watcher .move > .close {\n" + " display: none;\n" + "}\n" + "#thread-watcher .move > .close {\n" + " position: absolute;\n" + " right: 0px;\n" + " top: 0px;\n" + " padding: 0px 4px;\n" + "}\n" + ".watch-thread-link {\n" + " padding-top: 18px;\n" + " width: 18px;\n" + " height: 0px;\n" + " display: inline-block;\n" + " background-repeat: no-repeat;\n" + " opacity: 0.2;\n" + " position: relative;\n" + " top: 1px;\n" + "}\n" + ".watch-thread-link.watched {\n" + " opacity: 1;\n" + "}\n" + "/* Thread Stats */\n" + "#thread-stats {\n" + " background: none;\n" + " border: none;\n" + " box-shadow: none;\n" + "}\n" + ":root.float #thread-stats > .move > :not(#page-count) {\n" + " pointer-events: none;\n" + "}\n" + ":root.float #thread-stats {\n" + " padding: 0px 3px;\n" + "}\n" + "#page-count {\n" + " cursor: pointer;\n" + "}\n" + "/* Quote */\n" + ".catalog-thread > .comment > span.quote, #arc-list span.quote {\n" + " color: #789922;\n" + "}\n" + ":root:not(.catalog-mode) .deadlink {\n" + " text-decoration: none !important;\n" + "}\n" + ".backlink.deadlink:not(.forwardlink),\n" + ".quotelink.deadlink:not(.forwardlink) {\n" + " text-decoration: underline !important;\n" + "}\n" + ".inlined {\n" + " opacity: .5;\n" + "}\n" + "#qp input, .forwarded {\n" + " display: none;\n" + "}\n" + ".quotelink.forwardlink,\n" + ".backlink.forwardlink {\n" + " text-decoration: none;\n" + " border-bottom: 1px dashed;\n" + "}\n" + ".filtered {\n" + " text-decoration: underline line-through;\n" + "}\n" + ":root.hide-backlinks .backlink.filtered,\n" + ":root.hide-backlinks .backlink.filtered + .hashlink.filtered {\n" + " display: none;\n" + "}\n" + ".postNum + .container::before {\n" + " content: \" \";\n" + "}\n" + ".inline {\n" + " border: 1px solid;\n" + " display: table;\n" + " margin: 2px 0;\n" + "}\n" + ".inline .post {\n" + " border: 0 !important;\n" + " background-color: transparent !important;\n" + " display: table !important;\n" + " margin: 0 !important;\n" + " padding: 1px 2px !important;\n" + "}\n" + "#qp > .opContainer::after {\n" + " content: '';\n" + " clear: both;\n" + " display: table;\n" + "}\n" + "#qp .post {\n" + " border: none;\n" + " margin: 0;\n" + " padding: 2px 2px 5px;\n" + "}\n" + "#qp img {\n" + " max-height: 80vh;\n" + " max-width: 50vw;\n" + "}\n" + "/* Quote Threading */\n" + ".threadContainer {\n" + " margin-left: 20px;\n" + " border-left: 1px solid rgba(128,128,128,.3);\n" + "}\n" + ".threadOP {\n" + " clear: both;\n" + "}\n" + "/* File */\n" + ".fileText-original,\n" + ".fnswitch:hover > .fntrunc,\n" + ".fnswitch:not(:hover) > .fnfull,\n" + ".expanded-image > .post > .file > .fileThumb > video[data-md5],\n" + ".expanded-image > .post > .file > .fileThumb > img[data-md5] {\n" + " display: none;\n" + "}\n" + ".full-image {\n" + " display: none;\n" + " cursor: pointer;\n" + "}\n" + ".expanded-image > .post > .file > .fileThumb > .full-image {\n" + " display: inline;\n" + "}\n" + ".expanded-image {\n" + " clear: left;\n" + "}\n" + ".expanding {\n" + " opacity: .5;\n" + "}\n" + ":root.fit-height .full-image {\n" + " max-height: 100vh;\n" + "}\n" + ":root.fit-height.fixed .full-image {\n" + " /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n" + " max-height: 93vh;\n" + " max-height: calc(100vh - 35px);\n" + "}\n" + ":root.fit-width .full-image {\n" + " max-width: 100%;\n" + "}\n" + ":root.gecko.fit-width .full-image {\n" + " width: 100%;\n" + "}\n" + ".fileThumb > .warning {\n" + " clear: both;\n" + "}\n" + "/* WEBM Metadata */\n" + ".webm-title > a::before {\n" + " content: \"title\";\n" + " text-decoration: underline;\n" + "}\n" + ".webm-title.loading > a::after {\n" + " content: \"...\";\n" + "}\n" + ".webm-title.error > a:hover::before,\n" + ".webm-title.error > a:focus::before {\n" + " content: \"error\";\n" + " text-decoration: none;\n" + "}\n" + ".webm-title > span {\n" + " cursor: text;\n" + "}\n" + ".webm-title.not-found > span::before {\n" + " content: \"not found\";\n" + "}\n" + ".webm-title:not(:hover):not(:focus) > span,\n" + ".webm-title:hover > span + a,\n" + ".webm-title:focus > span + a {\n" + " display: none;\n" + "}\n" + "/* Volume control */\n" + "input[name=\"Default Volume\"] {\n" + " width: 4em;\n" + " height: 1ex;\n" + " vertical-align: middle;\n" + " margin: 0px;\n" + "}\n" + "/* Fappe Tyme */\n" + ":root.fappeTyme .thread > .noFile,\n" + ":root.fappeTyme .threadContainer > .noFile {\n" + " display: none;\n" + "}\n" + "/* Werk Tyme */\n" + ":root.werkTyme .postContainer:not(.noFile) .fileThumb,\n" + ":root.werkTyme .catalog-thumb:not(.deleted-file):not(.no-file),\n" + ":root:not(.werkTyme) .werkTyme-filename {\n" + " display: none;\n" + "}\n" + ".werkTyme-filename {\n" + " font-weight: bold;\n" + "}\n" + ":root.werkTyme .catalog-thread > a {\n" + " text-align: center;\n" + " -webkit-align-self: stretch;\n" + " align-self: stretch;\n" + "}\n" + "/* Index/Reply Navigation */\n" + "#navlinks {\n" + " font-size: 16px;\n" + " top: 25px;\n" + " right: 10px;\n" + "}\n" + ":root.catalog-mode #navlinks {\n" + " display: none;\n" + "}\n" + "/* Highlighting */\n" + ".qphl {\n" + " outline: 2px solid rgba(216, 94, 49, .8);\n" + "}\n" + ":root.highlight-you .quotesYou.opContainer,\n" + ":root.highlight-you .quotesYou > .reply {\n" + " border-left: 3px solid rgba(221, 0, 0, .8);\n" + "}\n" + ":root.highlight-own .yourPost.opContainer,\n" + ":root.highlight-own .yourPost > .reply {\n" + " border-left: 3px dashed rgba(221, 0, 0, .8);\n" + "}\n" + ".filter-highlight.opContainer,\n" + ".filter-highlight > .reply {\n" + " box-shadow: inset 5px 0 rgba(221, 0, 0, .5);\n" + "}\n" + ":root.highlight-own .yourPost > div.sideArrows,\n" + ":root.highlight-you .quotesYou > div.sideArrows,\n" + ".filter-highlight > div.sideArrows {\n" + " color: rgba(221, 0, 0, .8);\n" + "}\n" + ":root.highlight-own .yourPost.opContainer::after,\n" + ":root.highlight-you .quotesYou.opContainer::after,\n" + ".filter-highlight.opContainer::after {\n" + " content: \"\";\n" + " display: block;\n" + " clear: both;\n" + "}\n" + ".filter-highlight .catalog-thumb,\n" + ".filter-highlight .werkTyme-filename {\n" + " box-shadow: 0 0 3px 3px rgba(255, 0, 0, .5);\n" + "}\n" + ".catalog-thread.watched .catalog-thumb,\n" + ".catalog-thread.watched .werkTyme-filename {\n" + " border: 2px solid rgba(255, 0, 0, .75);\n" + "}\n" + "/* Spoiler text */\n" + ":root.reveal-spoilers s,\n" + ":root.reveal-spoilers s > a {\n" + " color: white !important;\n" + "}\n" + ":root.reveal-spoilers .removed-spoiler::before {\n" + " content: \"[spoiler]\";\n" + "}\n" + ":root.reveal-spoilers .removed-spoiler::after {\n" + " content: \"[/spoiler]\";\n" + "}\n" + "/* Thread & Reply Hiding */\n" + ".hide-thread-button,\n" + ".hide-reply-button {\n" + " float: left;\n" + " margin-right: 4px;\n" + " padding: 2px;\n" + "}\n" + ".hide-thread-button:not(:hover),\n" + ".hide-reply-button:not(:hover) {\n" + " opacity: 0.4;\n" + "}\n" + ".threadContainer .hide-reply-button {\n" + " margin-left: 2px !important;\n" + " position: relative;\n" + " left: 1px;\n" + "}\n" + ".hide-thread-button {\n" + " margin-top: -1px;\n" + "}\n" + ".stub ~ * {\n" + " display: none !important;\n" + "}\n" + ".stub input {\n" + " display: inline-block;\n" + "}\n" + ".thread[hidden] + hr {\n" + " display: none;\n" + "}\n" + ":root.reply-hide div.sideArrows {\n" + " display: none;\n" + "}\n" + "/* QR */\n" + ":root.hide-original-post-form #togglePostFormLink,\n" + "#qr.autohide:not(.focus):not(:hover):not(:active) > form,\n" + ":root.thread-view #qr:not(.show-new-thread-option) select[data-name=\"thread\"],\n" + "#file-n-submit:not(.has-file) #qr-filerm {\n" + " display: none;\n" + "}\n" + ":root.hide-original-post-form #postForm {\n" + " display: none !important;\n" + "}\n" + "#qr select,\n" + "#qr-filename-container > a,\n" + ".remove,\n" + ".captcha-img {\n" + " cursor: pointer;\n" + "}\n" + "#qr {\n" + " position: fixed;\n" + " padding: 1px;\n" + " border: 1px solid transparent;\n" + " min-width: 300px;\n" + " border-radius: 3px 3px 0 0;\n" + "}\n" + "#qr > form {\n" + " /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n" + " max-height: 85vh;\n" + " max-height: calc(100vh - 75px);\n" + " overflow-y: auto;\n" + " overflow-x: hidden;\n" + "}\n" + "#qrtab {\n" + " border-radius: 3px 3px 0 0;\n" + "}\n" + "#qrtab {\n" + " margin-bottom: 1px;\n" + "}\n" + "#qr .close {\n" + " float: right;\n" + " padding: 0 3px;\n" + "}\n" + ".qr-link-container {\n" + " text-align: center;\n" + "}\n" + ".qr-link-container-bottom {\n" + " width: 200px;\n" + " position: absolute;\n" + " left: -100px;\n" + " margin-left: 50%;\n" + " text-align: center;\n" + "}\n" + ".qr-link {\n" + " border-radius: 3px;\n" + " padding: 6px 10px 5px;\n" + " font-weight: bold;\n" + " vertical-align: middle;\n" + " border-style: solid;\n" + " border-width: 1px;\n" + " font-size: 10pt;\n" + "}\n" + ".persona {\n" + " width: 100%;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-flex-direction: row;\n" + " flex-direction: row;\n" + "}\n" + ".persona .field {\n" + " -webkit-flex: 1;\n" + " flex: 1;\n" + " width: 0;\n" + "}\n" + "#qr.forced-anon input[data-name=\"name\"]:not(.force-show),\n" + "#qr.forced-anon input[data-name=\"sub\"]:not(.force-show),\n" + "#qr.reply-to-thread input[data-name=\"sub\"]:not(.force-show),\n" + "body:not(.board_f) #qr select[name=\"filetag\"],\n" + "#qr.reply-to-thread select[name=\"filetag\"],\n" + "body:not(.board_jp) #sjis-toggle,\n" + "body:not(.board_sci) #tex-preview-button,\n" + "#qr.tex-preview .textarea > :not(#tex-preview),\n" + "#qr:not(.tex-preview) #tex-preview {\n" + " display: none;\n" + "}\n" + ".persona button {\n" + " -webkit-flex: 0 0 23px;\n" + " flex: 0 0 23px;\n" + " -webkit-align-self: stretch;\n" + " align-self: stretch;\n" + " border: 1px solid #BBB;\n" + " padding: 0;\n" + " background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n" + " color: #000;\n" + "}\n" + "#qr.sjis-preview #sjis-toggle, #qr.tex-preview #tex-preview-button {\n" + " background: #DCDCDC;\n" + "}\n" + "#sjis-toggle, #qr.sjis-preview textarea.field {\n" + " font-family: \"IPAMonaPGothic\",\"Mona\",\"MS PGothic\",monospace;\n" + " font-size: 16px;\n" + " line-height: 17px;\n" + "}\n" + "#tex-preview-button {\n" + " font-size: 10px;\n" + "}\n" + "#tex-preview {\n" + " white-space: pre-line;\n" + "}\n" + "#qr textarea.field {\n" + " height: 14.8em;\n" + " min-height: 9em;\n" + "}\n" + "#qr.has-captcha textarea.field {\n" + " height: 9em;\n" + "}\n" + "input.field.tripped:not(:hover):not(:focus) {\n" + " color: transparent !important;\n" + " text-shadow: none !important;\n" + "}\n" + "#qr textarea {\n" + " min-width: 100%;\n" + " resize: both;\n" + "}\n" + ".field {\n" + " -moz-box-sizing: border-box;\n" + " margin: 0px;\n" + " padding: 2px 4px 3px;\n" + "}\n" + "#qr label input[type=\"checkbox\"] {\n" + " position: relative;\n" + " top: 2px;\n" + "}\n" + "/* Recaptcha v1 */\n" + ".captcha-img {\n" + " margin: 0px;\n" + " text-align: center;\n" + " background-image: #fff;\n" + " font-size: 0px;\n" + " min-height: 59px;\n" + " min-width: 302px;\n" + "}\n" + ".captcha-input {\n" + " width: 100%;\n" + " margin: 1px 0 0;\n" + "}\n" + "#qr.captcha-v1 #qr-captcha-iframe {\n" + " display: none;\n" + "}\n" + "/* Recaptcha v2 */\n" + "#qr .captcha-root {\n" + " position: relative;\n" + "}\n" + "#qr .captcha-container > div > div {\n" + " margin: auto;\n" + "}\n" + "#qr .captcha-counter {\n" + " display: block;\n" + " width: 100%;\n" + " text-align: center;\n" + " pointer-events: none;\n" + "}\n" + "#qr.captcha-open .captcha-counter {\n" + " position: absolute;\n" + " bottom: 3px;\n" + "}\n" + "#qr .captcha-counter > a {\n" + " pointer-events: auto;\n" + "}\n" + "#qr:not(.captcha-open) .captcha-counter > a {\n" + " display: block;\n" + " width: 100%;\n" + "}\n" + "#qr.captcha-v2 #qr-captcha-iframe {\n" + " width: 302px;\n" + " height: 423px;\n" + " border: 0;\n" + " display: block;\n" + " margin: auto;\n" + "}\n" + ".goog-bubble-content {\n" + " max-width: 100vw;\n" + " max-height: 100vh;\n" + " overflow: auto;\n" + "}\n" + ".goog-bubble-content iframe {\n" + " position: static !important;\n" + "}\n" + "/* File Input, Submit Button, Oekaki */\n" + "#file-n-submit, #qr .oekaki {\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: stretch;\n" + " align-items: stretch;\n" + " height: 25px;\n" + " margin-top: 1px;\n" + "}\n" + "#file-n-submit > input, #qr-draw-button {\n" + " background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n" + " border: 1px solid #BBB;\n" + " border-radius: 2px;\n" + " height: 100%;\n" + "}\n" + "#qr-file-button, #qr-draw-button {\n" + " width: 15%;\n" + "}\n" + "#file-n-submit input[type=\"submit\"] {\n" + " width: 25%;\n" + "}\n" + "#qr-filename-container {\n" + " -webkit-flex: 1 1 auto;\n" + " flex: 1 1 auto;\n" + " width: 0;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: center;\n" + " align-items: center;\n" + " position: relative;\n" + " padding: 1px;\n" + "}\n" + "input#qr-filename {\n" + " border: none !important;\n" + " background: none !important;\n" + " outline: none;\n" + "}\n" + "#qr-filename,\n" + ".has-file #qr-no-file {\n" + " display: none;\n" + "}\n" + "#qr-no-file,\n" + ".has-file #qr-filename {\n" + " -webkit-flex: 1 1 auto;\n" + " flex: 1 1 auto;\n" + " width: 0px; /* XXX Fixes filename not shrinking to allow space for buttons in Edge */\n" + " display: inline-block;\n" + " padding: 0;\n" + " padding-left: 3px;\n" + " overflow: hidden;\n" + " text-overflow: ellipsis;\n" + " white-space: nowrap;\n" + "}\n" + "#qr-no-file {\n" + " color: #AAA;\n" + "}\n" + "#qr .oekaki.has-file {\n" + " display: none;\n" + "}\n" + "#qr .oekaki > label {\n" + " -webkit-flex: 1 1 auto;\n" + " flex: 1 1 auto;\n" + " width: 0;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: center;\n" + " align-items: center;\n" + " height: 100%;\n" + "}\n" + "#qr .oekaki > label > span {\n" + " margin: 0 3px;\n" + "}\n" + "#qr .oekaki > label > input {\n" + " -webkit-flex: 1 1 auto;\n" + " flex: 1 1 auto;\n" + " width: 0;\n" + " height: 100%;\n" + "}\n" + "#qr .oekaki-bg {\n" + " position: relative;\n" + " display: inline-block;\n" + " height: 100%;\n" + " width: 10%;\n" + " margin-left: 3px;\n" + "}\n" + "#qr .oekaki-bg > * {\n" + " position: absolute;\n" + " top: 0;\n" + " left: 0;\n" + " margin: 0;\n" + "}\n" + "#qr .oekaki-bg > :not([name=\"oekaki-bgcolor\"]) {\n" + " z-index: 1;\n" + "}\n" + "#qr [name=\"oekaki-bgcolor\"] {\n" + " height: 100%;\n" + " width: 100%;\n" + " border: none;\n" + " padding: 0;\n" + "}\n" + "#qr [name=\"oekaki-bg\"]:not(:checked) ~ [name=\"oekaki-bgcolor\"] {\n" + " visibility: hidden;\n" + "}\n" + "#qr input[type=\"file\"] {\n" + " visibility: hidden;\n" + " position: absolute;\n" + "}\n" + "/* Spoiler Checkbox, QR Icons */\n" + "#qr-filename-container > label, #qr-filename-container > a {\n" + " -webkit-flex: none;\n" + " flex: none;\n" + " margin: 0;\n" + " margin-right: 3px;\n" + "}\n" + "#qr:not(.has-spoiler) #qr-spoiler-label,\n" + "#file-n-submit:not(.has-file) #qr-spoiler-label,\n" + ".has-file #paste-area,\n" + ".has-file #url-button,\n" + "#file-n-submit:not(.custom-cooldown) #custom-cooldown-button {\n" + " display: none;\n" + "}\n" + "#qr-filename-container > label {\n" + " position: relative;\n" + "}\n" + "#qr-filename-container input[type=\"checkbox\"] {\n" + " margin: 0;\n" + "}\n" + ".checkbox-letter {\n" + " font-size: 13px;\n" + " font-weight: bold;\n" + "}\n" + "#qr-filename-container label:not(:hover) > input[type=\"checkbox\"]:not(:focus):not(:checked),\n" + "#qr-filename-container label:not(:hover) > input[type=\"checkbox\"]:not(:focus):not(:checked) ~ :not(.checkbox-letter),\n" + "#qr-filename-container label:hover > .checkbox-letter,\n" + "input[type=\"checkbox\"]:focus ~ .checkbox-letter,\n" + "input[type=\"checkbox\"]:checked ~ .checkbox-letter {\n" + " /* not displayed but still focusable */\n" + " position: absolute;\n" + " opacity: 0;\n" + " pointer-events: none;\n" + "}\n" + ".checkbox-letter, #paste-area, #url-button, #custom-cooldown-button, #dump-button {\n" + " opacity: 0.6;\n" + "}\n" + "#paste-area {\n" + " font-size: 0;\n" + "}\n" + "#paste-area:focus {\n" + " opacity: 1;\n" + "}\n" + "#custom-cooldown-button.disabled {\n" + " opacity: 0.27;\n" + "}\n" + "/* Thread and Flash Tag Select */\n" + "#qr select {\n" + " background: white;\n" + " border: 1px solid #CCC;\n" + "}\n" + "#qr select[data-name=\"thread\"] {\n" + " float: right;\n" + "}\n" + "#qr > form > select {\n" + " margin-top: 1px;\n" + "}\n" + "/* Dumping UI */\n" + ".dump #dump-list-container {\n" + " display: block;\n" + "}\n" + "#dump-list-container {\n" + " display: none;\n" + " position: relative;\n" + " overflow-y: hidden;\n" + " margin-top: 1px;\n" + "}\n" + "#dump-list {\n" + " overflow-x: auto;\n" + " overflow-y: hidden;\n" + " white-space: nowrap;\n" + " width: 248px;\n" + " max-width: 100%;\n" + " min-width: 100%;\n" + "}\n" + "#dump-list:hover {\n" + " overflow-x: auto;\n" + "}\n" + ".qr-preview {\n" + " -moz-box-sizing: border-box;\n" + " counter-increment: thumbnails;\n" + " cursor: move;\n" + " display: inline-block;\n" + " height: 90px;\n" + " width: 90px;\n" + " padding: 2px;\n" + " opacity: .5;\n" + " overflow: hidden;\n" + " position: relative;\n" + " text-shadow: 0 0 2px #000;\n" + " -moz-transition: opacity .25s ease-in-out;\n" + " vertical-align: top;\n" + " background-size: cover;\n" + "}\n" + ".qr-preview:hover,\n" + ".qr-preview:focus {\n" + " opacity: .9;\n" + "}\n" + ".qr-preview::before {\n" + " content: counter(thumbnails);\n" + " color: #fff;\n" + " position: absolute;\n" + " top: 3px;\n" + " right: 3px;\n" + " text-shadow: 0 0 3px #000, 0 0 8px #000;\n" + "}\n" + ".qr-preview#selected {\n" + " opacity: 1;\n" + "}\n" + ".qr-preview.drag {\n" + " box-shadow: 0 0 10px rgba(0,0,0,.5);\n" + "}\n" + ".qr-preview.over {\n" + " border-color: #fff;\n" + "}\n" + ".qr-preview > span {\n" + " color: #fff;\n" + "}\n" + ".remove {\n" + " background: none;\n" + " color: #e00;\n" + " padding: 1px;\n" + "}\n" + "a:only-of-type > .remove {\n" + " display: none;\n" + "}\n" + ".remove:hover::after {\n" + " content: \" Remove\";\n" + "}\n" + ".qr-preview:not(.has-file) label,\n" + "#qr:not(.has-spoiler) .qr-preview-spoiler {\n" + " display: none;\n" + "}\n" + ".qr-preview > label {\n" + " background: rgba(0,0,0,.5);\n" + " color: #fff;\n" + " right: 0;\n" + " bottom: 0;\n" + " left: 0;\n" + " position: absolute;\n" + " text-align: center;\n" + "}\n" + ".qr-preview > label > input {\n" + " margin: 0;\n" + "}\n" + "#add-post {\n" + " cursor: pointer;\n" + " font-size: 2em;\n" + " position: absolute;\n" + " top: 50%;\n" + " right: 10px;\n" + " -moz-transform: translateY(-50%);\n" + "}\n" + ".textarea {\n" + " position: relative;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + "}\n" + ":root.webkit .textarea {\n" + " margin-bottom: -2px;\n" + "}\n" + "#char-count {\n" + " color: #000;\n" + " background: hsla(0, 0%, 100%, .5);\n" + " font-size: 8pt;\n" + " position: absolute;\n" + " bottom: 1px;\n" + " right: 1px;\n" + " pointer-events: none;\n" + "}\n" + "#char-count.warning {\n" + " color: red;\n" + "}\n" + "/* Menu */\n" + ".menu-button:not(.fa-bars) {\n" + " display: inline-block;\n" + " position: relative;\n" + " cursor: pointer;\n" + "}\n" + "#header-bar .menu-button i {\n" + " border-top: 6px solid;\n" + " border-right: 4px solid transparent;\n" + " border-left: 4px solid transparent;\n" + " display: inline-block;\n" + " margin: 2px;\n" + " vertical-align: middle;\n" + "}\n" + ".post .menu-button,\n" + "#thread-watcher .menu-button {\n" + " width: 18px;\n" + " height: 15px;\n" + " text-align: center;\n" + "}\n" + "#menu {\n" + " position: fixed;\n" + " outline: none;\n" + "}\n" + "#menu, .submenu {\n" + " border-radius: 3px;\n" + " padding-top: 1px;\n" + " padding-bottom: 3px;\n" + "}\n" + ".entry {\n" + " cursor: pointer;\n" + " display: block;\n" + " outline: none;\n" + " padding: 2px 10px;\n" + " position: relative;\n" + " text-decoration: none;\n" + " white-space: nowrap;\n" + " min-width: 70px;\n" + " text-align: left;\n" + " text-shadow: none;\n" + "}\n" + ".left>.entry.has-submenu {\n" + " padding-right: 17px !important;\n" + "}\n" + ".entry input[type=\"checkbox\"], \n" + ".entry input[type=\"radio\"] {\n" + " margin: 0px;\n" + " position: relative;\n" + " top: 2px;\n" + "}\n" + ".has-submenu::after {\n" + " content: \"\";\n" + " border-left: .5em solid;\n" + " border-top: .3em solid transparent;\n" + " border-bottom: .3em solid transparent;\n" + " display: inline-block;\n" + " margin: .3em;\n" + " position: absolute;\n" + " right: 3px;\n" + "}\n" + ".left .has-submenu::after {\n" + " border-left: 0;\n" + " border-right: .5em solid;\n" + "}\n" + ".submenu {\n" + " display: none;\n" + " position: absolute;\n" + " left: 100%;\n" + " top: -1px;\n" + " margin-left: 0px;\n" + " margin-top: -2px;\n" + "}\n" + ".focused > .submenu {\n" + " display: block;\n" + "}\n" + ".imp-exp-result {\n" + " position: absolute;\n" + " text-align: center;\n" + " margin: auto;\n" + " right: 0px;\n" + " left: 0px;\n" + " width: 200px;\n" + "}\n" + ".export, .import, .reset {\n" + " cursor: pointer;\n" + " text-decoration: none !important;\n" + "}\n" + "/* Custom Board Titles */\n" + ".boardTitle, .boardSubtitle {\n" + " white-space: pre-line;\n" + "}\n" + ".boardTitle[contenteditable=\"true\"],\n" + ".boardSubtitle[contenteditable=\"true\"] {\n" + " cursor: text !important;\n" + "}\n" + "/* Link Title Favicons */\n" + ".linkify.audio {\n" + " 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;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.gfycat {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.gist {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABblBMVEXc3NykpKTW1tbb29ugoKCdnZ0AAAACAgIEDRcKCgoMDAwODg4QIzYRDAoTExMUDwwVAg0WICsaEw8aGhoiCBklGxUmERwwKCQ7LSU7Ozs8LSZFLyNINi1JNyxJNy1KSklMOi5VR1FXV1daQTRkZGRseYZwU0F4eHh7dnR8bWV/YE6IdGiKcGCKkJaNgYeNjY2RdGOScWCUcWCZmZmhoaGkpKSoqKirfmaurq6xsbG1tbW6urq+vr7AbmzBb23CwsLGxsbHx8fHyMjJycnJysrMzMzOiYbPi4fQ0NDRoYbT09PU1NTW1tbY2NjZqIzZ2dnb29vd3d3f39/i4uLktZrk5OTl5eXm5ubn5+fo6Ojq6urs7OzttKLu7u7wuqbw8PDx8fHz8/P4+Pj5+fn7uZj8vpz9ya79ybD/tZf/upr/wZ//w6H/xKH/xaL/xrH/yqj/y7T/zqv/z7D/07D/17n/2Lv/2Lz/3L//38n/4Mk3Q/ZuAAAABnRSTlMSFcbGzc5MNKFvAAAA1klEQVQoz2NgYPZHAswMDEwRSclwkBTBxOARn4gE4j0YXBOiJNUDg7y8Ar1UlOITXBkcY73Z2Li42dg42dn4wmIdGeyjQ7nZoEA4PNqewSZKlw0O9KJsGKwjBdl4ZeWkJGQUhNjEIq0ZrMI5+D0ri7Jz8itCRAXCrRgsQ3mUy+xicrPSbfO0REItGSyCVaVL3ONSU9LcCtQUgy0YzIJ85M1LizMzCsv9xF2CzBhMAwN99TV1DI0MtDWcAgNNGUycA5CAswkDi5kDwrMOZiwMjKzGSICVEQDhZj0UQV7PewAAAABJRU5ErkJggg==') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.image {\n" + " 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;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.installgentoo {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABcVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3dIYAAAAAAAAAAAAbGh4BBAcCBgoBBgoCBwsCCQ/QzucCCA7MyuXZ1eUBBQmTh8fo5/i9svIAAADh3vQAAAACCA0CCQ8CCQ4DDBQbGCUDChDr6vgAAAAAAAAREBIDCxK6tdfe2fTv7/cDCxIDDBQEDRUHDhgMJjXk4PZdXWdLUFoUNEYOKDgSMUMRLUBneI4eTGj08/QmW3onW3rTzvfOx/giU3IiVHMkWHdEaYJobHv3+PokWHpua6TNy9xZgZ+1quz8/foQKj0XPFInWn0nW38tZ4o6fqg8gq48grA9hrU/i7pAhrNAiLdBjLtEjr1FksNIjr5Il8pImMtKWnNqhL97odKFqti5q/q5rPq60+nCt/vLw/vPx/jV0vHY0/rc1/rg2/vh3fzn4fzu6/vx8vf19Pv19Pz49/v5+Pv8/Pv8/fr9/vv+/frziVtUAAAAT3RSTlMABQYHCAoNDhARGRobL0ZOV1xdXV5fYGBmZnB0eX2MjZSaoaGio6mqqqustLq7zubo6Ojo6evt7u/x8fLy9/f4+Pj5+vr6+vr6+/39/v7+XKgUSwAAAMhJREFUKM9jYGDg4OZmZgABKINT1dBAhBHIYFMxMBIDisjbhoZbCTExsCu5hoeY8DEwcOkEx8fY6MqpucTGB0izglVEplcU5/gmRYWBVQDNMK+s0hN3SvMyBpsBNJxXw0NfwTEjVQZqHQMHj5RfWW5mliSEC7TPzK6yJD/bXZQRzGdXcisqLy309okA2Q4Eis4peQWmstqBCdGW/CABraC45ERBBs3A6Fh/AbAKTwsHa34QZW8NVsGuLqwswQSjQICTmYMFQaEDAAF8JHLfKGswAAAAAElFTkSuQmCC') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.liveleak {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAlNJREFUGBkFwU2LVmUYAODrPu8Z5x1xSpRBXQyFoLsBE+wfiO5atJOgnf9DUPwFgtGinUgEaQsRhHYuMtpEiEWuG5iNjuOcj+c8z911xXcXL/68c3Dw1fzhg0QgEQAAEYGUKXFie9vxlSs/xk/rdavjGEkmkWSih65z4osv9GfOiK6LzEyZ2uGh4dUrmzs72ddlUUhkoiMr4PT167589Mh6c1N0nSRlqrX67dat+PDyZXRT19m5edPnt28rGFHxMcJ6d9fprS1/37tneP3aemPD1uamUydPOru3p5DdGOH0tWsu3LhhxIQJM2qEpRT/Pn3q/du3AhARSmvGTH0lplKMrVkiYpVpQaJlighzhDkzhmEA0fcWoqAfyaFW4zTlgCABxlrNmY4ylUzLsiREprFWc0T2M+ZSjKWY0AEaltZUjJixZJIpuk5pTWlNP2BYFvOyKJkCAKU1tTXHrZlqVWolUxdhxsfVSj9FmJfFMM9GdICGGa01HyMstYpMIFPJVNDPmYZSTOPoOEKHzNRlKpmWWh1j6TpLa2SKTKVWU6Z+Qolwdm/P9QcPZKa2LH69e9eIMs+WCL/cv2/98CGZPrt61am+V9APq1X89eyZ/968obVYaiXT4dGREgG+vnPHeHgYMsH2+fP+efEihtVKv7SWw/6+9/v7KYLMhIywTJPamvOXLomukyRsrNf+ePzYkpl9dJ3SWgSCSCQCfz5/7pMLF2yfO6eLiAQcHRz4/cmT+HR7O+Ob3d0fNt69+7a2BiICQCJbA0EgE5lpvbXl1OXL3/8Pfax4+6SjSukAAAAASUVORK5CYII=') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.pastebin {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII=') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.soundcloud {\n" + " 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;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.video {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII=') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.vimeo {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg==') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.vocaroo {\n" + " 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;\n" + " padding-left: 18px;\n" + "}\n" + ".linkify.youtube {\n" + " background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=') center left no-repeat!important;\n" + " padding-left: 18px;\n" + "}\n" + "/* Embedding */\n" + "#embedding {\n" + " padding: 1px 4px 1px 4px;\n" + " position: fixed;\n" + "}\n" + "#embedding.empty {\n" + " display: none;\n" + "}\n" + "#embedding > div:first-child {\n" + " display: -webkit-flex;\n" + " display: flex;\n" + "}\n" + "#embedding .move {\n" + " -webkit-flex: 1;\n" + " flex: 1;\n" + "}\n" + "#embedding .jump {\n" + " margin: -1px 4px;\n" + " text-decoration: none;\n" + "}\n" + "/* Gallery */\n" + "#a-gallery {\n" + " position: fixed;\n" + " top: 0;\n" + " bottom: 0;\n" + " left: 0;\n" + " right: 0;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-flex-direction: row;\n" + " flex-direction: row;\n" + " background: rgba(0,0,0,0.7);\n" + "}\n" + ".gal-viewport {\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: stretch;\n" + " align-items: stretch;\n" + " -webkit-flex-direction: row;\n" + " flex-direction: row;\n" + " -webkit-flex: 1 1 auto;\n" + " flex: 1 1 auto;\n" + " overflow: hidden;\n" + "}\n" + ".gal-thumbnails {\n" + " -webkit-flex: 0 0 150px;\n" + " flex: 0 0 150px;\n" + " overflow-y: auto;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-flex-direction: column;\n" + " flex-direction: column;\n" + " -webkit-align-items: stretch;\n" + " align-items: stretch;\n" + " text-align: center;\n" + " background: rgba(0,0,0,.5);\n" + " border-left: 1px solid #222;\n" + "}\n" + ".gal-hide-thumbnails .gal-thumbnails {\n" + " display: none;\n" + "}\n" + ".gal-thumb img,\n" + ".gal-thumb video {\n" + " max-width: 125px;\n" + " max-height: 125px;\n" + " height: auto;\n" + " width: auto;\n" + "}\n" + ".gal-thumb {\n" + " -webkit-flex: 0 0 auto;\n" + " flex: 0 0 auto;\n" + " padding: 3px;\n" + " line-height: 0;\n" + " transition: background .2s linear;\n" + "}\n" + ".gal-highlight {\n" + " background: rgba(0, 190, 255,.8);\n" + "}\n" + ".gal-prev {\n" + " order: 0;\n" + " border-right: 1px solid #222;\n" + "}\n" + ".gal-next {\n" + " order: 2;\n" + " border-left: 1px solid #222;\n" + "}\n" + ".gal-prev,\n" + ".gal-next {\n" + " -webkit-flex: 0 0 20px;\n" + " flex: 0 0 20px;\n" + " position: relative;\n" + " cursor: pointer;\n" + " opacity: 0.7;\n" + " background-color: rgba(0, 0, 0, 0.3);\n" + "}\n" + ".gal-prev:hover,\n" + ".gal-next:hover {\n" + " opacity: 1;\n" + "}\n" + ".gal-prev::after,\n" + ".gal-next::after {\n" + " position: absolute;\n" + " top: 48.6%;\n" + " -webkit-transform: translateY(-50%);\n" + " transform: translateY(-50%);\n" + " display: inline-block;\n" + " border-top: 11px solid transparent;\n" + " border-bottom: 11px solid transparent;\n" + " content: \"\";\n" + "}\n" + ".gal-prev::after {\n" + " border-right: 12px solid #fff;\n" + " right: 5px;\n" + "}\n" + ".gal-next::after {\n" + " border-left: 12px solid #fff;\n" + " right: 3px;\n" + "}\n" + ".gal-image {\n" + " order: 1;\n" + " -webkit-flex: 1 0 auto;\n" + " flex: 1 0 auto;\n" + " display: -webkit-flex;\n" + " display: flex;\n" + " -webkit-align-items: flex-start;\n" + " align-items: flex-start;\n" + " -webkit-justify-content: space-around;\n" + " justify-content: space-around;\n" + " overflow: hidden;\n" + " /* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */\n" + " width: 1%;\n" + "}\n" + ":root:not(.gal-fit-height):not(.gal-pdf) .gal-image {\n" + " overflow-y: scroll !important;\n" + "}\n" + ":root:not(.gal-fit-width):not(.gal-pdf) .gal-image {\n" + " overflow-x: scroll !important;\n" + "}\n" + ".gal-image a {\n" + " margin: auto;\n" + " line-height: 0;\n" + " max-width: 100%;\n" + "}\n" + ":root.gal-pdf .gal-image a {\n" + " width: 100%;\n" + " height: 100%;\n" + "}\n" + ".gal-fit-width .gal-image img,\n" + ".gal-fit-width .gal-image video {\n" + " max-width: 100%;\n" + "}\n" + ".gal-fit-height .gal-image img,\n" + ".gal-fit-height .gal-image video {\n" + " /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n" + " max-height: 95vh;\n" + " max-height: calc(100vh - 25px);\n" + "}\n" + ".gal-image iframe {\n" + " width: 100%;\n" + " height: 100%;\n" + "}\n" + ".gal-buttons {\n" + " font-size: 2em;\n" + " margin-right: 3px;\n" + " padding-left: 7px;\n" + " padding-right: 7px;\n" + " top: 5px;\n" + "}\n" + ":root.gal-pdf .gal-buttons {\n" + " top: 40px;\n" + " background: rgba(0,0,0,0.6) !important;\n" + " border-radius: 3px;\n" + "}\n" + ".gal-buttons a {\n" + " color: #ffffff;\n" + " text-shadow: 0px 0px 1px #000000;\n" + "}\n" + ".gal-buttons i {\n" + " display: inline-block;\n" + " margin: 2px;\n" + " position: relative;\n" + "}\n" + ".gal-start i {\n" + " border-left: 10px solid;\n" + " border-top: 6px solid transparent;\n" + " border-bottom: 6px solid transparent;\n" + " bottom: 1px;\n" + "}\n" + ".gal-stop i {\n" + " border: 5px solid;\n" + " bottom: 2px;\n" + "}\n" + ".gal-buttons.gal-playing > .gal-start,\n" + ".gal-buttons:not(.gal-playing) > .gal-stop {\n" + " display: none;\n" + "}\n" + ".gal-buttons .menu-button i {\n" + " border-top: 10px solid;\n" + " border-right: 6px solid transparent;\n" + " border-left: 6px solid transparent;\n" + " bottom: 2px;\n" + " vertical-align: baseline;\n" + "}\n" + ".gal-buttons,\n" + ".gal-name,\n" + ".gal-count {\n" + " position: fixed;\n" + " right: 195px;\n" + "}\n" + ".gal-hide-thumbnails .gal-buttons,\n" + ".gal-hide-thumbnails .gal-count,\n" + ".gal-hide-thumbnails .gal-name {\n" + " right: 44px;\n" + "}\n" + ".gal-name {\n" + " bottom: 6px;\n" + " background: rgba(0,0,0,0.6) !important;\n" + " border-radius: 3px;\n" + " padding: 1px 5px 2px 5px;\n" + " text-decoration: none !important;\n" + " color: white !important;\n" + "}\n" + ".gal-name:hover,\n" + ".gal-buttons a:hover {\n" + " color: rgb(95, 95, 101) !important;\n" + "}\n" + ":root.gal-pdf .gal-buttons a:hover {\n" + " color: rgb(204, 204, 204) !important;\n" + "}\n" + ".gal-count {\n" + " bottom: 27px;\n" + " background: rgba(0,0,0,0.6) !important;\n" + " border-radius: 3px;\n" + " padding: 1px 5px 2px 5px;\n" + " color: #ffffff !important;\n" + "}\n" + ":root:not(.gal-fit-width):not(.gal-pdf) .gal-name {\n" + " bottom: 23px !important;\n" + "}\n" + ":root:not(.gal-fit-width):not(.gal-pdf) .gal-count {\n" + " bottom: 44px !important;\n" + "}\n" + ":root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-buttons,\n" + ":root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-name,\n" + ":root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-count {\n" + " right: 178px !important;\n" + "}\n" + ":root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-buttons,\n" + ":root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-name,\n" + ":root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-count {\n" + " right: 28px !important;\n" + "}\n" + ".field[name=\"Slide Delay\"] {\n" + " width: 4em;\n" + "}\n" + ":root.gallery-open.fixed #header-bar:not(.autohide),\n" + ":root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before {\n" + " visibility: hidden;\n" + "}\n" + "/* General */\n" + ":root.yotsuba .dialog {\n" + " background-color: #F0E0D6;\n" + " border-color: #D9BFB7;\n" + "}\n" + ":root.yotsuba .field:focus,\n" + ":root.yotsuba .field.focus {\n" + " border-color: #EA8;\n" + "}\n" + "/* Header */\n" + ":root.yotsuba #header-bar.dialog {\n" + " background-color: rgba(240,224,214,0.98);\n" + "}\n" + ":root.yotsuba:not(.fixed) #header-bar, :root.yotsuba #notifications {\n" + " font-size: 9pt;\n" + "}\n" + ":root.yotsuba #header-bar, :root.yotsuba #notifications {\n" + " color: #B86;\n" + "}\n" + ":root.yotsuba #board-list a, :root.yotsuba #shortcuts a {\n" + " color: #800000;\n" + "}\n" + "/* Settings */\n" + ":root.yotsuba #fourchanx-settings fieldset, :root.yotsuba .section-main div::before {\n" + " border-color: #D9BFB7;\n" + "}\n" + ":root.yotsuba .suboption-list > div:last-of-type {\n" + " background-color: #F0E0D6;\n" + "}\n" + "/* Quote */\n" + ":root.yotsuba .backlink.deadlink {\n" + " color: #00E !important;\n" + "}\n" + ":root.yotsuba .inline {\n" + " border-color: #D9BFB7;\n" + " background-color: rgba(255, 255, 255, .14);\n" + "}\n" + "/* QR */\n" + ".yotsuba #dump-list::-webkit-scrollbar-thumb {\n" + " background-color: #F0E0D6;\n" + " border-color: #D9BFB7;\n" + "}\n" + ":root.yotsuba .qr-preview {\n" + " background-color: rgba(0, 0, 0, .15);\n" + "}\n" + ":root.yotsuba .qr-link {\n" + " border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184);\n" + " background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent;\n" + "}\n" + ":root.yotsuba .qr-link:hover {\n" + " background: #F0E0D6;\n" + "}\n" + "/* Menu */\n" + ":root.yotsuba #menu {\n" + " color: #800000;\n" + "}\n" + ":root.yotsuba .entry {\n" + " font-size: 10pt;\n" + "}\n" + ":root.yotsuba .focused.entry {\n" + " background: rgba(255, 255, 255, .33);\n" + "}\n" + "/* Thread Watcher */\n" + ":root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.disabled.replies-quoting-you {\n" + " color: #F00;\n" + "}\n" + "/* Watcher Favicon */\n" + ":root.yotsuba .watch-thread-link\n" + "{\n" + " background-image: url(\"data:image/svg+xml,\");\n" + "}\n" + "/* General */\n" + ":root.yotsuba-b .dialog {\n" + " background-color: #D6DAF0;\n" + " border-color: #B7C5D9;\n" + "}\n" + ":root.yotsuba-b .field:focus,\n" + ":root.yotsuba-b .field.focus {\n" + " border-color: #98E;\n" + "}\n" + "/* Header */\n" + ":root.yotsuba-b #header-bar.dialog {\n" + " background-color: rgba(214,218,240,0.98);\n" + "}\n" + ":root.yotsuba-b:not(.fixed) #header-bar, :root.yotsuba-b #notifications {\n" + " font-size: 9pt;\n" + "}\n" + ":root.yotsuba-b #header-bar, :root.yotsuba-b #notifications {\n" + " color: #89A;\n" + "}\n" + ":root.yotsuba-b #board-list a, :root.yotsuba-b #shortcuts a {\n" + " color: #34345C;\n" + "}\n" + "/* Settings */\n" + ":root.yotsuba-b #fourchanx-settings fieldset, :root.yotsuba-b .section-main div::before {\n" + " border-color: #B7C5D9;\n" + "}\n" + ":root.yotsuba-b .suboption-list > div:last-of-type {\n" + " background-color: #D6DAF0;\n" + "}\n" + "/* Quote */\n" + ":root.yotsuba-b .backlink.deadlink {\n" + " color: #34345C !important;\n" + "}\n" + ":root.yotsuba-b .inline {\n" + " border-color: #B7C5D9;\n" + " background-color: rgba(255, 255, 255, .14);\n" + "}\n" + "/* QR */\n" + ".yotsuba-b #dump-list::-webkit-scrollbar-thumb {\n" + " background-color: #D6DAF0;\n" + " border-color: #B7C5D9;\n" + "}\n" + ":root.yotsuba-b .qr-preview {\n" + " background-color: rgba(0, 0, 0, .15);\n" + "}\n" + ":root.yotsuba-b .qr-link {\n" + " border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210);\n" + " background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent;\n" + "}\n" + ":root.yotsuba-b .qr-link:hover {\n" + " background: #D9DDF3;\n" + "}\n" + "/* Menu */\n" + ":root.yotsuba-b #menu {\n" + " color: #000;\n" + "}\n" + ":root.yotsuba-b .entry {\n" + " font-size: 10pt;\n" + "}\n" + ":root.yotsuba-b .focused.entry {\n" + " background: rgba(255, 255, 255, .33);\n" + "}\n" + "/* Thread Watcher */\n" + ":root.yotsuba-b .replies-quoting-you > a, :root.yotsuba-b #watcher-link.disabled.replies-quoting-you {\n" + " color: #F00;\n" + "}\n" + "/* Watcher Favicon */\n" + ":root.yotsuba-b .watch-thread-link\n" + "{\n" + " background-image: url(\"data:image/svg+xml,\");\n" + "}\n" + "/* General */\n" + ":root.futaba .dialog {\n" + " background-color: #F0E0D6;\n" + " border-color: #D9BFB7;\n" + "}\n" + ":root.futaba .field:focus,\n" + ":root.futaba .field.focus {\n" + " border-color: #EA8;\n" + "}\n" + "/* Header */\n" + ":root.futaba #header-bar.dialog {\n" + " background-color: rgba(240,224,214,0.98);\n" + "}\n" + ":root.futaba:not(.fixed) #header-bar, :root.futaba #notifications {\n" + " font-size: 11pt;\n" + "}\n" + ":root.futaba #header-bar, :root.futaba #notifications {\n" + " color: #B86;\n" + "}\n" + ":root.futaba #header-bar a, :root.futaba #notifications a {\n" + " color: #800000;\n" + "}\n" + "/* Settings */\n" + ":root.futaba #fourchanx-settings fieldset, :root.futaba .section-main div::before {\n" + " border-color: #D9BFB7;\n" + "}\n" + ":root.futaba .suboption-list > div:last-of-type {\n" + " background-color: #F0E0D6;\n" + "}\n" + "/* Quote */\n" + ":root.futaba .backlink.deadlink {\n" + " color: #00E !important;\n" + "}\n" + ":root.futaba .inline {\n" + " border-color: #D9BFB7;\n" + " background-color: rgba(255, 255, 255, .14);\n" + "}\n" + "/* QR */\n" + ".futaba #dump-list::-webkit-scrollbar-thumb {\n" + " background-color: #F0E0D6;\n" + " border-color: #D9BFB7;\n" + "}\n" + ":root.futaba .qr-preview {\n" + " background-color: rgba(0, 0, 0, .15);\n" + "}\n" + ":root.futaba .qr-link {\n" + " border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184);\n" + " background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent;\n" + "}\n" + ":root.futaba .qr-link:hover {\n" + " background: #F0E0D6;\n" + "}\n" + "/* Menu */\n" + ":root.futaba #menu {\n" + " color: #800000;\n" + "}\n" + ":root.futaba .entry {\n" + " font-size: 12pt;\n" + "}\n" + ":root.futaba .focused.entry {\n" + " background: rgba(255, 255, 255, .33);\n" + "}\n" + "/* Thread Watcher */\n" + ":root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.disabled.replies-quoting-you {\n" + " color: #F00;\n" + "}\n" + "/* Watcher Favicon */\n" + ":root.futaba .watch-thread-link\n" + "{\n" + " background-image: url(\"data:image/svg+xml,\");\n" + "}\n" + "/* General */\n" + ":root.burichan .dialog {\n" + " background-color: #D6DAF0;\n" + " border-color: #B7C5D9;\n" + "}\n" + ":root.burichan .field:focus,\n" + ":root.burichan .field.focus {\n" + " border-color: #98E;\n" + "}\n" + "/* Header */\n" + ":root.burichan #header-bar.dialog {\n" + " background-color: rgba(214,218,240,0.98);\n" + "}\n" + ":root.burichan:not(.fixed) #header-bar, :root.burichan #header-bar #notifications {\n" + " font-size: 11pt;\n" + "}\n" + ":root.burichan #header-bar, :root.burichan #header-bar #notifications {\n" + " color: #89A;\n" + "}\n" + ":root.burichan #header-bar a, :root.burichan #header-bar #notifications a {\n" + " color: #34345C;\n" + "}\n" + "/* Settings */\n" + ":root.burichan #fourchanx-settings fieldset, :root.burichan .section-main div::before {\n" + " border-color: #B7C5D9;\n" + "}\n" + ":root.burichan .suboption-list > div:last-of-type {\n" + " background-color: #D6DAF0;\n" + "}\n" + "/* Quote */\n" + ":root.burichan .backlink.deadlink {\n" + " color: #34345C !important;\n" + "}\n" + ":root.burichan .inline {\n" + " border-color: #B7C5D9;\n" + " background-color: rgba(255, 255, 255, .14);\n" + "}\n" + "/* QR */\n" + ".burichan #dump-list::-webkit-scrollbar-thumb {\n" + " background-color: #D6DAF0;\n" + " border-color: #B7C5D9;\n" + "}\n" + ":root.burichan .qr-preview {\n" + " background-color: rgba(0, 0, 0, .15);\n" + "}\n" + ":root.burichan .qr-link {\n" + " border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210);\n" + " background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent;\n" + "}\n" + ":root.burichan .qr-link:hover {\n" + " background: #D9DDF3;\n" + "}\n" + "/* Menu */\n" + ":root.burichan #menu {\n" + " color: #000000;\n" + "}\n" + ":root.burichan .entry {\n" + " font-size: 12pt;\n" + "}\n" + ":root.burichan .focused.entry {\n" + " background: rgba(255, 255, 255, .33);\n" + "}\n" + "/* Thread Watcher */\n" + ":root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.disabled.replies-quoting-you {\n" + " color: #F00;\n" + "}\n" + "/* Watcher Favicon */\n" + ":root.burichan .watch-thread-link\n" + "{\n" + " background-image: url(\"data:image/svg+xml,\");\n" + "}\n" + "/* General */\n" + ":root.tomorrow .dialog {\n" + " background-color: #282A2E;\n" + " border-color: #111;\n" + "}\n" + "/* Header */\n" + ":root.tomorrow #header-bar.dialog {\n" + " background-color: rgba(40,42,46,0.9);\n" + "}\n" + ":root.tomorrow:not(.fixed) #header-bar, :root.tomorrow #notifications {\n" + " font-size: 9pt;\n" + "}\n" + ":root.tomorrow #header-bar, :root.tomorrow #notifications {\n" + " color: #C5C8C6;\n" + "}\n" + ":root.tomorrow #header-bar a, :root.tomorrow #notifications a {\n" + " color: #81A2BE;\n" + "}\n" + "/* Settings */\n" + ":root.tomorrow #fourchanx-settings fieldset, :root.tomorrow .section-main div::before {\n" + " border-color: #111;\n" + "}\n" + ":root.tomorrow .suboption-list > div:last-of-type {\n" + " background-color: #282A2E;\n" + "}\n" + "/* Catalog */\n" + ":root.tomorrow .catalog-code {\n" + " background-color: rgba(255, 255, 255, 0.1);\n" + "}\n" + "/* Quote */\n" + ":root.tomorrow .catalog-thread > .comment > span.quote, :root.tomorrow #arc-list span.quote {\n" + " color: #B5BD68;\n" + "}\n" + ":root.tomorrow .backlink.deadlink {\n" + " color: #81A2BE !important;\n" + "}\n" + ":root.tomorrow .inline {\n" + " border-color: #111;\n" + " background-color: rgba(0, 0, 0, .14);\n" + "}\n" + "/* Highlighting */\n" + ":root.tomorrow .qphl {\n" + " outline: 2px solid rgba(145, 182, 214, .8);\n" + "}\n" + ":root.tomorrow.highlight-you .quotesYou.opContainer,\n" + ":root.tomorrow.highlight-you .quotesYou > .reply {\n" + " border-left: 3px solid rgba(145, 182, 214, .8);\n" + "}\n" + ":root.tomorrow.highlight-own .yourPost.opContainer,\n" + ":root.tomorrow.highlight-own .yourPost > .reply {\n" + " border-left: 3px dashed rgba(145, 182, 214, .8);\n" + "}\n" + ":root.tomorrow .opContainer.filter-highlight,\n" + ":root.tomorrow .filter-highlight > .reply {\n" + " box-shadow: inset 5px 0 rgba(145, 182, 214, .5);\n" + "}\n" + ":root.tomorrow.highlight-own .yourPost > div.sideArrows,\n" + ":root.tomorrow.highlight-you .quotesYou > div.sideArrows,\n" + ":root.tomorrow .filter-highlight > div.sideArrows {\n" + " color: rgb(155, 185, 210);\n" + "}\n" + ":root.tomorrow .filter-highlight .catalog-thumb,\n" + ":root.tomorrow .filter-highlight .werkTyme-filename {\n" + " box-shadow: 0 0 3px 3px rgba(64, 192, 255, .7);\n" + "}\n" + ":root.tomorrow .catalog-thread.watched .catalog-thumb,\n" + ":root.tomorrow .catalog-thread.watched .werkTyme-filename {\n" + " border: 2px solid rgb(64, 192, 255);\n" + "}\n" + "/* QR */\n" + ".tomorrow #dump-list::-webkit-scrollbar-thumb {\n" + " background-color: #282A2E;\n" + " border-color: #111;\n" + "}\n" + ":root.tomorrow .qr-preview {\n" + " background-color: rgba(255, 255, 255, .15);\n" + "}\n" + ":root.tomorrow #qr .field {\n" + " background-color: rgb(26, 27, 29);\n" + " color: rgb(197,200,198);\n" + " border-color: rgb(40, 41, 42);\n" + "}\n" + ":root.tomorrow #qr .field:focus,\n" + ":root.tomorrow #qr .field.focus {\n" + " border-color: rgb(129, 162, 190) !important;\n" + " background-color: rgb(30,32,36);\n" + "}\n" + ":root.tomorrow .persona button {\n" + " background: linear-gradient(to bottom, #2E3035, #222427) no-repeat;\n" + " color: rgb(197,200,198);\n" + " border-color: rgb(40, 41, 42);\n" + " outline: none;\n" + "}\n" + ":root.tomorrow .persona button::-moz-focus-inner {\n" + " border: none;\n" + "}\n" + ":root.tomorrow .persona button:focus {\n" + " border-color: rgb(129, 162, 190);\n" + "}\n" + ":root.tomorrow #qr.sjis-preview #sjis-toggle,\n" + ":root.tomorrow #qr.tex-preview #tex-preview-button {\n" + " background: rgb(26, 27, 29);\n" + "}\n" + ":root.tomorrow #qr select,\n" + ":root.tomorrow #file-n-submit > input,\n" + ":root.tomorrow #qr-draw-button {\n" + " border-color: rgb(40, 41, 42);\n" + "}\n" + ":root.tomorrow #qr-filename {\n" + " color: rgb(197,200,198);\n" + "}\n" + ":root.tomorrow .qr-link {\n" + " border-color: rgb(25, 27, 31) rgb(25, 27, 31) rgb(10, 12, 16);\n" + " background: linear-gradient(#37393D, #282A2E) repeat scroll 0% 0% transparent;\n" + "}\n" + ":root.tomorrow .qr-link:hover {\n" + " background: #282A2E;\n" + "}\n" + "/* Menu */\n" + ":root.tomorrow #menu {\n" + " color: #C5C8C6;\n" + "}\n" + ":root.tomorrow .entry {\n" + " font-size: 10pt;\n" + "}\n" + ":root.tomorrow .focused.entry {\n" + " background: rgba(0, 0, 0, .33);\n" + "}\n" + "/* Unread */\n" + ":root.tomorrow #unread-line {\n" + " border-color: rgb(197, 200, 198);\n" + "}\n" + "/* Thread Watcher */\n" + ":root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.disabled.replies-quoting-you {\n" + " color: #F00 !important;\n" + "}\n" + "/* Watcher Favicon */\n" + ":root.tomorrow .watch-thread-link\n" + "{\n" + " background-image: url(\"data:image/svg+xml,\");\n" + "}\n" + "/* General */\n" + ":root.photon .dialog {\n" + " background-color: #DDD;\n" + " border-color: #CCC;\n" + "}\n" + ":root.photon .field:focus,\n" + ":root.photon .field.focus {\n" + " border-color: #EA8;\n" + "}\n" + "/* Header */\n" + ":root.photon #header-bar.dialog {\n" + " background-color: rgba(221,221,221,0.98);\n" + "}\n" + ":root.photon:not(.fixed) #header-bar, :root.photon #notifications {\n" + " font-size: 9pt;\n" + "}\n" + ":root.photon #header-bar, :root.photon #notifications {\n" + " color: #333;\n" + "}\n" + ":root.photon #header-bar a, :root.photon #notifications a {\n" + " color: #FF6600;\n" + "}\n" + "/* Settings */\n" + ":root.photon #fourchanx-settings fieldset, :root.photon .section-main div::before {\n" + " border-color: #CCC;\n" + "}\n" + ":root.photon .suboption-list > div:last-of-type {\n" + " background-color: #DDD;\n" + "}\n" + "/* Catalog */\n" + ":root.photon .catalog-code {\n" + " background-color: rgba(150, 150, 150, 0.2);\n" + "}\n" + "/* Quote */\n" + ":root.photon #arc-list tr:nth-of-type(odd) span.quote {\n" + " color: #C0E17A;\n" + "}\n" + ":root.photon .backlink.deadlink {\n" + " color: #F60 !important;\n" + "}\n" + ":root.photon .inline {\n" + " border-color: #CCC;\n" + " background-color: rgba(255, 255, 255, .14);\n" + "}\n" + "/* QR */\n" + ".photon #dump-list::-webkit-scrollbar-thumb {\n" + " background-color: #DDD;\n" + " border-color: #CCC;\n" + "}\n" + ":root.photon .qr-preview {\n" + " background-color: rgba(0, 0, 0, .15);\n" + "}\n" + ":root.photon .qr-link {\n" + " border-color: rgb(206, 206, 206) rgb(206, 206, 206) rgb(191, 191, 191);\n" + " background: linear-gradient(#ECECEC, #DDD) repeat scroll 0% 0% transparent;\n" + "}\n" + ":root.photon .qr-link:hover {\n" + " background: #DDDDDD;\n" + "}\n" + "/* Menu */\n" + ":root.photon #menu {\n" + " color: #333;\n" + "}\n" + ":root.photon .entry {\n" + " font-size: 10pt;\n" + "}\n" + ":root.photon .focused.entry {\n" + " background: rgba(255, 255, 255, .33);\n" + "}\n" + "/* Thread Watcher */\n" + ":root.photon .replies-quoting-you > a, :root.photon #watcher-link.disabled.replies-quoting-you {\n" + " color: #00F !important;\n" + "}\n" + "/* Watcher Favicon */\n" + ":root.photon .watch-thread-link\n" + "{\n" + " background-image: url(\"data:image/svg+xml,\");\n" + "}\n" + "/* XXX Moved to end of stylesheet to avoid breaking whole stylesheet in Maxthon. */\n" + "@supports (text-decoration-style: dashed) or (-moz-text-decoration-style: dashed) {\n" + " .quotelink.forwardlink,\n" + " .backlink.forwardlink {\n" + " text-decoration: underline;\n" + " -moz-text-decoration-style: dashed;\n" + " text-decoration-style: dashed;\n" + " border-bottom: none;\n" + " }\n" + "}", cssWWW: "#captcha-cnt {\n" + " height: auto;\n" + "}", features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Replacement', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.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], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['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], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] }; Main.init(); }).call(this);