<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>An Experiment in Bloggery &#187; Web</title>
	<atom:link href="http://kevin.sb.org/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://kevin.sb.org</link>
	<description>The occasional view into my life</description>
	<lastBuildDate>Fri, 09 Sep 2011 00:19:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WebKit and handling of surrogate pairs in HTML entities</title>
		<link>http://kevin.sb.org/2008/11/10/webkit-and-handling-of-surrogate-pairs-in-html-entities/</link>
		<comments>http://kevin.sb.org/2008/11/10/webkit-and-handling-of-surrogate-pairs-in-html-entities/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 00:20:15 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[entities]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[surrogate pair]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[UTF-16]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://kevin.sb.org/?p=164</guid>
		<description><![CDATA[In this modern day, HTML entities can reference arbitrary unicode codepoints. For example, &#38;#x2603; is the entity for &#x2603;. Not surprisingly, WebKit appears uses UTF-16 internally to represent unicode strings, or at the very least when interpreting HTML entities. One of the big benefits of using UTF-16 is every character is represented by 2 bytes [...]]]></description>
			<content:encoded><![CDATA[<p>In this modern day, HTML entities can reference arbitrary unicode codepoints. For example, <code>&amp;#x2603;</code> is the entity for &#x2603;. Not surprisingly, WebKit appears uses UTF-16 internally to represent unicode strings, or at the very least when interpreting HTML entities. One of the big benefits of using UTF-16 is every character is represented by 2 bytes (the 16 in UTF-16 means 16 bits). Contrast this with UTF-8, where a single character can be represented by anywhere from 1 to 4 bytes, or UTF-32 where every character requires 4 bytes (i.e. twice as much as UTF-16). Clearly UTF-16 seems to be useful, as it&#8217;s not too much larger than UTF-8 for ASCII strings (only double the size), and you can jump to any character with a simple index into the string. However, one of the often-ignored aspects of UTF-16 is the surrogate pair. Unicode contains more than 0xFFFF bytes, and yet a single UTF-16 &#8220;character&#8221; (or unichar) can only reference up to U+FFFF. The solution to this is to take the codepoints in Unicode planes 1-16 (<code>U+10000</code> - <code>U+10FFFF</code>) and represent them as 2 unichars. This is a surrogate pair. You can find more information on this in the <a href="http://en.wikipedia.org/wiki/UTF-16#Encoding_of_characters_outside_the_BMP">wikipedia entry for UTF-16</a>, but to put it simply, a surrogate pair uses a range of codepoints that don&#8217;t represent real characters (<code>U+D800</code> - <code>U+DFFF</code>) and uses them in combination to represent all the characters in the other planes.</p>

<p>The reason this is interesting is because it exposes an interesting quirk as to how WebKit interprets HTML entities. WebKit properly converts entities that represent characters outside of plane 0 into a surrogate pair, such as <code>&amp;#x1D367;</code> (&#x1D367;). This gets converted into <code>0xD834DF67</code>. The quirk is if you give it the surrogate pair codepoints directly, it doesn&#8217;t realize they&#8217;re not real characters individually and passes them through unscathed, so that same character can be written as <code>&amp;#xD834;&amp;#xDF67;</code> (&#xD834;&#xDF67;). Now this doesn&#8217;t seem particularly harmful, except if you only write the first of these entities, WebKit will then get very confused. It will end up throwing away the entire rest of the line of rendered text. Interestingly, it starts displaying text again after a line break, even if it&#8217;s just an implicit line break.</p>

<p>The ideal behavior here is WebKit should just silently ignore any entities which reference a codepoint that&#8217;s part of a surrogate pair. The fact that it doesn&#8217;t really doesn&#8217;t hurt anything, but I thought it was worth documenting.</p>

<p><strong>Update:</strong> A question was raised on twitter about how surrogate pairs affect indexing into a UTF-16 string. I didn&#8217;t know the answer, and strangely, I couldn&#8217;t find information on how to handle it with google either, so I tested empirically. <code>NSString</code> uses UTF-16 internally, so it was a great way to test. And what I found was that each half of a surrogate pair is counted as a separate character. The <code>-length</code> of the <code>NSString</code> is increased by 2 when you add a surrogate pair, and <code>-substringFromIndex:</code> will happily split up the surrogate pair for you. Of course, if you do split a surrogate pair, then attempting to convert the <code>NSString</code> into another encoding, even with the simple <code>-UTF8String</code>, will return NULL as such a conversion is illegal (when you generate a unicode stream it has to be well-formed, and so you cannot generate a stream with half of a surrogate pair - and half of a surrogate pair in UTF-16 will be converted into a single invalid 3-byte UTF-8 sequence).</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2008/11/10/webkit-and-handling-of-surrogate-pairs-in-html-entities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tweet Tweet</title>
		<link>http://kevin.sb.org/2007/01/23/tweet-tweet/</link>
		<comments>http://kevin.sb.org/2007/01/23/tweet-tweet/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 10:11:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Atom]]></category>
		<category><![CDATA[IM]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[Sidekick]]></category>
		<category><![CDATA[status]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Twitterific]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://f3787f9e-061a-4347-9c18-246a5308992f</guid>
		<description><![CDATA[There&#8217;s a new site that&#8217;s been getting really popular lately called Twitter. If you haven&#8217;t heard of it, it&#8217;s basically a status message, like IM, but actually usable. Twitter provides XML/JSON feeds, as well as a way to post updates over the web, over IM (using Jabber), or over SMS. You can also receive &#8220;tweets&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a new site that&#8217;s been getting really popular lately called <a href="http://twitter.com/">Twitter</a>.
If you haven&#8217;t heard of it, it&#8217;s basically a status message, like IM, but actually usable.
<a href="http://twitter.com/">Twitter</a> provides XML/JSON feeds, as well as a way to post updates over the web, over
IM (using Jabber), or over SMS. You can also receive &#8220;tweets&#8221; (Twitter updates) that your
friends posted with any of these mechanisms. There are also various applications (such as
<a href="http://iconfactory.com/software/twitterrific">Twitterific</a>), if you want yet another way to send/receive tweets.</p>

<p>By far the most powerful aspect of Twitterific is the SMS support. I have free SMS with my
<a href="http://www.sidekick.com/">Sidekick</a> data plan, but I&#8217;ve never had a reason to use it before. But now I can receive
tweets on my phone all day long, and send my own no matter where I am. For example, I sent
this <a href="http://twitter.com/eridius/statuses/3723833">tweet</a> while in class.</p>

<p>If you want to keep track of what I&#8217;m doing, just take a gander at <a href="http://twitter.com/eridius">my profile</a>.
And if you sign up for your own account, you can add me as a friend to receive my tweets.
If you add me and I recognize your name, I&#8217;ll probably add you back too.</p>

<div class="update">There&#8217;s a <a href="http://twitter.com/bbcnews">BBC News</a> twitter profile. How cool is that?</div>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2007/01/23/tweet-tweet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Resurrection of Typosphere</title>
		<link>http://kevin.sb.org/2007/01/22/the-resurrection-of-typosphere/</link>
		<comments>http://kevin.sb.org/2007/01/22/the-resurrection-of-typosphere/#comments</comments>
		<pubDate>Mon, 22 Jan 2007 19:34:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[DreamHost]]></category>
		<category><![CDATA[irc]]></category>
		<category><![CDATA[Planet Argon]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[trac]]></category>
		<category><![CDATA[typo]]></category>
		<category><![CDATA[Typosphere]]></category>

		<guid isPermaLink="false">http://54f021aa-61c3-4e07-82f3-51e46c740bca</guid>
		<description><![CDATA[After months of absence, Typosphere has returned from the dead! We migrated off of Planet Argon and onto DreamHost, where we should have more control. We also upgraded to Trac 0.10.3 and turned off anonymous editing (users now have to register to file a ticket). This should (hopefully) prevent the issue that lead to Typosphere [...]]]></description>
			<content:encoded><![CDATA[<p>After months of absence, <a href="http://www.typosphere.org">Typosphere</a> has returned from the dead!</p>

<p>We migrated off of <a href="http://www.planetargon.com">Planet Argon</a> and onto <a href="http://www.dreamhost.com">DreamHost</a>, where we should have more control.
We also upgraded to <a href="http://trac.edgewall.org">Trac</a> 0.10.3 and turned off anonymous editing (users now have to register to file a ticket).
This should (hopefully) prevent the issue that lead to Typosphere dying in the first place.</p>

<div class="highlight">
<p>One important thing to note is that as part of this process, we also moved the subversion repository.
Unfortunately, the old repository was hosted as an svn:// URI using the typosphere.org domain, which meant
there was no way to preserve this URI (since we can&#8217;t run long-lived background daemons on DreamHost). The
new URI uses http and a new subdomain, so if necessary we can move the repository without moving the website.</p>

<p style="text-align: left">The new repository URL is <a href="http://svn.typosphere.org/typo/trunk">http://svn.typosphere.org/typo/trunk</a>.</p>
</div>

<p><span id="more-136"></span></p>

<p>The issue, as near as I can tell, is Typosphere started getting spammed massively. At this time none of the
developers (and that includes me) was really paying attention to Typo, as we were busy with other things. So
for about a month Typosphere Trac got so full of spam that, well, it was more spam in one location than
I&#8217;ve ever seen in the rest of my life. This managed to trip a bug in Trac that caused it to start sucking
CPU and RAM, and so Planet Argon turned off Trac for our account.</p>

<p>Some time later, the other developers and I started trying to resurrect Typosphere. Unfortunately, at about
this time the systems administrator for Planet Argon was preparing to leave the company, so any attempts at
contacting him to resolve the issue went unanswered. I eventually called Planet Argon (which is how I learned
that the systems administrator had, in fact, left that very day) and spoke to the new systems administrator. He
agreed to try and fix Trac for us, but after hearing nothing for a few days, I decided it would be better to seek
hosting elsewhere.</p>

<p>Luckily, I had access to a <a href="http://www.dreamhost.com">DreamHost</a> account with plenty of spare bandwidth and disk space,
so we decided to move there. For the most part the migration went smoothly, until I started up Trac and discovered
exactly how much spam was in there.</p>

<p>This problem stumped me for about 2 weeks. I spent several hours trying to clean it by hand one day, and after those
several hours I couldn&#8217;t tell the difference. So, yesterday, I finally sat down to try and solve the problem.</p>

<p>With the help of the fine folks on the <a href="irc://chat.freenode.net/#trac">#trac</a> IRC channel, especially coderanger, I wrote a script which deleted
every single ticket change after a certain timestamp (corresponding to the first spam comment). Unfortunately, there
were probably a handful of legitimate changes lost, but there really was no other alternative. In any case, this script
worked flawlessly, and Trac was de-spammed. To prevent this from happening in the future, I turned off anonymous
editing and installed a plugin which allows users to register for an account. Hopefully the requirement of registration
will block most spam.</p>

<p>There was one interesting aspect to this that puzzled me until yesterday. The vast majority of the spam I saw contained
words that I had placed into the blacklist ages ago. I couldn&#8217;t figure out why the spam protection wasn&#8217;t working.
And then yesterday I discovered the reason. The blacklist is kept on a page called BadContent. The first code block
on that page consists of regular expressions, one per line, that each match a blacklisted expression. Unfortunately,
I forgot to mark this page read-only. So what happened was one of the random spam attempts happened to target this
page. The spammer replaced the content with his own code block containing a vast number of <code>&lt;a href&gt;</code> tags linking
to spammy websites. This had the effect of replacing the entire blacklist with a bunch of regular expressions matching
<code>&lt;a href&gt;</code> tags. This meant that all of the stuff that was previously blacklisted was no longer being blocked, opening
the floodgates for all sorts of spam.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2007/01/22/the-resurrection-of-typosphere/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Haml: A new markup format for Rails</title>
		<link>http://kevin.sb.org/2007/01/19/haml-a-new-markup-format-for-rails/</link>
		<comments>http://kevin.sb.org/2007/01/19/haml-a-new-markup-format-for-rails/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 07:38:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Haml]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[markup]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://bb44e772-6a69-431f-8024-0b7918fd09d1</guid>
		<description><![CDATA[Haml is a new markup format for Ruby on Rails apps that just hit 1.0. At first glance it looks pretty odd, but it turns out to be really easy to write in, and it&#8217;s shorter and, actually, easier to read than the equivalent eRB. I think I&#8217;m going to convert Typo to use Haml [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://haml.hamptoncatlin.com/">Haml</a> is a new markup format for Ruby on Rails apps that just hit 1.0. At first glance
it looks pretty odd, but it turns out to be really easy to write in, and it&#8217;s shorter and,
actually, easier to read than the equivalent eRB.</p>

<p>I think I&#8217;m going to convert <a href="http://www.typosphere.org">Typo</a> to use <a href="http://haml.hamptoncatlin.com/">Haml</a> for all its templates. I already did Azure&#8217;s layout
file and it was pretty simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2007/01/19/haml-a-new-markup-format-for-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MacUpdate oddity</title>
		<link>http://kevin.sb.org/2006/03/15/macupdate-oddity/</link>
		<comments>http://kevin.sb.org/2006/03/15/macupdate-oddity/#comments</comments>
		<pubDate>Wed, 15 Mar 2006 16:04:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[azureus]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[macupdate]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://56e3f3d2-8e3a-4ae6-a082-99e1a4f50acf</guid>
		<description><![CDATA[Last night I tried searching MacUpdate for bittorrent or Azureus and got zero results. I thought that to be very strange, and wondered if Joel decided to take an anti-piracy stance (despite the fact that BitTorrent is very useful for distribution of perfectly legal materials). But today when I looked again, I got all the [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I tried searching <a href="http://www.macupdate.com">MacUpdate</a> for <a href="http://www.macupdate.com/bittorrent">bittorrent</a> or <a href="http://www.macupdate.com/Azureus">Azureus</a> and got zero results. I thought that to be very strange, and wondered if Joel decided to take an anti-piracy stance (despite the fact that BitTorrent is very useful for distribution of perfectly legal materials). But today when I looked again, I got all the results I expected. Very strange.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2006/03/15/macupdate-oddity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Ultimate Showdown of Ultimate Destiny</title>
		<link>http://kevin.sb.org/2006/01/22/the-ultimate-showdown-of-ultimate-destiny/</link>
		<comments>http://kevin.sb.org/2006/01/22/the-ultimate-showdown-of-ultimate-destiny/#comments</comments>
		<pubDate>Sun, 22 Jan 2006 23:53:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[ultimate]]></category>

		<guid isPermaLink="false">http://d939acf0-f86d-47e7-abf5-215fba786b80</guid>
		<description><![CDATA[My friend from college just sent me a link to The Ultimate Showdown of Ultimate Destiny, which is the greatest thing I have seen in a while. I managed to find the website for the guy(s?) who did the music. Their website can be found at eviltrailmix.com/lemondream/, although they hit their bandwidth limit today, but [...]]]></description>
			<content:encoded><![CDATA[<p>My friend from college just sent me a link to <a href="http://home.comcast.net/~wepon1984/ultimateshowdown.swf">The Ultimate Showdown of Ultimate Destiny</a>, which is the greatest thing I have seen in a while. I managed to find the website for the guy(s?) who did the music. Their website can be found at <a href="http://www.eviltrailmix.com/lemondream/">eviltrailmix.com/lemondream/</a>, although they hit their bandwidth limit today, but they should be back tomorrow.</p>

<p><strong>Update:</strong> Comments disabled because I&#8217;m tired of all the inane comments I&#8217;ve been receiving. There&#8217;s really no discussion to be had here, so no point in having comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2006/01/22/the-ultimate-showdown-of-ultimate-destiny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RSS feed for crash reports</title>
		<link>http://kevin.sb.org/2006/01/05/rss-feed-for-crash-reports/</link>
		<comments>http://kevin.sb.org/2006/01/05/rss-feed-for-crash-reports/#comments</comments>
		<pubDate>Fri, 06 Jan 2006 02:04:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[crashreporter]]></category>
		<category><![CDATA[NetNewsWire]]></category>
		<category><![CDATA[rss]]></category>

		<guid isPermaLink="false">http://1391d297-5838-43c6-b81c-2a24d0caca2d</guid>
		<description><![CDATA[Inspired by a script mentioned on ranchero.com, I wrote a ruby script that generates an RSS feed for all the Crash Reporter logs on your machine. Just create a New Special Subscription in NetNewsWire, point it at the script, and you&#8217;re all set.]]></description>
			<content:encoded><![CDATA[<p>Inspired by a script <a href="http://ranchero.com/?comments=1&#038;postid=1248">mentioned</a> on <a href="http://ranchero.com">ranchero.com</a>, I wrote a ruby <a href="/files/showcrashreports.rb">script</a> that generates an RSS feed for all the Crash Reporter logs on your machine. Just create a New Special Subscription in <a href="http://ranchero.com/netnewswire/">NetNewsWire</a>, point it at the script, and you&#8217;re all set.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2006/01/05/rss-feed-for-crash-reports/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>MouseHole and JavaScript</title>
		<link>http://kevin.sb.org/2005/09/03/mousehole-and-javascript/</link>
		<comments>http://kevin.sb.org/2005/09/03/mousehole-and-javascript/#comments</comments>
		<pubDate>Sun, 04 Sep 2005 03:23:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mousehole]]></category>
		<category><![CDATA[proxy]]></category>

		<guid isPermaLink="false">http://3d5d900f9c832f5b8654d85fc336d39c</guid>
		<description><![CDATA[So why has been talking about MouseHole lately. If you&#8217;re unaware, MouseHole is a ruby script that acts as a web proxy and filters HTML documents via ruby scripts. Or for a much better look at it, go look at what why wrote. Anyway, I wanted a way to do JavaScript cross-site AJAX tricks, like [...]]]></description>
			<content:encoded><![CDATA[<p>So <a href="http://www.whytheluckystiff.net">why</a> has been <a href="http://redhanded.hobix.com/inspect/mousehole11InPlainView.html">talking</a> about <a href="http://mousehole.rubyforge.org">MouseHole</a> lately. If you&#8217;re unaware, <a href="http://mousehole.rubyforge.org">MouseHole</a> is a ruby script that acts as a web proxy and filters HTML documents via ruby scripts. Or for a much better look at it, go look at what why <a href="http://redhanded.hobix.com/inspect/mousehole11InPlainView.html">wrote</a>.</p>

<p>Anyway, I wanted a way to do JavaScript cross-site AJAX tricks, like what <a href="http://greasemonkey.mozdev.org/">Greasemonkey</a> enables. Unfortunately, because <a href="http://mousehole.rubyforge.org">MouseHole</a> is a pre-processor, not a JavaScript extension, it&#8217;s not possible. So I spent a few hours and wrote a way for <a href="http://mousehole.rubyforge.org">MouseHole</a> scripts to provide content that doesn&#8217;t actually exist (as opposed to mutating existing content). This way JavaScript can do an AJAX call within the same domain (so it doesn&#8217;t hit the security limitations) but that call is intercepted by your script, so you could pull info from other sites and send it back, or whatever you wish.</p>

<p>I haven&#8217;t actually done anything with this new capability yet aside from a rather silly example script which simply adds a button to Google that asks MouseHole for a random number. I&#8217;d really like to extend <a href="http://maps.google.com">Google Maps</a>, but that will require delving into how it works, and it&#8217;s far too late to do that now, as I need to get to bed.</p>

<p>Anyhow, I put together a patch and sent it to the MouseHole Scripters mailing list. If you check out MouseHole from the CVS <a href="http://www.rubyforge.org/projects/mousehole">repository</a>, you can apply my <a href="/files/mousehole-1.patch">patch</a> and test it. Or you can just wait to see if it gets added to <a href="http://mousehole.rubyforge.org">MouseHole</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2005/09/03/mousehole-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The fish returns</title>
		<link>http://kevin.sb.org/2005/08/28/the-fish-returns/</link>
		<comments>http://kevin.sb.org/2005/08/28/the-fish-returns/#comments</comments>
		<pubDate>Sun, 28 Aug 2005 16:21:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[fish]]></category>
		<category><![CDATA[puzzle]]></category>

		<guid isPermaLink="false">http://eeeae0c8ae593e1854905446d3892e01</guid>
		<description><![CDATA[From the people who brought us Who Owns The Fish? comes a new logic puzzle, School of Government. I just ran across this today, and the answer deadline is tomorrow, so that was cutting it a little close, but with a pen and a pad of paper I think I&#8217;ve solved it. And no, I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>From the people who brought us <a href="http://kevin.sb.org/articles/2005/08/03/who-owns-the-fish">Who Owns The Fish?</a> comes a new logic puzzle, <a href="http://www.coudal.com/theotherfish.php">School of Government</a>. I just ran across this today, and the answer deadline is tomorrow, so that was cutting it a little close, but with a pen and a pad of paper I think I&#8217;ve solved it. And no, I&#8217;m not going to give you the solution (like I did last time). Go solve it on your own.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2005/08/28/the-fish-returns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Who owns the fish?</title>
		<link>http://kevin.sb.org/2005/08/03/who-owns-the-fish/</link>
		<comments>http://kevin.sb.org/2005/08/03/who-owns-the-fish/#comments</comments>
		<pubDate>Thu, 04 Aug 2005 02:11:00 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[fish]]></category>
		<category><![CDATA[puzzle]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://d717a07af411fe50a7403730b62347d7</guid>
		<description><![CDATA[I ran across a link on SvN to an interesting logic puzzle called Whose Fish?. It purports to be a logic puzzle created by Albert Einstein, and claims Einstein said 98% of the population would not be able to solve it. So naturally, I was intrigued. The only problem was, the logic matrix for the [...]]]></description>
			<content:encoded><![CDATA[<p>I ran across a link on <a href="http://www.37signals.com/svn/">SvN</a> to an interesting logic puzzle called <a href="http://www.coudal.com/thefish.php" title="Who owns the fish?">Whose Fish?</a>. It purports to be a logic puzzle created by Albert Einstein, and claims Einstein said 98% of the population would not be able to solve it. So naturally, I was intrigued.</p>

<p>The only problem was, the logic matrix for the puzzle doesn&#8217;t fit on a single piece of paper, and I don&#8217;t have Excel installed. So what did I do? I wrote a CGI script in Ruby that generated a logic matrix using a table of checkboxes, and I wrote some accompanying JavaScript to make it easier to use. Go <a href="http://kevin.sb.org/files/fish.cgi">try it</a>!</p>

<p>If you don&#8217;t want to solve the puzzle yourself, feel free to check out some of my steps. Just please, don&#8217;t submit this as your own answer. If you&#8217;re going to submit an answer, do the work yourself. So anyway, here are some of my steps:</p>

<ol>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222000020000000022000020000200002000000002122222000020000122220000220000200201222220000000022000020000200002000022221200001222202000020000200000000200000200221222020000000020000020000200021222000002002021222020000200000000200002200002000020000000022212000220020000000000000002022212002000000000000000200002022122000000000000020000200020000000000000002002020002000000000000221220200000200000200000000200212220020000020000000020002000221220002000000002000200000200222120000000200020000020000220000000000200200000000002021222000022212200000000200202000002002000000000022022000000200200000002221202000222210020000000000200200021222000000000000000200000200000000000000000012222020000000000000000002020002000000000000000000220000200000000000000000020000">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222200022000020022000020000200002000020002122222200020200122220002220000200221222220200000022000020200200002002022221220001222222000220000200220000202000200221222020000000020002020000200021222000002002021222020000200000000200202200002000020000000022212200222020000002200002002022212002000000000000002200002022122000000000000020000200020000000000000002002020002000000000000221222200020200000222000020200212220020000020000000022002000221220002000000002020200000200222120000000200020000020000220000000200200200000000002021222200022212200000000200202000002002000000000022022000020200200000002221202000222212020020000200202200021222200002000020000200020200200000000000000012222020000000000000000002020002000000000000000000220000200000000000000000020000">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222200022000020022000020000200002000020002122222200020200122220002220000200221222220200000022000020200200002002022221220001222222000220000200220000202000220221222020200000020002020000202021222020202002021222022000200000000200202200002000020000000022212200222020000002200002002022212022000200000000002200202022122000000000000020000200020000000000000002002020022000000000000221222200020200000222000020200212220220202020000000022002020221220002000000002020220000200222120000000200020000020000220000000200200200000000002021222200022212202000020200202000002002000000000022022000020202200000002221202000222212020020000200202200021222200002000020000200020200200200000000000012222020000000000000000002020002000002000000000000220000200000000000000000020000">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222200022000020022000020000200002000020002122222200020200122220002220000200221222220200000022000020200200002002022221220001222222122220000200220000202002221221222020200000020002122220202021222020202002021222022000200000000200202222102000020000000022212221222220000002200002002022212022000200000000002201222222122000000000000020212222122200000000000002022221022000000000000221222200020220000222000020200212222221202020000000022002020221220002000000002020220000220222120000000200020000022000220000000200200200000000002021222200022212202000020200202000002002000000000022022000020202200000002221202000222212020020000200202200021222200002000020000200020200200200000000000012222020000000000000000002020002000002000000000000220000200000000000000000020000">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222212222000020022000020000202002000020002122222200020200122220002220000200221222220200000022000020200202002002022221220001222222122220000200220020202002221221222020200002020002122220202021222020202002021222022000200022212200202222102000020000002022212221222220021222200202002022212022000200022212122221222222122020000002020020212222122202000000202002022221022000200000020221222200020220000222000020200212222221202020000000022002020221220002000000002020220000220222120000000200020000022000220000000200200200200000002021222200022212212222020200202000002002002000000022022000020202200200002221202000222212020020000200202200021222200202200020000200020200200220020000000012222020000002002000000002020002000222122122200000220000200000020020000000020000">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222212222122020222002020220222002221222212122222220020220122220202220000221221222222221212222002020200202002122222221220001222222122221220202220020202202221221222020200002022212122220222021222020202202021222022000200022212200202222102200020000002022212221222220021222200202202022212022000200022212122221222222122020222002020220212222122202000000202002022221022000200000020221222200020220000222000022221212222221202020200001222212222221220202220020212222220000220222121222222212220000022000220200000202200200200000002021222222122212212222022202202002022002002000000022222002122222200202002221212222222212020020200202202200021222200202220022212222120200200220020000002012222020000002002000000202022022020222122122200220220200200000020020000002020020">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222212222122020222002022221222002221222212122222221220220122220202220000221221222222221212222002021222202002122222221220001222222122221220202220020222212221221222020200002022212122220222021222020202212221222022200200022212212222222102200020000002022212221222220021222200202202022212022000200022212122221222222122020222002020220212222122202000000202002022221022000200000020221222200020220000222000022221212222221202020200001222212222221220202220020212222222000220222121222222212220000022000220200000202200200200000002021222222122212212222022202202002022002002000000022222002122222200202002221212222222212020020200202202200021222200202220022212222120200200220020000002012222020000002002000000202022022020222122122200220220200200000020020000002020020">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222212222122122222002022221222212221222212122222221221222122222212220000221221222222221212222002021222222122122222221220001222222122221221222220020222212221221222222212002022212122222222121222220202212221222122222212222212212222222122212222121222222212221222222121222200202212222212022022212222212122221222222122122222002022221212222122222221002202122222221022022221200220221222221220220000222000022221212222221222221200001222212222221220202220020212222222120220222121222222212221221222200222200001222212222221220202021222222122212212222022202202022122222122122202022222002122222221222212221212222222212122222212212222200021222222212220022212222120200200222020000002012222020000002202022000202022022020222122122200220220200200000022020000002020020">Step</a></li>
<li><a href="http://kevin.sb.org/files/fish.cgi?122222212222122122222002022221222212221222212122222221221222122222212220000221221222222221212222002021222222122122222221220001222222122221221222220020222212221221222222212002022212122222222121222220202212221222122222212222212212222222122212222121222222212221222222121222200202212222212122222212222212122221222222122122222002022221212222122222221002202122222221222122221200220221222221221222221222000022221212222221222221200001222212222221221222220020212222222122221222121222222212221221222221222200001222212222221222212221222222122212212222222212202022122222122122212222222002122222221222212221212222222212122222212212222200021222222212220022212222120200200222020000002012222020000002202022000202022022020222122122200220220200200000022020000002020020">Step</a></li>
</ol>

<p>And here&#8217;s the <a href="http://kevin.sb.org/files/fish.cgi?122222212222122122222122222221222212221222212122222221221222122222212222212221221222222221212222212221222222122122222221222211222222122221221222221222222212221221222222212222122212122222222121222221222212221222122222212222212212222222122212222121222222212221222222121222221222212222212122222212222212122221222222122122222122222221212222122222221222212122222221222122221212222221222221221222221222221222221212222221222221222211222212222221221222221222212222222122221222121222222212221221222221222221221222212222221222212221222222122212212222222212212222122222122122212222222122122222221222212221212222222212122222212212222222121222222212222122212222121222212222221222212212222222122212212222222212122222122222122122212222221222222121222222122122222221">final solution</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2005/08/03/who-owns-the-fish/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
