var org = {p3k: ({url:"http://dvice.com/rss.xml", xml:"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rss version=\"2.0\">\n<channel>\n<title>DVICE</title>\n<link>http://dvice.com/</link>\n<description>We love technology. We want to know about it, write about it, and shake it till it breaks. Part of the Syfy Network, DVICE has a worldwide team of writers who constantly immerse themselves in the tech world, distilling the sometimes-excessive information out there to bring you only what you need to know.</description>\n<language>en</language>\n<copyright>Copyright 2010</copyright>\n<lastBuildDate>Tue, 09 Feb 2010 11:01:24 -0500</lastBuildDate>\n<generator>http://www.sixapart.com/movabletype/?v=4.24-en</generator>\n<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n\n\n<item>\n<title>Netgear router turns 3G wireless into WiFi</title>\n<author>Adam Frucci</author>\n<description><![CDATA[<img border=\"0\" alt=\"Netgear router turns 3G wireless into WiFi\" src=\"http://dvice.com/assets_c/2010/02/netgearoib35-thumb-230x320-33497.jpg\">]]><![CDATA[<p>Are you sick of paying for cable internet when you only use the internet for light surfing and email? Well, you could always switch completely to 3G wireless internet, provided you trust your wireless provider to not crap out on you.</p>\n\n<p>This new Netgear router can help you do just that, converting a 3G wireless signal into WiFi your laptop can understand. Of course, it also works with traditional connections via ethernet, but where's the adventure in that?</p>\n\n<p><a href=\"http://www.netgear.com/About/PressReleases/en-US/2010/20100209.aspx\">Netgear</a> via <A href=\"http://www.engadget.com/2010/02/09/netgear-partners-with-ericsson-for-a-3g-receiving-wifi-emanatin/\">Engadget</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/netgear-router.php</link>\n<guid>http://dvice.com/archives/2010/02/netgear-router.php</guid>\n<category>Computer Peripherals</category>\n<pubDate>Tue, 09 Feb 2010 11:01:24 -0500</pubDate>\n</item>\n\n<item>\n<title>Apple releases Aperture 3 with some iPhoto features on board</title>\n<author>Adam Frucci</author>\n<description><![CDATA[<img border=\"0\" alt=\"Apple releases Aperture 3 with some iPhoto features on board\" src=\"http://dvice.com/assets_c/2010/02/aperture3-thumb-500x313-33496.jpg\">]]><![CDATA[<p>Apple's pro photo software Aperture has never really caught on like some of its more popular software. Maybe it was the price, at $200, or maybe it just didn't deliver an experience that couldn't be better replicated elsewhere. But Apple's not ready to give up on it yet.</p>\n\n<p>The new version of Aperture has just hit the Apple store, and it brings along with it the Faces and Places features that iPhoto users have been enjoying for some time now. Faces auto-detects who is in each photo, letting you automatically sort pictures by who's in them. Places uses geotagging to place your photos on a map based on where you took them.</p>\n\n<p>Will these features be enough to get you to drop $200 on photo importing and organization software?</p>\n\n<p>Via <A href=\"http://www.apple.com/aperture/\">Apple</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/apple-releases.php</link>\n<guid>http://dvice.com/archives/2010/02/apple-releases.php</guid>\n<category>Apple</category>\n<pubDate>Tue, 09 Feb 2010 10:15:10 -0500</pubDate>\n</item>\n\n<item>\n<title>Publisher cutting books down to 2,000 words and less for the Kindle</title>\n<author>Kevin Hall</author>\n<description><![CDATA[<img border=\"0\" alt=\"Publisher cutting books down to 2,000 words and less for the Kindle\" src=\"http://dvice.com/assets_c/2010/02/TheCreativePen-reading-Flickr-thumb-550x553-33475.jpg\">]]><![CDATA[<p>Sure, I love me some e-reading, but the one big downside is that books have too many darn words! Lucky for me a company called FT Press has my back: it's boiling down professional and self-help books into \"Elements\" and \"Shorts.\" The former hovers somewhere between 1,000 to 2,000 words and sells for $2, while Shorts are a little longer at $3 for around 5,000 words.</p>\n\n<p>So, why take existing books and truncate them? Timothy C. Moore, publisher of the FT Press, told <i>The New York Times</i> that it was \"a good idea to be able to provide people with shorter, more expedient, more time-sensitive\" versions of books.</p>\n\n<p>FT Press's approach eats into publisher profits, as it's unlikely that someone would spring for the full book after getting the best bits. The authors of the original work, however, are entitled to royalties from the online sales.</p>\n\n<p>So what's next? Who knows: maybe in the future people will buy their favorite chapters just as you would a song instead of an album.</p>\n\n<p><a href=\"http://www.nytimes.com/2010/02/08/business/media/08condense.html?ref=technology\">The New York Times</a>, via <a href=\"http://www.geeksugar.com/Publisher-Sells-Cheaper-Shortened-Versions-eBooks-7325931\">GeekSugar</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/publisher-cutti.php</link>\n<guid>http://dvice.com/archives/2010/02/publisher-cutti.php</guid>\n<category>Tablets</category>\n<pubDate>Tue, 09 Feb 2010 09:31:05 -0500</pubDate>\n</item>\n\n<item>\n<title>Heineken Bot ready serve beer without the human smalltalk</title>\n<author>Adario Strange</author>\n<description><![CDATA[<img border=\"0\" alt=\"Heineken Bot ready serve beer without the human smalltalk\" src=\"http://dvice.com/assets_c/2010/02/heinbrbot0098-32-thumb-550x378-33476.jpg\">]]><![CDATA[<p>While the early money is that the first mass commercialization of robots will hit the sex industry, serving booze to wayward humans is running a close second. The Heineken Bot, developed by tinkerers at the UK's Middlesex University, is something like a cross between <a href=\"http://dvice.com/archives/2009/01/star_wars_clock.php\">R2D2</a> and your favorite local suds pourer, only without the inane chit chat. </p>\n\n<p>Using sensors mounted on its top portion, the bot can detect when your beer mug is topped off with just a wave of the hand, and can roll over to your side of the bar due to a preprogrammed area map. You can see video of the Heineken Bot in action <a href=\"http://www.gizmowatch.com/entry/heineken-bot-is-best-beer-serving-robot-we-ve-seen-in-a-while/\">here</a>. </p>\n\n<p>Via <a href=\"http://www.gizmowatch.com/entry/heineken-bot-is-best-beer-serving-robot-we-ve-seen-in-a-while/\">GizmoWatch</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/heineken-bot-re.php</link>\n<guid>http://dvice.com/archives/2010/02/heineken-bot-re.php</guid>\n<category>Robots</category>\n<pubDate>Tue, 09 Feb 2010 04:31:30 -0500</pubDate>\n</item>\n\n<item>\n<title>If online newspapers forced you to pay, would you read them?</title>\n<author>Kevin Hall</author>\n<description><![CDATA[<img border=\"0\" alt=\"If online newspapers forced you to pay, would you read them?\" src=\"http://dvice.com/assets_c/2010/02/Murdoch-Rusbridger-thumb-550x330-33440.jpg\">]]><![CDATA[<p>Rupert Murdoch (above, left), CEO and Sith Lord of News Corp (which owns a variety of book, magazine and newspaper publishers including HarperCollins, <i>The New York Post</i> and <i>The Wall Street Journal</i>) is one of the most vocal &#8212; not to mention powerful &#8212; forces driving the idea that online news websites should charge for the content provided. Typically, news sites and blogs rely on advertising money to stay up and running.</p>\n\n<p><i>The Wall Street Journal</i>, owned by Murdoch's News Corp, is one such news site that charges a subscription fee for access to all of its articles. <i>The New York Times</i>, which isn't owned by News Corp, recently announced that it would also adopt a subscriber \"pay wall\" model in 2011. It's no secret that the magazine and newspaper industry is in trouble, and pay walls are seen as one way to help stop the bleeding.</p>\n\n<p>Not all outlets see adopting pay walls as the way to go. Alan Rusbridger (above, right), editor of The Guardian, recently gave a speech in which he defended the virtues of free content and relying on ad revenue. One of the big fears behind the pay wall structure is the fact that it'd turn certain readers away, which would lower readership and drive down ad revenue.</p>\n\n<p>Rusbridger called Murdoch out directly: <blockquote>\"Rupert Murdoch, who has in his time flirted with free models and who has ruthlessly cut the price of his papers to below cost in order to win audiences or drive out competition&#133; this same Rupert Murdoch is being very vocal in asserting that the reader must pay a proper sum for content &#8212; whether in print or digitally.\"</blockquote></p>\n\n<p>More than just a different way to provide content, Rusbridger sees the Internet as adding a vital layer to journalism &#8212; an interactive, evolving one &#8212; that could be damaged by forcing regular readers of a periodical to pay. Casual readers could come and go, but \"loyal\" readers, as Rusbridger describes them, would seemingly be punished.</p>\n\n<p>Murdoch, in response, said that he hadn't listened to or read Rusbridger's speech but that the general idea \"sounds like BS\" to him. He didn't say \"BS\" exactly, of course. He used the version not fit to print.</p>\n\n<p>So, where do you stand? Sound off in the comments, and don't forget to hit up our poll below.</p>\n\n<p>Read Rusbridger's entire speech <a href=\"http://www.guardian.co.uk/media/2010/jan/25/cudlipp-lecture-alan-rusbridger\">here</a>.</p>\n\n<p><a href=\"http://www.guardian.co.uk/media/greenslade/2010/feb/03/rupert-murdoch-rusbridger-bs\">The Guardian</a>, via <a href=\"http://www.nytimes.com/2010/02/08/business/media/08iht-cache08.html?ref=technology\">The New York Times</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/if-online-newsp.php</link>\n<guid>http://dvice.com/archives/2010/02/if-online-newsp.php</guid>\n<category>Internet</category>\n<pubDate>Mon, 08 Feb 2010 18:06:45 -0500</pubDate>\n</item>\n\n<item>\n<title>Oxo Good Grips Cord Catch does exactly one thing</title>\n<author>Peter Pachal</author>\n<description><![CDATA[<img border=\"0\" alt=\"Oxo Good Grips Cord Catch does exactly one thing\" src=\"http://dvice.com/assets_c/2010/02/oxo_good_grips_cord_catch-thumb-550x389-33431.jpg\">]]><![CDATA[<p>Found in our mailbox the other day: The Oxo Good Grips Cord Catch. While we certainly love <a href=\"http://dvice.com/archives/2010/01/hands-on-with-t.php\">shiny electronic toys</a> that do lots of different things, here's a product that's beautiful for its simplicity. The Catch has just one job &#8212; saving that charging cable from falling behind your desk. And it does it with style, sporting a nicely curved design and a silver finish. It stays in place via the rubberized bottom and sheer heft (the half-ounce spec on <a href=\"http://www.oxo.com/xxoxo_ibeCCtpOXOPrdDtl.jsp?a=b&item=86545&section=10039\">Oxo's product page</a> is incorrect &#8212; it actually weighs closer to five).</p>\n\n<p>After using the catch to hold our iPhone charging cable for a few days, we've given it a permanent place on our desk. We do have this suggested upgrade: The Catch's cable guide should have some kind of \"flaps\" to prevent cords from easily popping out of it. But even with that quibble, the $7 Catch has paid for itself with time saved in cancelled expeditions behind our gadget stack in search of fallen cords.</p>]]></description>\n<link>http://dvice.com/archives/2010/02/simplicity-inca.php</link>\n<guid>http://dvice.com/archives/2010/02/simplicity-inca.php</guid>\n<category>Reviews</category>\n<pubDate>Mon, 08 Feb 2010 16:57:14 -0500</pubDate>\n</item>\n\n<item>\n<title>1080p streaming video coming to Netflix [update: maybe not], but will it matter?</title>\n<author>Charlie White</author>\n<description><![CDATA[<img border=\"0\" alt=\"1080p streaming video coming to Netflix [update: maybe not], but will it matter?\" src=\"http://dvice.com/assets_c/2010/02/netflix_rokuHD_front1080p-thumb-550x358-33439.jpg\">]]><![CDATA[<p>Netflix fans, your streaming video service is just about to accommodate higher HDTV resolution in glorious 1080p. It's unclear exactly when this 1080p streaming with 5.1 surround sound will be rolled out &#8212; Netflix says it will be sometime \"later this year.\"</p>\n\n<p>You'll need more bandwidth to handle the higher resolution, probably exceeding the 7 to 10 Mbps required to stream the company's 720p HD content on the <a href=\"http://dvice.com/archives/2008/12/hands-on-99-rok.php\">Roku</a> box, <a href=\"http://dvice.com/archives/2008/12/hands-on-netfli.php\">TiVo</a>,  the <a href=\"http://dvice.com/archives/2008/10/netflix-to-stre.php\">Xbox 360</a>, and <a href=\"http://dvice.com/archives/2009/10/ps3-owners-youl.php\">PlayStation 3</a>. Let's hope Netflix has a better compression scheme up its sleeve for this 1080p trick, supported by Microsoft Silverlight 1080p streaming introduced last March.</p>\n\n<p>All that additional resolution won't mean much unless Netflix can stream more than just a measly 6% of its movies in HD, as it does now. That's lame &#8212; even<a href=\"http://gizmodo.com/5466753/why-netflix-doesnt-really-care-about-hd\"> Netflix's own PR flack calls it \"underwhelming.</a>\" Beyond that, there's the problem of bandwidth-stingy Internet service providers, many of whom also sell pay-per-view movies on cable, <a href=\"http://news.cnet.com/8301-31001_3-10449187-261.html\">balking at opening up their pipes for a competitor's 1080p content</a>. </p>\n\n<p>Now Netflix tells CNET the reference to 1080p streaming was a mistake. According to CNET: </p>\n\n<blockquote>\"Netflix now claims that it incorrectly acknowledged 1080p streaming in the company's 2010 development road map. A Netflix representative has clarified that the company plans to bring 5.1 surround and closed captioning to its streaming HD videos later this year, though 1080p Watch Instantly is not on the books for this year.\"</blockquote>\n\n<p>Oh well. Netflix must think bandwidth won't be wide enough for that kind of rez, at least not this year. Or maybe it's just being coy, still planning a big 1080p splash!</p>\n\n<p>Via <a href=\"http://news.cnet.com/8301-27076_3-20000054-248.html\">CNET</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/1080p-streaming.php</link>\n<guid>http://dvice.com/archives/2010/02/1080p-streaming.php</guid>\n<category>HDTV</category>\n<pubDate>Mon, 08 Feb 2010 16:11:44 -0500</pubDate>\n</item>\n\n<item>\n<title>Shuttle&apos;s final night launch lifts largest window ever into orbit</title>\n<author>Charlie White</author>\n<description><![CDATA[<img border=\"0\" alt=\"Shuttle's final night launch lifts largest window ever into orbit\" src=\"http://dvice.com/assets_c/2010/02/shuttle-night-launch-history-cs-100208-02-thumb-550x335-33421.jpg\">]]><![CDATA[<p>The last shuttle to be launched at night rose off its launch pad before dawn this morning, atop a torrent of fire that seemed as bright as the sun. On board <em>Endeavor </em>(STS-130) is <a href=\"http://en.wikipedia.org/wiki/Cupola_(ISS)\"><em>Cupola</em></a>,  a relatively huge bay window to be attached to the International Space Station (ISS) that will give astronauts the <a href=\"http://dvice.com/archives/2009/06/space-station-a.php\">most magnificent view ever seen from space</a> (short of taking a spacewalk). Expect great pictures from this 1.6-ton behemoth &#8212; it's 9.7 feet wide and 5 feet long with seven windows all around, including a 31.5-inch circular window, the largest ever flown into space.</p>\n\n<p>Also along for the ride is <em><a href=\"http://en.wikipedia.org/wiki/Tranquility_(ISS_module)\">Tranquility</a></em>, whose technical name is the unassuming \"Node 3.\" That module will have six \"birthing locations\" (or in plain terms, places to plug in more modules), three of which aren't scheduled to be used, and one will be where <em>Cupola </em>will be connected. Tranquility will also contain the most advanced life-support systems ever flown in space, recycling wastewater and generating oxygen.</p>\n\n<p>Via <a href=\"http://www.space.com/news/shuttle-night-launch-history-cs-100208.html\">Space.com</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/shuttles-last-n.php</link>\n<guid>http://dvice.com/archives/2010/02/shuttles-last-n.php</guid>\n<category>Space</category>\n<pubDate>Mon, 08 Feb 2010 15:29:21 -0500</pubDate>\n</item>\n\n<item>\n<title>Darth Vader alarm clock wakes you up with the power of the Dark Side</title>\n<author>Adam Frucci</author>\n<description><![CDATA[<img border=\"0\" alt=\"Darth Vader alarm clock wakes you up with the power of the Dark Side\" src=\"http://dvice.com/assets_c/2010/02/darth-alarm-clock-thumb-560x656-33416.jpg\">]]><![CDATA[<p>Do you require a bit of motivation to get out of bed in the morning? Well, there are few people more motivating than Darth Vader, right?</p>\n\n<p>With this Darth Vader alarm clock, a shadow Vader will appear when the alarm goes off, reminding you to get out of bed or the forces of the Dark Side will overtake you. It also features a snooze button, just in case you feel the power of The Force deep inside you.</p>\n\n<p><a href=\"http://shop.starwars.com/catalog/product.xml?topcatID=1300264;product_id=1318506\">StarWars.com</a> via <a href=\"http://www.geekalerts.com/darth-vader-alarm-clock/\">Geek Alerts</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/darth-vader-ala.php</link>\n<guid>http://dvice.com/archives/2010/02/darth-vader-ala.php</guid>\n<category>Miscellaneous</category>\n<pubDate>Mon, 08 Feb 2010 14:45:56 -0500</pubDate>\n</item>\n\n<item>\n<title>Portable Cinedeck lets filmmakers record and edit high-rez footage</title>\n<author>Charlie White</author>\n<description><![CDATA[<img border=\"0\" alt=\"Portable Cinedeck lets filmmakers record and edit high-rez footage\" src=\"http://dvice.com/assets_c/2010/02/cinedeck_front550-thumb-550x342-33409.jpg\">]]><![CDATA[<p>Cinematographers got sick of lugging around bulky and anvil-heavy recording gear, so they designed the \"extremely portable\" Cinedeck, a hotshot digital video recorder that's 8 inches wide and weighs 4 pounds. It digitally records HD footage from any camera that outputs HDMI or HDSDI onto its off-the-shelf solid-state drives. </p>\n\n<p>Besides functioning as a digital recorder and high-rez playback unit, this versatile box's on-board Intel Core2 Extreme quad qx9300 processor powers a fast Windows PC inside, letting you hook up a mouse, keyboard and a larger monitor to edit together your shots using whichever Windows editing software you prefer.</p>\n\n<p>Shipping next month is the first Cinedeck/Extreme model, capable of handling resolutions up to 1080p. Later this year, the company will roll out versions for 3D shooting, higher-rez 2K film work, and even a model that handles footage from <a href=\"http://dvice.com/archives/2009/04/redrock-hybrid.php\">those sweet 1080p-shooting digital SLR cameras</a>. Pricing starts at $7995, so you can see it's intended for pro use on film shoots. </p>\n\n<p>Here's the press release with more details:</p>]]></description>\n<link>http://dvice.com/archives/2010/02/portable-cinede.php</link>\n<guid>http://dvice.com/archives/2010/02/portable-cinede.php</guid>\n<category>HDTV</category>\n<pubDate>Mon, 08 Feb 2010 13:57:11 -0500</pubDate>\n</item>\n\n<item>\n<title>The 7 best Super Bowl XLIV commercials featuring tech</title>\n<author>Charlie White</author>\n<description><![CDATA[<img border=\"0\" alt=\"The 7 best Super Bowl XLIV commercials featuring tech\" src=\"http://dvice.com/assets_c/2010/02/logo_2010-super-bowl-thumb-550x247-33387.jpg\">]]><![CDATA[<p>Talking animals took a back seat to high technology this year during the commercial breaks of <a href=\"http://dvice.com/archives/2010/02/why-super-bowl.php\">Super Bowl XLIV</a>. After a slow start full of desperate beer lovers and lethal corn chips, the tech started flowing in abundance. By the time those old codgers called The Who took to the stage at halftime, we knew this was going to be a good year for tech-related Super Bowl commercials. Here are our top seven favorites:</p>]]></description>\n<link>http://dvice.com/archives/2010/02/top-5-super-bow.php</link>\n<guid>http://dvice.com/archives/2010/02/top-5-super-bow.php</guid>\n<category>Video</category>\n<pubDate>Mon, 08 Feb 2010 13:06:47 -0500</pubDate>\n</item>\n\n<item>\n<title>Live your hovercraft dreams with a remote control</title>\n<author>Adam Frucci</author>\n<description><![CDATA[<img border=\"0\" alt=\"Live your hovercraft dreams with a remote control\" src=\"http://dvice.com/assets_c/2010/02/rc-hoverpod_main-thumb-350x300-33408.jpg\">]]><![CDATA[<p>When I was a kid, I thought hovercrafts were going to be the vehicle of the future. And why not? They ditch wheels for floating around on a cushion of air! Alas, it was not to be. But that doesn't mean we can't enjoy hovercrafts in remote-controlled toy form.</p>\n\n<p>The RC Hoverpod lets you do just that, using downward-blasted air to scoot this diminutive vehicle all over the place. Just stay away from bumps. I'm pretty sure the speedbump is what kept hovercrafts from ever catching on, so you'll want to keep your toy version from falling into the same trap.</p>\n\n<p><a href=\"http://www.iwantoneofthose.com/rc-hoverpod/index.html\">I Want One of Those</a> via <a href=\"http://www.coolest-gadgets.com/20100208/rc-hoverpod-brings-kid/\">Coolest Gadgets</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/live-your-hover.php</link>\n<guid>http://dvice.com/archives/2010/02/live-your-hover.php</guid>\n<category>Toys</category>\n<pubDate>Mon, 08 Feb 2010 12:16:38 -0500</pubDate>\n</item>\n\n<item>\n<title>Qisda phone delivers an insane 1,280 x 1,024 resolution</title>\n<author>Adam Frucci</author>\n<description><![CDATA[<img border=\"0\" alt=\"Qisda phone delivers an insane 1,280 x 1,024 resolution\" src=\"http://dvice.com/assets_c/2010/02/vodafone-qisda-qcm-330-thumb-500x531-33407.jpg\">]]><![CDATA[<p>How high a resolution do you need on your phone? The upcoming Qisda QCM-330 offers a whopping 1,280 x 1,024 resolution on its 4-inch screen, which is higher than many laptop screens.</p>\n\n<p>The phone is being unveiled next month at the CeBIT tradeshow, and it looks like it'll be coming to Europe on Vodafone. How such a high pixel density will look on such a small screen has yet to be seen, but just spec-wise, it's impressive. We're looking forward to seeing more details of this monster once it's officially available.</p>\n\n<p><a href=\"http://www.unwiredview.com/2010/02/08/vodafones-upcoming-phones-qisda-qcm-330-with-1280-x-1024-pixels-screen-lg-gd880-and-more/\">Unwired View</a>, via <a href=\"http://www.slashgear.com/vodafone-qisda-qcm-330-and-lg-gd880-break-cover-0873146/\">Slashgear</a>, via <a href=\"http://gizmodo.com/5466673/even-at-4+inches-the-qisda-qcm+330-dwarfs-the-ipads-resolution\">Gizmodo</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/qisda-phone-del.php</link>\n<guid>http://dvice.com/archives/2010/02/qisda-phone-del.php</guid>\n<category>Cellphones</category>\n<pubDate>Mon, 08 Feb 2010 11:28:22 -0500</pubDate>\n</item>\n\n<item>\n<title>Real Time Canvas Clock: a snapshot in time</title>\n<author>Leslie Shapiro</author>\n<description><![CDATA[<img border=\"0\" alt=\"Real Time Canvas Clock: a snapshot in time\" src=\"http://dvice.com/assets_c/2010/02/canvasclockprim-thumb-350x350-33393.jpg\">]]><![CDATA[<p>When is a picture of a clock more than just a picture? When it's actually a <a href=\"http://dvice.com/archives/2010/01/this-geek-clock.php\">real clock</a>. The Real Time Canvas Clock is a stark picture of an old-timey desk clock, except this picture shows the actual time &#8212 mounted flush to the canvas is a real clock mechanism.</p>\n\n<p>The clock runs on one AA battery and the clock's mechanics are accessed from the back of the canvas. This simple work of art will <a href=\"http://www.latestbuy.com.au/real-time-canvas-clock.html\">set you back $36</a>. While all the world is going 3D, it's nice to see some good old-fashioned 2D media catching our eye.</p>\n\n<p><a href=\"http://www.techfresh.net/real-time-canvas-clock/?ac=658233465&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+techfresh+%28TechFresh%2C+Consumer+Electronics+Guide%29&utm_content=Google+Reader\">Tech Fresh</a> via <a href=\"http://www.coolest-gadgets.com/20100207/real-tim-canvas-clock-shows-current-time/\">Coolest Gadgets</a></p>]]></description>\n<link>http://dvice.com/archives/2010/02/real-time-canva.php</link>\n<guid>http://dvice.com/archives/2010/02/real-time-canva.php</guid>\n<category>Household</category>\n<pubDate>Mon, 08 Feb 2010 10:42:53 -0500</pubDate>\n</item>\n\n<item>\n<title>Are Klipsch Image X10i earphones too good for the iPhone?</title>\n<author>Charlie White</author>\n<description><![CDATA[<img border=\"0\" alt=\"Are Klipsch Image X10i earphones too good for the iPhone?\" src=\"http://dvice.com/assets_c/2010/02/Image_Hand.JPG-thumb-550x488-33367.jpg\">]]><![CDATA[<p>Tiny earbuds made of aluminum have been a Klipsch specialty for a couple of years now, and now the company adds to its stable of <a href=\"http://dvice.com/archives/2007/08/klipsch-image-earphones-claime.php\">the world's tiniest cans</a> with its high-end Image X10i in-ear headset, now sporting iPhone capability. Let's give them a listen, as well as try them out on our iPhone 3GS, determining if they're really worth their unusually steep $350 price.</p>]]></description>\n<link>http://dvice.com/archives/2010/02/klipsch-image-x.php</link>\n<guid>http://dvice.com/archives/2010/02/klipsch-image-x.php</guid>\n<category>Reviews</category>\n<pubDate>Mon, 08 Feb 2010 09:43:56 -0500</pubDate>\n</item>\n\n</channel>\n</rss>\n", message:undefined, modified:(new Date(1265732100578)), baseUri:"http://p3k.org/rss/", query:"frameColor=black&textColor=black&_=1238276937606&titleBarColor=lightblue&compact=&fontFace=&align=&showXmlButton=&maxItems=30&boxFillColor=white&titleBarTextColor=black&width=620&url=http://dvice.com/rss.xml&", param:{textColor:"black", width:"620", align:"", fontFace:"", url:"http://dvice.com/rss.xml", compact:"", frameColor:"black", showXmlButton:"", boxFillColor:"white", _:"1238276937606", titleBarColor:"lightblue", maxItems:"30", titleBarTextColor:"black"}, box:"<table class=\"rssBox\" width=\"${width}\" bgcolor=\"${frameColor}\" \n      style=\"table-layout: fixed; overflow: hidden; font-family: ${fontFace};\" \n      align=\"${align}\" cellspacing=\"1\" cellpadding=\"7\" border=\"0\">\n<tr bgcolor=\"${titleBarColor}\">\n<td>\n   ${xmlButton}\n   <strong>${title}</strong>\n   <div>\n      <small style=\"color: ${titleBarTextColor};\">${date}</small>\n   </div>\n</td>\n</tr>\n<tr bgcolor=\"${boxFillColor}\">\n<td class=\"rssBoxContent\" style=\"color: ${textColor};\">\n   ${image}\n   ${items}\n   ${input}\n   <div class=\"rssBoxPromo\" style=\"margin-top: 0px; text-align: left; \n         font: 9px verdana, sans-serif\">\n      RSS box by <a href=\"http://p3k.org/rss\">p3k.org</a>.\n   </div>\n</td>\n</tr>\n</table>\n\n", image:"<a href=\"${link}\"><img src=\"${source}\" width=\"${width}\" height=\"${height}\" \nalt=\"${title}\" title=\"${title}\" align=\"${align}\" valign=\"${valign}\" \nhspace=\"${hspace}\" vspace=\"${vspace}\" border=\"0\" /></a>\n\n", input:"<form method=\"get\" action=\"${link}\">\n${description}\n<input type=\"text\" name=\"${name}\" size=\"15\" /> <input type=\"submit\" \nvalue=\"${title}\" />\n</form>\n\n", item:"<div class=\"rssBoxItemContent\">\n${title}\n${break}\n${description}\n${buttons}\n</div><br />\n\n", date:"${year}-${month}-${day}, ${hours}:${minutes}h\n\n", link:"<a class=\"${class}\" href=\"${link}\" style=\"${style}\">${text}</a>\n", error:"<?xml version=\"1.0\"?>\n<rss version=\"error\">\n   <channel>\n      <title>RSS Box Error</title>\n      <link>${link}</link>\n      <description>This output was automatically generated to report an error \n      that occurred during a request to the JavaScript RSS Box Viewer.</description>\n      <item>\n         <title>Oops, something went wrong...</title>\n         <description>An error occurred while processing the request to the \n         JavaScript RSS Box Viewer.</description>\n      </item>\n      <item>\n         <title>An error message was returned by the server.</title>\n         <description>${message}</description>\n      </item>\n      <item>\n         <description>Most likely, this might have happened because of a \n         non-existent or invalid RSS feed URL. Please check and possibly correct \n         your input, then try again.</description>\n      </item>\n   </channel>\n</rss>\n\n"})};
function debug(str) {
   return document.write('<p><span style="background-color: yellow;">', 
         str, '</span><p>');
}

org.p3k.RssBox = function() {
   var ref;
   var ISOPATTERN = /([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9:]+).*$/;
   
   var data = org.p3k;
   data.defaults = {
      url: "http://blog.p3k.org/rss",
      maxItems: 7,
      width: 200,
      align: "",
      frameColor: "black",
      titleBarColor: "lightblue",
      titleBarTextColor: "black",
      boxFillColor: "white",
      textColor: "black",
      showXmlButton: "",
      compact: ""
   };
   
   var baseUri = data.baseUri;
    
   var getColor = function(str) {
      if (str.length === 6 && parseInt(str, 16) && str.indexOf("#") !== 0) {
         str = "#" + str;
      }
      return str.toLowerCase();
   }

   var value;
   for (var i in data.defaults) {
      value = data.param[i];
      if (!value || value.length === 0) {
         data.param[i] = data.defaults[i];
      } else if (i.indexOf("Color") > 0) {
         data.param[i] = getColor(value);
      }
   }

   // FIXME: Ugly work-around for many boxes using too small width 
   // values because the former version did not show the exact output.
   if (data.param.javascript && data.param.width < 200) {
      data.param.width = 200;
   }
   // Remove obsolete parameters from param and query
   delete data.param.javascript;
   data.query = data.query.replace("javascript=true", "");   

   var NAMESPACES = {
      dc: "http://purl.org/dc/elements/1.1/",
      rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   };

   var getUrl = function(url) {
      url = baseUri + "proxy.r?" + encodeURIComponent(url);
   
      var HttpRequest = function() {
         return (typeof XMLHttpRequest !== "undefined") ?
            new XMLHttpRequest() : new ActiveXObject("Msxml2.XMLHTTP");
      }
   
      var request = new HttpRequest();
      request.open("GET", url, false);
      request.send(null);   
      if (!request.getResponseHeader("Date")) {
         var cached = request;
         var ifModifiedSince = cached.getResponseHeader("Last-Modified") || 
               new Date(0); // January 1, 1970
         request = new HttpRequest();
         request.open("GET", url, false);
         request.setRequestHeader("If-Modified-Since", ifModifiedSince);
         request.send("");
         if (request.status === 304) {
            request = cached; 
         }
      }
      return request;
   }
   
   var getDocument = function(source) {
      if (source) {
         if (document.implementation.createDocument) {
            var parser = new DOMParser();
            var doc = parser.parseFromString(source, "text/xml");
            return doc;
         } else if (window.ActiveXObject) {
            var doc = new ActiveXObject("Microsoft.XMLDOM");
            doc.async = "false";
            doc.loadXML(source);
            return doc;
         }
      }
      return null;
   }
   
   var getError = function() {
      var msg = null, root;
      if (!xml || data.message) {
         msg = data.message || "Unknown error.";
      } else if (xml.parseError && xml.parseError.errorCode) {
         msg = xml.parseError.reason; // IExplore
      } else if (root = xml.documentElement) {
         var errorNode;
         if (root.nodeName === "parsererror") {
            msg = xml.documentElement.textContent; // Mozilla
         } else if ((errorNode = root.childNodes[0]) && 
               errorNode.nodeName === "parsererror") {
            msg = errorNode.textContent; // Safari
         } else if (!/rss|rdf|scriptingNews/i.test(xml.documentElement.nodeName)) {
            msg = "Incompatible data format. Are you sure this is an RSS feed?";
         }
      }
      return msg;
   }
   
   var getNode = function(parent, name, namespace) {
      if (namespace) {
         if (typeof parent.getElementsByTagNameNS === "undefined") {
            var elements = parent.getElementsByTagName(namespace + ":" + name);
         } else {
            var elements = parent.getElementsByTagNameNS(NAMESPACES[namespace], name);
         }
      } else {
         var elements = parent.getElementsByTagName(name);
      }
      if (elements && elements[0]) {
         return elements[0];
      }
      return null;
   }
   
   var getText = function(node) {
      if (node && node.childNodes && node.childNodes.length > 0) {
         return node.childNodes[0].nodeValue || "";
      }
      return "";
   }
   
   var trim = function(str) {
      if (str) {
         return str.replace(/^\s*(\S*)\s*$/, "$1");
      }
      return "";
   }
   
   var padZero = function(n) {
      if (n < 10) {
         return "0" + n
      }
      return n;
   }

   var encodeXml = function(str) {
      if (!str) {
         return "";
      }
      return str.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&/g, "&amp;");
   }
      
   var render = function(template, param) {
      if (!template || !param) {
         return template;
      }
      template = template.replace(/\$\{([^}]+)\}/g, function() {
         var key = arguments[1];
         return param[key] || "";
      });
      return template;
   }
   
   var renderDate = function(date) {
      if (date.constructor !== Date) {
         var str = String(date);
         var millis = Date.parse(str.replace(ISOPATTERN, "$1/$2/$3 $4"));
         if (millis) {
            date = new Date(millis);
         } else {
            date = new Date;
         }
      }

      return render(data.date, {
         year: date.getFullYear(),
         month: padZero(date.getMonth() + 1),
         day: padZero(date.getDate()),
         hours: padZero(date.getHours()),
         minutes: padZero(date.getMinutes()),
         seconds: padZero(date.getSeconds()),
         timeZone: "" // date.getTimezoneOffset()
      });
   }
   
   var renderButtons = function(enclosure, source) {
      var result = "";
      if (enclosure && enclosure.link) {
         result += render(data.image, {
            source: baseUri + "enclosure.gif",
            title: enclosure.type,
            link: encodeURI(enclosure.link),
            width: 13,
            height: 16
         });
      }
      if (source && source.link) {
         result += render(data.image, {
            source: baseUri + "source.gif",
            title: source.title,
            link: encodeURI(source.link),
            width: 15,
            height: 15
         });
      }
      return result;         
   }
   
   var param = data.param;
   var rss = data.rss = {items: []};
   var xml = getDocument(data.xml);

   rss.error = getError();
   if (rss.error !== null) {
      xml = getDocument(render(data.error, {
         link: baseUri + "?" + encodeXml(data.query),
         message: encodeXml(rss.error)
      }));
      param.compact = 0;
      param.showXmlButton = 1;
   }

   var root = xml.documentElement;
   var type = root.nodeName;

   if (type === "scriptingNews") {
      var channel = getNode(xml, "header");
      rss.format = "Scripting News";
      rss.version = getText(getNode(channel, "scriptingNewsVersion"));
      rss.title = getText(getNode(channel, "channelTitle"));
      rss.description = getText(getNode(channel, "channelDescription"));
      rss.link = getText(getNode(channel, "channelLink"));
      if (ref = getText(getNode(channel, "imageUrl"))) {
         ref = rss.image = {source: ref};
         ref.title = getText(getNode(channel, "imageTitle"));
         ref.link = getText(getNode(channel, "imageLink"));
         ref.width = getText(getNode(channel, "imageWidth"));
         ref.height = getText(getNode(channel, "imageHeight"));
         ref.description = getText(getNode(channel, "imageCaption"));
      }
   } else {
      var channel = getNode(xml, "channel");
      rss.format = "RSS";
      rss.version = (type === "rdf:RDF") ? "1.0" : 
            root.getAttribute("version");
      rss.title = getText(getNode(channel, "title"));
      rss.description = getText(getNode(channel, "description"));
      rss.link = getText(getNode(channel, "link"));
      var image = getNode(xml, "image");
      if (image) {
         ref = rss.image = {};
         ref.source = getText(getNode(image, "url"));
         ref.title = getText(getNode(image, "title"));
         ref.link = getText(getNode(image, "link"));
         ref.width = getText(getNode(image, "width"));
         ref.height = getText(getNode(image, "height"));
         ref.description = getText(getNode(image, "description"));
      }
   }
   
   if (type === "rdf:RDF") {
      rss.date = renderDate(getText(getNode(channel, "date", "dc")) || data.modified);
      rss.rights = getText(getNode(channel, "creator", "dc"));
      var input = getNode(root, "textinput");
      if (input && !getNode(input, "link")) {
         input = root.getElementsByTagName("textinput")[1];
      }
      if (input) {
         ref = rss.input = {};
         ref.link = getText(getNode(input, "link"));
         ref.description = getText(getNode(input, "description"));
         ref.name = getText(getNode(input, "name"));
         ref.title = getText(getNode(input, "title"));
      }
   } else {
      rss.date = renderDate(getText(getNode(channel, "lastBuildDate") || getText(getNode(channel, "pubDate"))) || data.modified);
      rss.rights = getText(getNode(channel, "copyright"));
   }
   
   var item, text, node;
   var items = xml.getElementsByTagName("item");

   for (var i=0; i<Math.min(items.length, param.maxItems); i+=1) {
      item = items[i];

      if (type === "scriptingNews") {
         ref = {title: ""};
         ref.description = getText(getNode(item, "text")).replace(/\n/g, " ");
         ref.link = getText(getNode(item, "link"));
         if (text = trim(getText(getNode(item, "linetext")).replace(/\n/g, " "))) {
            ref.description = ref.description.replace(new RegExp(text), 
                  '<a href="' + getText(getNode(item, "url")) + '">' + text + '</a>');
         }
      } else {
         ref = {
            title: getText(getNode(item, "title")),
            description: getText(getNode(item, "description")),
            link: getText(getNode(item, "link") || getNode(item, "guid"))
         };
     }

     if (node = getNode(item, "source")) {
        ref.source = {
           link: node.getAttribute("url"),
           title: getText(node)
        }
     }
     
     if (node = getNode(item, "enclosure")) {
        ref.enclosure = {
           link: node.getAttribute("url"),
           length: node.getAttribute("length"),
           type: node.getAttribute("type")
        }
     }
     
     if (node = getNode(item, "category")) {
        ref.category = {
           domain: node.getAttribute("domain") || "",
           content: getText(node)
        }
     }
     
     rss.items.push(ref);
   }
   
   var item, items = "";
   for (var i=0; i<rss.items.length; i+=1) {
      item = rss.items[i];
      items += render(data.item, {
         title: new function() {
            var title = (!param.compact ? "<strong>" : "");
            if (item.link) {
               title += render(data.link, {
                  link: encodeURI(item.link),
                  text: item.title,
                  'class': "rssBoxItemTitle"
               });
            } else {
               title += item.title;
            }
            !param.compact && (title += "</strong>");
            return new String(title); // FIXME: Funny, title alone will be rendered as [object]
         }(),
         'break': item.title && item.description ? "<br />" : "",
         description: (!param.compact || !item.title) && item.description,
         buttons: renderButtons(item.enclosure, item.source)
      });
   }
   
   var box = render(data.box, {
      title: rss.link ? render(data.link, {
         link: encodeURI(rss.link),
         text: rss.title,
         'class': "rssBoxTitle",
         style: "color: " + param.titleBarTextColor
      }) : rss.title,
      description: rss.description,
      items: items,

      xmlButton: param.showXmlButton && render(data.image, {
         link: param.url,
         source: baseUri + "rss.png",
         title: rss.format + " " + rss.version,
         width: 16,
         height: 16,
         align: "right",
         hspace: 3
      }),
      
      image: !param.compact && rss.image && render(data.image, {
         link: encodeURI(rss.image.link),
         source: rss.image.source,
         width: rss.image.width,
         height: rss.image.height,
         title: rss.image.title,
         align: "right",
         valign: "baseline",
         hspace: 5,
         vspace: 5
      }),
      
      input: !param.compact && rss.input && render(data.input, {
         link: encodeURI(rss.input.link),
         description: rss.input.description,
         name: rss.input.name,
         title: rss.input.title
      }),
      
      date: rss.date,
      width: param.width,
      frameColor: param.frameColor,
      fontFace: param.fontFace,
      align: param.align,
      titleBarColor: param.titleBarColor,
      titleBarTextColor: param.titleBarTextColor,
      boxFillColor: param.boxFillColor,
      textColor: param.textColor
   });

   if (!window.rssBoxSetup) {
      document.write(box);
   }
   
   return box;
};

org.p3k.RssBox();

