Stories
Slash Boxes
Comments

SoylentNews is people

Log In

Log In

Create Account  |  Retrieve Password


My Ideal House, Part 1

Posted by cafebabe on Tuesday October 31 2017, @01:57PM (#2721)
0 Comments
Hardware

(This is tangentially related to other topics and is here for completeness.)

Two Storey, Large, Conventional Design

              Downstairs                                     Upstairs
+-----------------------   ---+---------+     +-----------------------------+---------+
|                             |         |     |               |             |         |
|                             |         |     |               |             |         |
|           Kitchen           | Heating |     |               |   Bedroom   |         |
|             and             |   and   |     |    Bedroom    |             | Bedroom |
|           Dining              Storage |     |               |             |         |
|                             |         |     |               +-------   ---+         |
|                             |         |     |                                       |
+-------------   ---+------   +---------+     +---------------+   +         +---------+
|                   |         |         |     |                   |         |         |
|                   |                   |     |                   |                   |
|                   |         |         |     |                   |         |  Bath   |
|                   |         | Office  |     |                   |         |   and   |
|                   |  Hall   |         |     |                   |  Hall   | Shower  |
|    Living Room    |   and   |         |     |      Bedroom      |   and   |         |
|                   | Stairs  |         |     |                   | Stairs  |         |
|                   |         +---------+     |                   |         +---------+
|                   |         |         |     |                   |         |         |
|                               Toilet  |     |                   |           Toilet  |
|                   |         |         |     |                   |         |         |
+-------------------+---   ---+---------+     +-------------------+---------+---------+

Two Storey, Medium, Conventional Design

         Downstairs                           Upstairs
+---------+---------+---   ---+     +---------+---------+---------+
|         |         |         |     |         |         |         |
|         |         |         |     |         | Heating |         |
|         | Toilet  |         |     |         |   and   |  Bath   |
| Office  |         | Kitchen |     | Bedroom | Storage |   and   |
|         |         |         |     |         |         | Toilet  |
|         +---   ---+         |     |     +---+---   ---+         |
|                             |     |                             |
+---------+         +---   ---+     +-----+   +         +---------+
|         |         |         |     |         |         |         |
|         |  Hall   |         |     |         |  Hall   |         |
| Living  |   and   |         |     |         |   and   |         |
|  Room   | Stairs  | Dining  |     | Bedroom | Stairs  | Bedroom |
|         |         |         |     |         |         |         |
|                             |     |         |                   |
|         |         |         |     |         |         |         |
+---------+---   ---+---------+     +---------+---------+---------+

Other designs pending.

My Ideal Car

Posted by cafebabe on Tuesday October 31 2017, @01:54PM (#2720)
2 Comments
Hardware

(This is the 40th of many promised articles which explain an idea in isolation. It is hoped that ideas may be adapted, linked together and implemented.)

Richard Buckminster Fuller was an inspiring crack-pot who often got details wrong but had a grand vision. One aspect was the Dymaxion car which had space for eight people, travelled at the speed of an airplane and had the fuel economy of a motorbike. While he was not present in the prototype, a fatal crash occurred. This restrained development. However, I wonder if something more like his buildings would be suitable for a vehicle. Specifically, the general plan was to keep heavy stuff at the bottom (generators, air conditioning units) and have a geometric structure above it for strength and safety.

So, perhaps it would be possible to make a pyramid car from tubular steel. It would be very much like a section of a crane but on wheels. There would be three versions: small, medium and large. The small version would just be a pyramid on wheels. The engine would be under the rear seats. The medium version would have a dedicated section at the front for an engine. The large version would have a hood and truck. Steering would be left, right or center. Center drive (like a McLaren F1) provides extra legroom for rear passengers.

Indicators and suchlike would use the cell network protocol and there would be no CANBus DRM. And there would be no iPhone dock or suchlike. Instead, the dashboard has 4U of racking on the left and right. 2U or more may be reserved statutory indicators, such as speedometer. However, 4U or more is available for customization. Perhaps you'd like a 1500W amplifier (and an auxillary alternator to power it)? Perhaps you'd like a dedicated war-driving unit and a more moderate jukebox? Unfortunately, there is no space for an 11U beer fridge.

Safety comes first. All seats have five point safety belts. Racking provides additional heat protection from engine fire. And in a collision with another vehicle, the tubular steel ensures that the other vehicle is the crumple zone. It may look ugly, it isn't particularly aerodynamic, but it is difficult to steal, difficult to roll and harder to injure or kill yourself.

My Ideal Keyboard

Posted by cafebabe on Tuesday October 31 2017, @01:48PM (#2719)
0 Comments
Hardware

(This is the 39th of many promised articles which explain an idea in isolation. It is hoped that ideas may be adapted, linked together and implemented.)

I doubt my ideal keyboard would ever be produced in significant quantities. However, with slowly advancing skill with micro-controllers and circuit design, I could make one or two for myself.

Cost is not the primary consideration. Therefore, it is possible to make a keyboard extra keys, full travel keys and possibly multiple interfaces. For example, USB, PS/2 serial and line serial. The keyboard would be a straight run keyboard to simplify layout. Staggered keys are a remnant of typewriter hammers. As is QWERTY layout. Given a free choice, I'd have dedicated upper case keys and lower case keys in alphabetical order. This would be of benefit to people who don't primarily use Roman script. It would also help people with dyslexia. Some people type in capitals because the text on the screen matches the letters on the keys. However, if the keys are labeled in lower case, the opposite problem occurs: Some people find it problematic to ever use upper case. Having dedicated upper case keys and lower case keys resolves this problem. For legacy reasons and convenience, shift keys and shift lock remains. In this scenario, cases are flipped.

The first row is 16 hot keys and macro keys. These provide functions such as volume control and application launching. The second row of keys is 16 function keys. These are specific to applications, although F1 typically raises documentation. The third row of keys has the escape key and 15 symbols. The fourth row of keys is digits and punctuation. The fifth and sixth row is upper case letters and punctuation. The seventh and eighth row is lower case letters, punctuation and the delete key. If this sounds like seven bit ASCII then that's entirely the idea. As described so far, keyboard decode is trivial unless legacy, raw codes are required.

We have six meta keys: [shift], [control], [alternate], [Greek], [Cyrillic] and [top]. These are at the bottom of the keyboard and mirrored on both sides with the exception that right [alternate] typically allows code-points to be dialled directly. One column of keys on the left provides [shift lock], [Greek lock], [Cyrillic lock], [top lock] and [tab]. What happens if [Greek] and [Cyrillic] are both used? Probably nothing but we have sufficient options for Amharic chording, Kanji and phonetic symbols. The keyboard controller may require a large ROM unless fnctionality is offloaded to a more capable host.

On a QWERTY keyboard, [undo], [cut], [copy] and [paste] are assigned to [control] + Z, [control] + X, [control] + C and [control] + V. If these keys are re-arranged then this cluster is broken. So, between the two clusters of meta keys, we have dedicated keys for [undo], [redo], [cut], [copy], [paste], [pop] and possibly other functions. [paste] and [pop] perform the same function in legacy applications. However, in applications where the clipboard is a stack rather than a singleton, [paste] applies the top of stack without side-effect and [pop] applies the top of stack before discarding it. This potentially allows an unlimited number of items to be cut or copied and then pasted in reverse order.

Remaining keys fill an additional two columns on the right and are described from the bottom. There is carriage return and backspace. Arrow keys and paging keys are not in a triangle, diamond or suchlike. They are in a 2×2 blocks:-

[page up] [page right]
[page left] [page down]
[up] [right]
[left] [down]

Also have [home] and [end]. The remaining space in the top left and right is filled with the crufty keys such as [print screen] and [scroll lock]. So, we have a 19 column, 12 row keyboard which has a passing resemblance to a Chinese typewriter. It is more suited to writing APL than gaming but it would be an absolute joy for me.

Micro-Controllers, NTSC, PAL, SCART, VGA And HDMI

Posted by cafebabe on Tuesday October 31 2017, @01:46PM (#2718)
0 Comments
Hardware

(This is the 38th of many promised articles which explain an idea in isolation. It is hoped that ideas may be adapted, linked together and implemented.)

It is possible for a micro-controller to drive a VGA display. I was aware that there is a competitive graphics demo category for such systems. However, I hadn't considered a system in detail.

Simple eight bit computers, such as early Sinclair Spectrum models or a Galaksija use a memory-mapped 4021 logic chip shift register or suchlike for screen output. A 4MHz Z80 or suchlike spends about 80% of its processing power loading data into the shift register. This is horrendously inefficient but it significantly reduced the cost of early home computers. To maximize functionality in Spectrum designs, all Z80 alternate registers were reserved for rastering. Whereas, in Galaksija designs, the unrolled loop in ROM used timing-compatible Z80 opcodes which also provided QWERTY keyboard decode.

With an 84MHz Atmel SAM ARM processor in an Arduino Due, every pixel can be set directly from software without shift registers. For maximum resolution, especially at VGA resolution rather than NTSC or PAL, an unrolled loop remains beneficial. However, rather than being hand-rolled assembly, possibly with ancillary functions, it merely requires a C compiler and a tweaked Makefile to ensure display.o or suchlike contains a long, unrolled loop. With an 84MHz processor and 31kHz HSync, there are approximately 2700 processor cycles per line. Allowing for border and HSync, 640×480 display can be implemented with three instructions per pixel.

Furthermore, with a 32 bit micro-controller, it is possible to set 32 I/O lines simultaneously. These could represent HSync, VSync and 10 bits per channel for RGB color. Or it is possible to have two screen with five bits per channel per screen. Or five screens with two bits per channel per screen. Or 10 screens with one bit per channel per screen. Or 30 screens with one bit per pixel output. Unfortunately, driving VGA quickly exhausts RAM. An Atmel SAM has a minimum of three 32KB banks RAM. However, 640×480 is 307200 pixels. Per pixel-plane per screen, this is 38400 bytes RAM (37.5KB). So, two bits per pixel is the baseline functionality unless some form of compression or indirection is used. The most obvious technique is tiling such as a character mode where some or all of the available characters are user defined. For example, seven bit ASCII from 32 to 127 could be fixed and the remaining 160 code-points could be programmable. With a 16 bit character field, it may be possible to have eight bit Latin1 symbols plus 768 programmable code-points. Or maybe more.

It is particularly annoying for such arrangements to become practical after NTSC, PAL, SCART and VGA are considered deprecated. However, it you want to implement trustworthy computing, do not discard any of this equipment. After my recent experience of HDMI replacing SCART, I certainly won't be discarding anything with a SCART or VGA connector.

I have a friend who closely follows one soap opera, The Apprentice, business pitch shows and political news. He has anything in background when he writes Java Swing applications. He has a CRT television with a SCART connector which receives from a terrestrial digital decoder. The latter stopped working without warning and no obvious cause of failure. He hurridly replaced one digital decoder with another. However, the old decoder has two SCART connectors and the new decoder has one SCART connector and one HDMI connector. He only uses one SCART connector but he wasn't happy to lose the potential redundancy of a second SCART socket.

Many devices have multiple SCART sockets and this allows N devices to be daisy-chained with N-1 cables. Any device can take a lead and devices up and down the chain will follow. I presume that a device with one SCART socket and one HDMI socket implements similar functionality while also bridging between analog and digital. Unfortunately, I'm hugely unimpressed with HDMI functionality. With the exception of VCR recording, most SCART devices worked with NTSC and PAL. Such interoperability doesn't apply with the new-fangled digital equivalent.

I thought that he gained the potential to use his new decoder with his LCD computer display. Unfortnately, this completely fails because the minimum resolution of the digital decoder is 1920×1080 pixels and the maximum resolution of the LCD screen is 1280×1024 pixels. They have completely incompatible horizontal and vertical resolution! I know that the vertical resolution of SCART is poor but this type of incompatibility rarely occurred.

I'm most unimpressed that HDMI 4.0 provides full, unfiltered InterNet Protocol tunneling between devices. A shockingly typical configuration would be a subset of NewsCorp digital satellite decoder connected to a Samsung voice and/or gesture recognition television connected to a Windows 10 keylogger and/or game console with camera and NSA key connected to an ADSL router with a hidden route. What could possibly go wrong?

Whereas, you've got eight processor registers and three instruction cycles on a Harvard bus to assemble an arbitrary bit pattern for VGA display. And there's no data-path for any funny business.

Status Report For Oct 2017

Posted by cafebabe on Tuesday October 31 2017, @01:18PM (#2717)
0 Comments
/dev/random

I expected to be off-line for two or three weeks. Unfortunately, with medical problems, legal problems, accommodation problems and financial problems, at least one month of my time has been consumed with matters unrelated to work. However, for five days per week, I'm in an environment with no television, no radio, no phone and no InterNet connection. Even with a flaky laptop which has led me to draft all text on paper, it is common for me to write more than 3000 words per day. For example, the specification for the cell networking protocol is more than 19000 words. I also have seven draft articles pending with two publications. Around this, I have:-

From this, I have made scattered progress. Specifically:-

  • It is possible to make a 6502 cell network switch with 1KB RAM but this only works if the cell size is very small and/or it has four ports or less. 2KB RAM allows 24 byte cells and eight ports. Either configuration may require 32KB ROM or more.
  • I found an easy method to optimize bit matrix transpose operations simultaneously on AVR, ARM and Thumb. However, it compiles very slowly.
  • I've applied the technique of defensive programming to electronics. In particular, how to make all circuitry resiliant to unexpected mains electricity without incurring significant component cost or power loss. This is helped by programming and electronics having idioms for common tasks.
  • I found a reference to Dimension 404, which appears to be the SyFy Channel's counterpart to Black Mirror on NetFlix and Electric Dreams on Channel4/Amazon.
  • I found that it is possible to make a Communicator Badge which transmits Ambisonic A-Format audio.
  • I found that it is possible to make a Communicator Badge which works in a conference bridge and places each participant in a different position on a sound-stage.
  • Atmel SAM interrupts are all bottom priority by default and therefore all interrupts are processed sequentially unless specifically configured.
  • Atmel SAM privileges are present by default unless running inside an interrupt or specifically relinquished. (Obvious with hindsight but worthwhile to check.)
  • Don't buy the cheapest Arduino Nano clones because they don't ship with the Arduino firmware installed. Installation requires cursory understanding of SPI, a working Arduino and use of the hateful Arduino GUI. Come back PIC. All is forgiven.
  • I got 4094 logic chip output shift registers working on the first attempt.
  • I have completely failed to get 4021 logic chip input shift registers working. I have also completely failed to get MCP4921 DACs working. I presume the problem is Voltage level incompatibility between 3.3V circuitry and 5V circuitry.
  • An LM317 Voltage Regulator consists of a Zener diode, an operational amplifier and power transistors. An LM317 is slightly less integrated than the trusty 7805 Voltage Regulator but provides significantly more flexibility. An LM317 is typically used in an output feedback arrangement to obtain a Voltage which is a multiple of the 1.25V Zener. For example, a potential divider with 10kΩ and 27kΩ to ground provides approximately 5V. (1+3ish units of the 1.25V.) However, an LM317 also works perfectly fine with no feedback. A potential divider from the input supply provides any ratio plus 1.25 Volts. Although each device handles a maximum of 28 Volts or suchlike, a sufficiently long cascade of regulators allows any input from car battery to European mains to regulated down to 5 Volts or similar.
  • Mains electricity can be rectified with a MOSFET rectifier bridge. If you're crazy enough to connect MOSFET control gates directly to mains then rectification can be acheived with two NPN MOSFETs, two PNP MOSFETs and nothing else. If you want to reduce the gate Voltage to something sane, use the potential divider idiom of resistor, Zener, Zener in reverse, resistor. This can provide something around 5 Volt relative to ground.
  • I sorta understand the difference between live, neutral and ground. That's sufficient for me to stay away from it until I understand it better.
  • A MOSFET with 2 Ohm resistance is problematic when V = I × R, P = I × V and P = I2 × R where R = 2 Ohm and I = 6.6 Ampère. That's a lot of friction.

Random findings:-

Soylent Upgrade Greasemonkey/Tampermonkey extension v14

Posted by takyon on Saturday October 28 2017, @04:53PM (#2712)
7 Comments
Code

NOW WITH MORE BLOAT!

SKIP TO THE COMMENTS

// ==UserScript==
// @name Soylent Upgrade
// @version 14.0
// @grant none
// @match http://soylentnews.org/*article.pl*
// @match http://*.soylentnews.org/*article.pl*
// @match https://soylentnews.org/*article.pl*
// @match https://*.soylentnews.org/*article.pl*

// @match http://soylentnews.org/*submit.pl*
// @match http://*.soylentnews.org/*submit.pl*
// @match https://soylentnews.org/*submit.pl*
// @match https://*.soylentnews.org/*submit.pl*

// @match http://soylentnews.org/*admin.pl*
// @match http://*.soylentnews.org/*admin.pl*
// @match https://soylentnews.org/*admin.pl*
// @match https://*.soylentnews.org/*admin.pl*

// @match http://soylentnews.org/*comments.pl*
// @match http://*.soylentnews.org/*comments.pl*
// @match https://soylentnews.org/*comments.pl*
// @match https://*.soylentnews.org/*comments.pl*

// @include /^https?://(.*\.)?soylentnews\.org/.*?journal\.pl.*?/
// @match http://soylentnews.org/*journal.pl*
// @match http://*.soylentnews.org/*journal.pl*
// @match https://soylentnews.org/*journal.pl*
// @match https://*.soylentnews.org/*journal.pl*

// @include /^https?://(.*\.)?soylentnews\.org/.*?pollBooth\.pl\?qid=.*/
// ==/UserScript==

// Begin User Options:

var simplifyChars = true; // Change to false if you don't want stylized quotation marks, ellipses, etc. to be replaced
var stripEmail = false; // Remove auto-filled email from submission
var doiChecker = true; // Add Crossref search to DOIs in the summary
var disableCycler = false; // Change to true to disable the button that cycles through *New* comments

// End User Options

/* ! http://mths.be/fromcodepoint v0.1.0 by @mathias */
if (!String.fromCodePoint) { (function() { var defineProperty = (function() { try { var object = {}; var $defineProperty = Object.defineProperty; var result = $defineProperty(object, object, object) && $defineProperty; } catch(error) {} return result; }()); var stringFromCharCode = String.fromCharCode; var floor = Math.floor; var fromCodePoint = function() { var MAX_SIZE = 0x4000; var codeUnits = []; var highSurrogate; var lowSurrogate; var index = -1; var length = arguments.length; if (!length) { return ''; } var result = ''; while (++index < length) { var codePoint = Number(arguments[index]); if ( !isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || floor(codePoint) != codePoint ) { throw RangeError('Invalid code point: ' + codePoint); } if (codePoint <= 0xFFFF) { codeUnits.push(codePoint); } else { codePoint -= 0x10000; highSurrogate = (codePoint >> 10) + 0xD800; lowSurrogate = (codePoint % 0x400) + 0xDC00; codeUnits.push(highSurrogate, lowSurrogate); } if (index + 1 == length || codeUnits.length > MAX_SIZE) { result += stringFromCharCode.apply(null, codeUnits); codeUnits.length = 0; } } return result; }; if (defineProperty) { defineProperty(String, 'fromCodePoint', { 'value': fromCodePoint, 'configurable': true, 'writable': true }); } else { String.fromCodePoint = fromCodePoint; } }()); }

// Add "Quote This" buttons to all initially visible comments
var spans = document.getElementsByTagName("span");
for (var x=0; x<spans.length; x++)
{
    if (spans[x].id.indexOf("reply_link_")==0)
    {
        var button = document.createElement("span");
        button.setAttribute("class","nbutton");
        var p = document.createElement("p");
        var b = document.createElement("b");
        var a = document.createElement("a");
        // Set the href of the "Quote This" button to the href of the "Reply to This" button, with the escaped contents of the post added to URL and any [domain.names] following links in the post cut out:
        a.setAttribute("href",spans[x].getElementsByTagName("a")[0].href.replace("#post_comment","&postercomment="+escape("<blockquote>"+document.getElementById("comment_body_"+spans[x].id.replace("reply_link_","")).innerHTML.replace(/<\/a>\s\[.*?\..*?\]/g,"<\/a>")+"<\/blockquote>\n\n")+"#post_comment"));
        // To Do: Shorten URLs longer than 2000 characters
        a.appendChild(document.createTextNode("Quote This"));
        b.appendChild(a);
        p.appendChild(b);
        button.appendChild(p);
        spans[x].parentNode.insertBefore(button, spans[x].nextSibling);
        spans[x].parentNode.insertBefore(document.createTextNode(" "), spans[x].nextSibling); // Divider
    }
}

// DOI checker in the summary
if (doiChecker && window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/article\.pl/)!=-1)
{
    var summary = document.getElementById("articles").getElementsByClassName("intro")[0];
    summary.innerHTML = summary.innerHTML.replace(/(\(|\[)DOI: (10[^\s\n<]*)(\)|\])/gi,"$1DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
    summary.innerHTML = summary.innerHTML.replace(/(\(|\[)open, DOI: (10[^\s\n<]*)(\)|\])/gi,"$1open, DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
    if (document.getElementById("articles").getElementsByClassName("full").length > 0)
    {
        var summary2 = document.getElementById("articles").getElementsByClassName("full")[0];
        summary2.innerHTML = summary2.innerHTML.replace(/(\(|\[)DOI: (10[^\s\n<]*)(\)|\])/gi,"$1DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
        summary2.innerHTML = summary2.innerHTML.replace(/(\(|\[)open, DOI: (10[^\s\n<]*)(\)|\])/gi,"$1open, DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
    }
}

// Empty email input area, but only on submission page
if (stripEmail && window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/submit\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "email")
        {
            boxes[x].value = "";
        }
    }
}

// Add title case button next to title/subj field on Story Submissions, Submission Preview, Story Preview, and New Journal
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/(submit\.pl|admin\.pl|journal\.pl|journal\.pl\?op=edit)/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "title" || boxes[x].name == "subj" || boxes[x].name == "description")
        {
            boxes[x].id = "storyTitle";
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("value","Title Case");
            button.setAttribute("title","Convert title to title case.");
            button.setAttribute("onclick","document.getElementById('storyTitle').value=document.getElementById('storyTitle').value.replace(/^\\s/gi,'').replace(/\\b([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/\\b(at|of|is|and|to|in|by|as|its|be|the|on|a|an|but|or|for)\\b/gi,function(m, p1){return p1.toLowerCase();}).replace(/^([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/:\\s([a-z])/gi,function(m, p1){return ': '+p1.toUpperCase();}).replace(/([a-z])['\u2019]([a-z])/gi,function(m, p1, p2){return p1+'\\''+p2.toLowerCase();}).replace(/\\bx(86|64)\\b/gi,'x$1').replace(/\\bIphone/gi,'iPhone').replace(/\\s$/gi,'');");
            boxes[x].parentNode.insertBefore(button, boxes[x].nextSibling);
            if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1 || boxes[x].name == "subj")
            {
                boxes[x].parentNode.insertBefore(document.createElement("br"), boxes[x].nextSibling);
            }
            else
            {
                boxes[x].parentNode.insertBefore(document.createTextNode(" "), boxes[x].nextSibling);
            }
        }
    }
}

// Add warning for creating a story in the past
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "op" && (boxes[x].value == "save"))
        {
            // New onclick extracts the post date, compares to the current date, and only submits if the post date is in the future or the user overrides the warning:
            boxes[x].setAttribute("onclick","var d = new Date(document.getElementById('slashstoryform').elements['time'].value.replace(/\\s/,'T')); var a = true; if (d < Date.now()){a = confirm('Are you sure you want to post a story '+(Math.round((Date.now()-d)/60000))+' minutes in the past?');} if (a) {st_submit(this);}");
        }
    }
}

// Expand all initially hidden spoiler blocks when editing a story
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].className == "spoiler")
        {
            boxes[x].checked = true;
        }
    }
}

// Add draft capabilties to story submission form
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/submit\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("textarea");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "story")
        {
            var p = document.createElement("p");

            // Save Draft button
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("value","Save Draft");
            button.setAttribute("onclick","saveSoydraft();");
            p.appendChild(button);

            p.appendChild(document.createTextNode(" "));

            // Discard Draft button
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("id","discardDraft");
            button.setAttribute("value","Discard");
            // Disable the Discard Draft button onload if no draft is available
            if(!localStorage.getItem("soydraft"))
            {
                button.setAttribute("disabled","disabled");
            }
            else
            {
                button.setAttribute("onclick","discardSoydraft();");
            }
            p.appendChild(button);

            p.appendChild(document.createTextNode(" "));

            // Autosave checkbox
            var span = document.createElement("span");
            span.setAttribute("id","autosaveBar");
            // Hide autosave checkbox onload if no draft is available
            if (document.getElementById("storyTitle").value == "" && boxes[x].value == "")
            {
                if(localStorage.getItem("soydraft"))
                {
                    span.setAttribute("style","visibility:visible;");
                }
                else
                {
                    span.setAttribute("style","visibility:hidden;");
                }
            }
            span.appendChild(document.createTextNode("Autosave?"));
            var checkbox = document.createElement("input");
            checkbox.setAttribute("type","checkbox");
            checkbox.setAttribute("id","autosave");
            checkbox.setAttribute("value","");
            checkbox.setAttribute("onclick","if (this.checked==false){autosaveOff();} else {autosaveOn();}");
            checkbox.setAttribute("style","vertical-align:middle;");
            span.appendChild(checkbox);
            span.appendChild(document.createTextNode(" "));
            p.appendChild(span);

            // "Saved." text will appear and fade out whenever a draft is saved
            var span2 = document.createElement("span");
            span2.setAttribute("id","autosaveState");
            span2.setAttribute("style","opacity:0;");
            span2.appendChild(document.createTextNode("Saved."));
            p.appendChild(span2);

            boxes[x].parentNode.insertBefore(p, boxes[x]);

            // Load draft if it exists, but only if workspace is clear
            if (document.getElementById("storyTitle").value == "" && boxes[x].value == "")
            {
                if(localStorage.getItem("soydraft"))
                {
                    document.getElementById("storyTitle").value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[0]);
                    for (var y=0; y<document.getElementsByClassName("fullbox").length; y++)
                    {
                        if (document.getElementsByClassName("fullbox")[y].name == "dept")
                        {
                            document.getElementsByClassName("fullbox")[y].value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[1]);
                            break;
                        }
                    }
                    document.getElementById("primaryskid").value = JSON.parse(localStorage.getItem("soydraft"))[2];
                    document.getElementById("tid").value = JSON.parse(localStorage.getItem("soydraft"))[3];
                    boxes[x].value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[4]);
                }
            }
        }
    }
}

var boxes = document.getElementsByTagName("textarea");
for (var x=0; x<boxes.length; x++)
{
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var temp = boxes[x].value; // Retrieve textarea contents
        temp = temp.replace(/<\/p><p>/g,"<\/p>\n\n<p>"); // Add newlines between paragraphs
        temp = temp.replace(/<br>\s?<br>/g,"<\/p>\n\n<p>"); // Convert double break tags to paragraph tags
        temp = temp.replace(/<\/blockquote><p>/g,"<\/blockquote>\n\n<p>"); // Add newlines after blockquotes
        temp = temp.replace(/<\/p><blockquote>/g,"<\/p>\n\n<blockquote>"); // Add newlines before blockquotes
        temp = temp.replace(/<blockquote><div><p>/g,"<blockquote><div>\n\n<p>"); // Add newlines within start of blockquotes
        temp = temp.replace(/<\/p><\/div><\/blockquote>/g,"<\/p>\n\n<\/div><\/blockquote>"); // Add newlines within end of blockquotes
        temp = temp.replace(/<\/blockquote><blockquote>/g,"<\/blockquote>\n\n<blockquote>"); // Add newlines between two blockquotes
        temp = temp.replace(/<p class="byline">\s/i,"<p class=\"byline\">"); // Remove extra space from byline
        temp = temp.replace(/<p>\s/g,"<p>"); // Remove extra space from start of paragraph
        temp = temp.replace(/\s<\/p>/g,"<\/p>"); // Remove extra space from end of paragraph
        temp = temp.replace(/<\/li><li>/g,"<\/li>\n<li>"); // Add newlines between list items
        temp = temp.replace(/(<\/li>)(<\/[u|o]l>)/g,'$1\n$2'); // Add newline after last list item
        temp = temp.replace(/(<\/p>)(<[u|o]l>)/g,'$1\n$2'); // Add newlines before lists
        temp = temp.replace(/<p>\[...\]/g,"<p>[...] "); // Add space within beginning of foreshortened paragraph
        while (temp.indexOf("  ")!=-1)
        {
            temp = temp.replace(/  /g," "); // Replace double spaces with single spaces
        }
        if (simplifyChars)
        {
            temp = temp.replace(/\u2018/g,"'"); // 'LEFT SINGLE QUOTATION MARK' (U+2018) to (U+0027)
            temp = temp.replace(/\u2019/g,"'"); // 'RIGHT SINGLE QUOTATION MARK' (U+2019) to (U+0027)
            temp = temp.replace(/\u201C/g,"\""); // 'LEFT DOUBLE QUOTATION MARK' (U+201C) to (U+0022)
            temp = temp.replace(/\u201D/g,"\""); // 'RIGHT DOUBLE QUOTATION MARK' (U+201D) to (U+0022)
            temp = temp.replace(/\u2026/g,"..."); // 'HORIZONTAL ELLIPSIS' (U+2026) to (U+002E) x3
        }
        boxes[x].value = temp;
        boxes[x].rows = 32; // Expand textarea height to 32 rows
    }
    var toolbar = document.createElement("div");

    // Blockquote button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Blockquote");
    tempbutton.setAttribute("title","Wrap \u003Cblockquote\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addBlockquote(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Paragraph and Line break buttons
    var tempspan = document.createElement("span");
    tempspan.setAttribute("id","htmlFormatButtons");
    if (document.getElementById("posttype") && document.getElementById("posttype").selectedIndex == 0)
    {
        tempspan.setAttribute("style","display:none;"); // Hide if initial post type option is "Plain Old Text"
    }
    if (document.getElementById("posttype"))
    {
        document.getElementById("posttype").addEventListener("change", function() {if (document.getElementById('posttype').selectedIndex == 0) {document.getElementById('htmlFormatButtons').style.display = 'none'} else {document.getElementById('htmlFormatButtons').style.display = 'inline'}}); // Change visibility of these buttons based on value of post type
    }
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","P");
    tempbutton.setAttribute("title","Wrap \u003Cp\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addPara(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","BR");
    tempbutton.setAttribute("title","Insert a line break.");
    tempbutton.setAttribute("onclick","addBreak(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    toolbar.appendChild(tempspan);

    // HR button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","HR");
        tempbutton.setAttribute("title","Insert a horizontal rule.");
        tempbutton.setAttribute("style","text-decoration:underline overline;");
        tempbutton.setAttribute("onclick","addHRule(document.getElementsByTagName('textarea')["+x+"]);");
        tempspan.appendChild(tempbutton);
        toolbar.appendChild(tempspan);
    }

    // URL button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","URL");
    tempbutton.setAttribute("title","Create a hyperlink around the selected text.");
    tempbutton.setAttribute("style","text-decoration:underline;");
    tempbutton.setAttribute("onclick","addHyperlink(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);
    toolbar.appendChild(document.createTextNode(" "));

    // Bold button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","B");
    tempbutton.setAttribute("title","Bold");
    tempbutton.setAttribute("style","font-weight:bold;");
    tempbutton.setAttribute("onclick","addBold(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Italic button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","I");
    tempbutton.setAttribute("title","Italic");
    tempbutton.setAttribute("style","font-style:italic;");
    tempbutton.setAttribute("onclick","addItalic(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Strike button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","S");
    tempbutton.setAttribute("title","Strikethrough");
    tempbutton.setAttribute("style","text-decoration:line-through;");
    tempbutton.setAttribute("onclick","addStrike(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Code button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Code");
    tempbutton.setAttribute("title","Wrap \u003Cecode\u003E tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addEcode(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Teletype button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","TT");
    tempbutton.setAttribute("title","Wrap \u003Ctt\u003E (teletype, i.e. monospace) tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addTT(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Spoiler button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","\u25A0\u25A0\u25A0");
    tempbutton.setAttribute("title","Wrap \u003Cspoiler\u003E tags around the selected text.");
    //tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSpoiler(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Small button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","\u0073\u1D0D\u1D00\u029F\u029F");
        tempbutton.setAttribute("title","Wrap \u003Csmall\u003E tags around the selected text.");
        // tempbutton.setAttribute("style","font-size:75%;");
        tempbutton.setAttribute("onclick","addSmall(document.getElementsByTagName('textarea')["+x+"]);");
        toolbar.appendChild(tempbutton);
    }

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Superscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u00B2");
    tempbutton.setAttribute("title","Superscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSuper(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Subscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u2082");
    tempbutton.setAttribute("title","Subscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSubsc(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Ordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","1. List");
    tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
    tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"],'1');");
    toolbar.appendChild(tempbutton);

    // Ordered list button - Alpha
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","A. List");
    tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
    tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"],'A');");
    toolbar.appendChild(tempbutton);

    // Ordered list button - Roman
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","I. List");
    tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
    tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"],'I');");
    toolbar.appendChild(tempbutton);

    // Unordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","\u2022 List");
    tempbutton.setAttribute("title","Insert an unordered list or convert newline-separated text into an unordered list.");
    tempbutton.setAttribute("onclick","addUnordlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider
    toolbar.appendChild(document.createElement("br")); // Divider

    // Create 7 macro buttons
    for (var i=1; i<=7; i++)
    {
        // Create macros if they don't exist
        if(!localStorage.getItem("soymacro"+i))
        {
            localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"string","Sample Text"]));
            //localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"regexp","/a/gi","b"]));
        }
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("id","soymacros"+x+"button"+i);
        tempbutton.setAttribute("value",JSON.parse(localStorage.getItem("soymacro"+i))[0]);
        if (JSON.parse(localStorage.getItem("soymacro"+i))[1]=="string")
        {
            if (JSON.parse(localStorage.getItem("soymacro"+i))[2].length < 40)
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2]);
            }
            else
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2].substring(0,40)+"...");
            }
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        else
        {
            tempbutton.setAttribute("title","Replace text matched by the regular expression: " + JSON.parse(localStorage.getItem("soymacro"+i))[2] + " with: " + JSON.parse(localStorage.getItem("soymacro"+i))[3]);
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        toolbar.appendChild(tempbutton);
    }
    // Create macros edit button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Edit");
    tempbutton.setAttribute("title","Configure user macros or discard changes.");
    tempbutton.setAttribute("onclick","if (document.getElementById('macrobar"+x+"').style.display == 'none') {document.getElementById('macrobar"+x+"').style.display = 'block'; macrobarInit("+x+");} else {document.getElementById('macrobar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75);}}");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider

    // Despace button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Despace");
    tempbutton.setAttribute("title","Delete newlines within the selection.");
    tempbutton.setAttribute("onclick","despace(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Symbol button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value",":-)");
    tempbutton.setAttribute("title","Insert a symbol.");
    tempbutton.setAttribute("onclick","if (document.getElementById('smilebar"+x+"').style.display == 'none') {document.getElementById('smilebar"+x+"').style.display = 'block'} else {document.getElementById('smilebar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75); } }");
    toolbar.appendChild(tempbutton);
    boxes[x].parentNode.insertBefore(toolbar, boxes[x].nextSibling);

    // Symbol list
    var smilebar = document.createElement("div");
    smilebar.setAttribute("style","-moz-user-select:none; -webkit-user-select:none; display:none; font-size:16pt; max-height:240px; overflow:auto; padding:0.5em;");
    smilebar.setAttribute("id","smilebar"+x);
    var smiles = ["\u0026amp;","\u0026lt;","\u0026gt;","\u0026nbsp;"];

    var codes = [[161,169],[171,172],[174],[176,177],[180,183],[187,191],[215],[224,255],[402],[629],[632],[916],[920],[931],[934],[937],[945,946],[956],[960],[963],[8211,8213],[8216,8221],[8226],[8230],[8251],[8315],[8331],[8364],[8478],[8482],[8528,8542],[8585],[8592,8652],[8712,8716],[8721],[8730],[8733,8734],[8736],[8743,8749],[8756,8757],[8773],[8776],[8800,8805],[8834,8837],[8984],[9095],[9760],[9762,9765],[9770],[9773,9775],[9784,9794],[9812,9831],[9833,9842],[9850],[9855,9861],[9874,9877],[9882,9885],[9888,9893],[9913],[9940],[9962],[9971],[9981],[9992,10087],[12316],[12336],[21328],[65533],[127744,127756],[127759],[127775,127776],[127797],[127801],[127804,127812],[127817],[127820,127822],[127828,127831],[127838,127839],[127843],[127849],[127855],[127860,127867],[127873,127877],[127884],[127891],[127904,127911],[127918],[127939],[127942],[127977],[128025],[128039],[128074,128078],[128123,128131],[128137,128142],[128148,128150],[128152],[128158],[128161,128165],[128168,128170],[128172],[128175,128177],[128187],[128189,128190],[128193,128194],[128197],[128200,128204],[128206],[128214],[128225,128227],[128231,128233],[128241],[128244],[128246],[128250,128252],[128259],[128266,128270],[128273,128276],[128278,128280],[128286],[128293,128299],[128302,128303],[128509,128565],[128640],[128659],[128681],[128684,128685],[128701]];

    for (var i=0; i<codes.length; i++) { if (codes[i].length > 1) { for (var j=codes[i][0]; j<=codes[i][1]; j++) { smiles[smiles.length] = String.fromCodePoint(j); } } else { smiles[smiles.length] = String.fromCodePoint(codes[i][0]); } } // Populate smiles array with code ranges converted to individual characters

    smiles = smiles.concat(["xD",":-)",":^)","(^_^;)","(\u00A0\u0361\u00B0\u00A0\u035C\u0296\u00A0\u0361\u00B0)","(\u00A0\u0361\u007E\u00A0\u035C\u0296\u00A0\u0361\u00B0)\uFEFF","\u00AF\u005C\u005F(\u30C4)\u005F\u002F\u00AF","(\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u00A0\u253B\u2501\u253B","(\u30CE\u0CA0\u76CA\u0CA0)\u30CE\u5F61\u253B\u2501\u253B","(\u0060\uFF65\u03C9\uFF65\u00B4)","\u0CA0_\u0CA0","\u0295\u2022\u1D25\u2022\u0294","(\u3065\uFFE3\u00A0\u00B3\uFFE3)\u3065","\u0669(\u204E\u275B\u1D17\u275B\u204E)\u06F6","\u30FD\u0F3C\u0E88\u0644\u035C\u0E88\u0F3D\uFF89","(\uB208\u2038\uB208)","\u006F(\u3003\uFF3E\u25BD\uFF3E\u3003)\u006F","\u0028\u0028\u30FE\u0028\u2267\u76BF\u2266\uFF1B\u0029\u30CE\uFF3F\u0029\u0029","\u30FD\u0028\u002A\u2312\u2207\u2312\u002A\u0029\uFF89","\u0028\u2267\u2207\u2266\u0029\u002F","\u0028\u0E07\u00A0\u0360\u00B0\u00A0\u035F\u0644\u035C\u00A0\u0361\u00B0\u0029\u0E07"]); // Add in arbitrary emoticons
    // Note: \u00A0 is a non-breaking space character.

    for (var i=0; i<smiles.length; i++)
    {
        var smile = document.createElement("span");
        smile.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
        smile.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+smiles[i].replace("\u005C","\u005C\u005C")+"');");
        smile.appendChild(document.createTextNode(smiles[i]));
        smilebar.appendChild(smile);
        if (i<smiles.length) // A space is added after every symbol including the final one
        {
            smilebar.appendChild(document.createTextNode(" "));
        }
    }

    var flags = [];
    flags = flags.concat([[[127462,127467],"Afghanistan"]]); // AF/Afghanistan
    flags = flags.concat([[[127462,127478],"Antarctica"]]); // AQ/Antarctica
    flags = flags.concat([[[127462,127482],"Australia"]]); // AU/Australia
    flags = flags.concat([[[127463,127465],"Bangladesh"]]); // BD/Bangladesh
    flags = flags.concat([[[127463,127479],"Brazil"]]); // BR/Brazil
    flags = flags.concat([[[127464,127462],"Canada"]]); // CA/Canada
    flags = flags.concat([[[127464,127475],"China"]]); // CN/China
    flags = flags.concat([[[127464,127476],"Colombia"]]); // CO/Colombia
    flags = flags.concat([[[127464,127482],"Cuba"]]); // CU/Cuba
    flags = flags.concat([[[127465,127466],"Germany"]]); // DE/Germany
    flags = flags.concat([[[127466,127468],"Egypt"]]); // EG/Egypt
    flags = flags.concat([[[127466,127480],"Spain"]]); // ES/Spain
    flags = flags.concat([[[127988,917605,917619,917603,917620,917631],"Catalonia"]]); // ES-CT/Catalonia
    flags = flags.concat([[[127466,127482],"European Union"]]); // EU/European Union
    flags = flags.concat([[[127467,127479],"France"]]); // FR/France
    flags = flags.concat([[[127468,127463],"United Kingdom"]]); // GB/United Kingdom
    flags = flags.concat([[[127988,917607,917602,917605,917614,917607,917631],"England"]]); // GB-ENG/England
    flags = flags.concat([[[127988,917607,917602,917619,917603,917620,917631],"Scotland"]]); // GB-SCT/Scotland
    flags = flags.concat([[[127988,917607,917602,917623,917612,917619,917631],"Wales"]]); // GB-WLS/Wales
    flags = flags.concat([[[127468,127479],"Greece"]]); // GR/Greece
    flags = flags.concat([[[127469,127472],"Hong Kong"]]); // HK/Hong Kong
    flags = flags.concat([[[127470,127465],"Indonesia"]]); // ID/Indonesia
    flags = flags.concat([[[127470,127466],"Ireland"]]); // IE/Ireland
    flags = flags.concat([[[127470,127473],"Israel"]]); // IL/Israel
    flags = flags.concat([[[127470,127475],"India"]]); // IN/India
    flags = flags.concat([[[127470,127478],"Iraq"]]); // IQ/Iraq
    flags = flags.concat([[[127470,127479],"Iran"]]); // IR/Iran
    flags = flags.concat([[[127470,127481],"Italy"]]); // IT/Italy
    flags = flags.concat([[[127471,127474],"Jamaica"]]); // JM/Jamaica
    flags = flags.concat([[[127471,127477],"Japan"]]); // JP/Japan
    flags = flags.concat([[[127472,127466],"Kenya"]]); // KE/Kenya
    flags = flags.concat([[[127472,127477],"North Korea"]]); // KP/North Korea
    flags = flags.concat([[[127472,127479],"South Korea"]]); // KR/South Korea
    flags = flags.concat([[[127473,127463],"Lebanon"]]); // LB/Lebanon
    flags = flags.concat([[[127473,127486],"Libya"]]); // LY/Libya
    flags = flags.concat([[[127474,127475],"Mongolia"]]); // MN/Mongolia
    flags = flags.concat([[[127474,127485],"Mexico"]]); // MX/Mexico
    flags = flags.concat([[[127475,127468],"Nigeria"]]); // NG/Nigeria
    flags = flags.concat([[[127477,127466],"Peru"]]); // PE/Peru
    flags = flags.concat([[[127477,127472],"Pakistan"]]); // PK/Pakistan
    flags = flags.concat([[[127477,127479],"Puerto Rico"]]); // PR/Puerto Rico
    flags = flags.concat([[[127477,127480],"Palestinian Territory"]]); // PS/Palestinian Territory
    flags = flags.concat([[[127479,127482],"Russia"]]); // RU/Russia
    flags = flags.concat([[[127480,127462],"Saudi Arabia"]]); // SA/Saudi Arabia
    flags = flags.concat([[[127480,127465],"Sudan"]]); // SD/Sudan
    flags = flags.concat([[[127480,127466],"Sweden"]]); // SE/Sweden
    flags = flags.concat([[[127480,127468],"Singapore"]]); // SG/Singapore
    flags = flags.concat([[[127480,127476],"Somalia"]]); // SO/Somalia
    flags = flags.concat([[[127481,127469],"Thailand"]]); // TH/Thailand
    flags = flags.concat([[[127481,127479],"Turkey"]]); // TR/Turkey
    flags = flags.concat([[[127481,127484],"Taiwan"]]); // TW/Taiwan
    flags = flags.concat([[[127482,127468],"Uganda"]]); // UG/Uganda
    flags = flags.concat([[[127482,127480],"United States"]]); // US/United States
    flags = flags.concat([[[127483,127462],"Vatican City"]]); // VA/Vatican City
    flags = flags.concat([[[127483,127466],"Venezuela"]]); // VE/Venezuela
    flags = flags.concat([[[127487,127462],"South Africa"]]); // ZA/South Africa
    flags = flags.concat([[[127487,127484],"Zimbabwe"]]); // ZW/Zimbabwe
    flags = flags.concat([[[127987],"White Flag"]]); // Waving White Flag
    flags = flags.concat([[[127988],"Black Flag"]]); // Waving Black Flag
    flags = flags.concat([[[127987,65039,8205,127752],"Rainbow Flag"]]); // Waving White Flag + Rainbow
    flags = flags.concat([[[127988,8205,9760,65039],"Pirate Flag"]]); // Waving Black Flag + Skull and Crossbones
    //flags = flags.concat([[[000000,000000],"STRING"]]); // STRING

    for (var i=0; i<flags.length; i++)
    {
        var flag = document.createElement("span");
        flag.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
        var s1 = "", s2 = "";
        for (var j=0; j<flags[i][0].length; j++)
        {
            s1 += String.fromCodePoint(flags[i][0][j]);
            s2 += "&#"+flags[i][0][j]+";";
        }
        flag.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+s2+"');");
        flag.setAttribute("title",flags[i][1]);
        flag.appendChild(document.createTextNode(s1));
        smilebar.appendChild(flag);
        if (i+1<flags.length)
        {
            smilebar.appendChild(document.createTextNode(" "));
        }
    }

    toolbar.parentNode.insertBefore(smilebar, toolbar.nextSibling);

    // Create macro configuration interface
    var macrobar = document.createElement("div");
    macrobar.setAttribute("style","display:none; padding:0.5em;");
    macrobar.setAttribute("id","macrobar"+x);
    var table = document.createElement("table");
    var tr = document.createElement("tr");
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Name"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Type"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("String | Expression"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.setAttribute("title","Only used with expressions. Parenthesized substring matches (e.g. '$1') can be used.");
    th.setAttribute("style","cursor:help;");
    th.appendChild(document.createTextNode("Expression Replace"));
    tr.appendChild(th);
    table.appendChild(tr);
    for (var i=1; i<=7; i++)
    {
        var tr = document.createElement("tr");

        // Macro name
        var td = document.createElement("td");
        var name = document.createElement("input");
        name.setAttribute("type","text");
        name.setAttribute("id","soymacros"+x+"name"+i);
        td.appendChild(name);
        tr.appendChild(td);

        // Macro type
        var td = document.createElement("td");
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"S");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" String "));
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"E");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" Expression "));
        tr.appendChild(td);

        // Field A
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldA"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        // Field B
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldB"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        table.appendChild(tr);
    }
    macrobar.appendChild(table);

    var p = document.createElement("p");
    var save = document.createElement("input");
    save.setAttribute("type","button");
    save.setAttribute("value","Save");
    save.setAttribute("title","Save any edits to the macro configuration.");
    save.setAttribute("onclick","macrobarSave("+x+");");
    p.appendChild(save);
    p.appendChild(document.createTextNode(" "));
    var guide = document.createElement("a");
    guide.setAttribute("href","https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions");
    guide.setAttribute("target","_blank");
    guide.appendChild(document.createTextNode("Regexp Guide"));
    p.appendChild(guide);
    macrobar.appendChild(p);

    toolbar.parentNode.insertBefore(macrobar, toolbar.nextSibling);
}

// Change Stories link to regular admin.pl on breakingnews, meta, politics, and communityreviews nexii
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/(breakingnews|meta|politics|communityreviews)\//)!=-1)
{
    if (document.getElementById("adminmenu"))
    {
        var t = document.getElementById("adminmenu").getElementsByTagName("a");
        for (var i=0; i<t.length; i++)
        {
            if (t[i].innerText == "Stories")
            {
                t[i].setAttribute("href","//soylentnews.org/admin.pl");
            }
        }
    }
}

// Easily cycle through *New* comments
if (!disableCycler && (document.querySelector(".newBadge") || (document.querySelector(".dimmed") && document.querySelector(".comment > div.commentDiv:not(.dimmed)"))))
{
    var temp = document.getElementById("links");
    var temp2 = document.createElement("div");
    temp2.setAttribute("style","position:fixed; bottom:15px; z-index:-100;");
    var temp3 = document.createElement("input");
    temp3.setAttribute("type","button");
    temp3.setAttribute("value","New Comment \u00BB");
    temp3.setAttribute("onclick","cycleNew();");
    temp2.appendChild(temp3);
    temp.appendChild(temp2);
}

var temp = document.createElement("script");

// Add selection handling function
temp.appendChild(document.createTextNode("function getSelection(textarea) { if ('selectionStart' in textarea) { if (textarea.selectionStart != textarea.selectionEnd) { return [textarea.selectionStart,textarea.selectionEnd]; } } } "));

// Add comment formatting buttons
temp.appendChild(document.createTextNode("function addBlockquote(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<blockquote>'+area.value.substring(sel[0],sel[1])+'<\/blockquote>' + area.value.substring(sel[1]); } } function addPara(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<p>'+area.value.substring(sel[0],sel[1])+'<\/p>' + area.value.substring(sel[1]); } } function addBreak(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<br>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHRule(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<hr>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHyperlink(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { url = prompt('URL:', 'https://'); if (url==null) {return false;} area.value = area.value.substring(0,sel[0]) + '<a href=\"'+url+'\">'+area.value.substring(sel[0],sel[1])+'<\/a>' + area.value.substring(sel[1]); } } function addBold(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<b>'+area.value.substring(sel[0],sel[1])+'<\/b>' + area.value.substring(sel[1]); } } function addItalic(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<em>'+area.value.substring(sel[0],sel[1])+'<\/em>' + area.value.substring(sel[1]); } } function addStrike(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<del>'+area.value.substring(sel[0],sel[1])+'<\/del>' + area.value.substring(sel[1]); } } function addEcode(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<ecode>'+area.value.substring(sel[0],sel[1])+'<\/ecode>' + area.value.substring(sel[1]); } } function addTT(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<tt>'+area.value.substring(sel[0],sel[1])+'<\/tt>' + area.value.substring(sel[1]); } } function addSpoiler(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<spoiler>'+area.value.substring(sel[0],sel[1])+'<\/spoiler>' + area.value.substring(sel[1]); } } function addSmall(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<small>'+area.value.substring(sel[0],sel[1])+'<\/small>' + area.value.substring(sel[1]); } } function addSuper(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sup>'+area.value.substring(sel[0],sel[1])+'<\/sup>' + area.value.substring(sel[1]); } } function addSubsc(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sub>'+area.value.substring(sel[0],sel[1])+'<\/sub>' + area.value.substring(sel[1]); } } "));

// Add list creation functions
temp.appendChild(document.createTextNode("function addOrdlist(area,type) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ol type=\\\"' + type + '\\\"><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ol>' + area.value.substring(area.selectionEnd); } else { temp = '<ol type=\\\"' + type + '\\\">'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } if (temp=='<ol type=\\\"' + type + '\\\">') {return;} area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ol>' + area.value.substring(area.selectionStart); } } } function addUnordlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ul><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ul>' + area.value.substring(area.selectionEnd); } else { temp = '<ul>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } if (temp=='<ul>') {return;} area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ul>' + area.value.substring(area.selectionStart); } } }"));

// Add macro functions
temp.appendChild(document.createTextNode("function macroChoose(area,x) { if (JSON.parse(localStorage.getItem('soymacro'+x))[1]=='string') { macroString(area,x); } else { macroRegexp(area,x); } }"));
temp.appendChild(document.createTextNode("function macroString(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { area.value = area.value.substring(0,sel[0]) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(sel[1]); } else if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length,pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length); } }"));
temp.appendChild(document.createTextNode("function macroRegexp(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { var reg = JSON.parse(localStorage.getItem('soymacro'+x))[2]; area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(new RegExp(reg.substring(reg.indexOf('/')+1,reg.lastIndexOf('/')), reg.substring(reg.lastIndexOf('/')+1)),JSON.parse(localStorage.getItem('soymacro'+x))[3]) + area.value.substring(sel[1]); } }"));
temp.appendChild(document.createTextNode("function macrobarInit(x) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+x+'name'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { document.getElementById('soymacros'+x+'type'+y+'S').checked = true; } else { document.getElementById('soymacros'+x+'type'+y+'E').checked = true; } document.getElementById('soymacros'+x+'fieldA'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[2]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]!='string') { document.getElementById('soymacros'+x+'fieldB'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[3]; } else { document.getElementById('soymacros'+x+'fieldB'+y).value = ''; } } }"));
temp.appendChild(document.createTextNode("function macrobarSave(x) { for (var y=1; y<=7; y++) { if (document.getElementById('soymacros'+x+'type'+y+'S').checked == true) { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'string',document.getElementById('soymacros'+x+'fieldA'+y).value])); } else { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'regexp',document.getElementById('soymacros'+x+'fieldA'+y).value,document.getElementById('soymacros'+x+'fieldB'+y).value])); } } document.getElementById('macrobar'+x).style.display = 'none'; var boxes = document.getElementsByTagName('textarea'); for (var z=0; z<boxes.length; z++) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+z+'button'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { if (JSON.parse(localStorage.getItem('soymacro'+y))[2].length < 40) { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2]; } else { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2].substring(0,40)+'...'; } } else { document.getElementById('soymacros'+z+'button'+y).title = 'Replace text matched by the regular expression: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2] + ' with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[3]; } } } }"));

// Add despace function
temp.appendChild(document.createTextNode("function despace(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(/\\r/g,' ').replace(/\\n/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ') + area.value.substring(sel[1]); } }"));

// Add unicode insertion function
temp.appendChild(document.createTextNode("function addSmile(area, smile) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,pos) + smile + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+smile.length,pos+smile.length) } }"));

// Add save submission function
temp.appendChild(document.createTextNode("function saveSoydraft() { try {window.clearTimeout(timer);} catch(e){} var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { if (document.getElementById('storyTitle').value!=''||boxes[x].value!='') { document.getElementById('autosaveBar').style.visibility='visible'; document.getElementById('autosaveState').style.transition='opacity 0s'; document.getElementById('autosaveState').style.opacity='1'; document.getElementById('autosaveState').offsetWidth = document.getElementById('autosaveState').offsetWidth; document.getElementById('autosaveState').style.transition='opacity 1s'; document.getElementById('autosaveState').style.opacity='0'; var y=0; for (y=0; y<document.getElementsByClassName('fullbox').length; y++) { if (document.getElementsByClassName('fullbox')[y].name == 'dept') { break; } } localStorage.setItem('soydraft',JSON.stringify([encodeURI(document.getElementById('storyTitle').value),encodeURI(document.getElementsByClassName('fullbox')[y].value),document.getElementById('primaryskid').value,document.getElementById('tid').value,encodeURI(boxes[x].value)])); document.getElementById('discardDraft').removeAttribute('disabled'); document.getElementById('discardDraft').setAttribute('onclick','discardSoydraft();'); } else { alert('There is no title or story to save.'); } break; } } }"));

// Add discard submission function
temp.appendChild(document.createTextNode("function discardSoydraft() { autosaveOff(); document.getElementById('autosave').checked=false; document.getElementById('autosaveBar').style.visibility='hidden'; localStorage.removeItem('soydraft'); document.getElementById('discardDraft').setAttribute('disabled','disabled'); document.getElementById('discardDraft').removeAttribute('onclick'); }"));

// Add autosave functions
temp.appendChild(document.createTextNode("function autosaveOn() { var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { boxes[x].onkeydown = function() {try {window.clearTimeout(timer);} catch(e){} timer = window.setTimeout(function() { if(document.getElementById(\"autosaveBar\").style.visibility==\"visible\") {saveSoydraft();} }, 3000);}; } } document.getElementById('storyTitle').onkeydown = function() {try {window.clearTimeout(timer);} catch(e){} timer = window.setTimeout(function() { if(document.getElementById(\"autosaveBar\").style.visibility==\"visible\") {saveSoydraft();} }, 3000);}; }"));
temp.appendChild(document.createTextNode("function autosaveOff() { var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { try {window.clearTimeout(timer);} catch(e){} boxes[x].onkeydown = null; } } document.getElementById('storyTitle').onkeydown = null; }"));

// Add new comment cycling function
// Credit: charon
temp.appendChild(document.createTextNode("var newComN = 0; var newComments = document.querySelector('.newBadge') ? document.querySelectorAll('.newBadge') : document.querySelectorAll('.comment > div:not(.dimmed)'); function cycleNew() {if (!newComments[newComN]) {return;} if (newComN != 0 && window.pageYOffset > newComments[newComN].offsetTop + 100) {while (newComments[newComN].offsetTop <= window.pageYOffset){newComN++;}} var p = newComments[newComN++]; var y = p.offsetTop; while (p = p.offsetParent) {y += p.offsetLeft;} window.scrollTo(0,y); if(newComN>=newComments.length-1){newComN=0;}}"));

document.getElementsByTagName('head')[0].appendChild(temp); // Add script to page

74-Year-Old "Ninja" Cat Burglar Caught

Posted by takyon on Wednesday October 25 2017, @01:35PM (#2708)
4 Comments
/dev/random

To catch a ‘ninja’ thief: Osaka police unmask 74-year-old cat burglar

Police in Osaka have finally nabbed a nimble “ninja” thief who dressed in black and scrambled over walls to commit scores of break-ins over an eight-year career — and were astonished to find he was 74.

Police had been stumped by a string of burglaries, their only lead being security camera footage showing an agile thief with a black neck-warmer pulled up to the nose and a parker hood down to the eyebrows.

“He was dressed all in black just like a ninja,” a senior official at the Kawachi Police Station said.

But the master thief made a mistake in May — his neck-warmer slipped and his identity was revealed on camera.

Police recognized their man as Mitsuaki Tanigawa, 74, who had a previous record of thefts.

Pimax 8K VR Headset and Threadripper 1900X

Posted by takyon on Wednesday October 25 2017, @01:32AM (#2705)
0 Comments
Hardware

Watch someone else play with a high end VR headset:

Getting Fully Immersed With Pimax's 8K VR Headset (Hands On)

The lowest core count Threadripper reviewed:

AMD Ryzen Threadripper 1900X CPU Review

STD fun (Star Trek Discovery)

Posted by Gaaark on Tuesday October 24 2017, @09:00PM (#2704)
1 Comment
Topics

Am currently watching Episode 2 of STD. And it may not be canon to TOS, but maybe canon to the reboot movie?

But it is fun, so far.


A cloaked klingon vessel just rammed a Federation ship: COOL strategy.

So far, i am interested. So far, STD is.... fascinating.

Nice Dreams: post here!

Posted by Gaaark on Friday October 20 2017, @10:07PM (#2699)
18 Comments
/dev/random

From the probably-watched-too-much-Cheech-and-Chong-as-a kid dept.

The strangest dream that i can remember that woke me up laughing went like this:

I took a glass and filled it with water
I took a tampon by the string and dipped it in the water, then dipped it in cocaine.
Then i dipped the tampon into the water.

In my dream i said, "I've invented coca-cola!" and started laughing. Woke up laughing and had a great day after that.

I need a few more dreams like that, i tell you what!