<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-29787727</id><updated>2011-12-31T12:21:48.346-05:00</updated><category term='correctness'/><category term='plug-ins'/><category term='xsl'/><category term='tools'/><category term='ironpython'/><category term='funny'/><category term='apple'/><category term='unit'/><category term='meta-blogging'/><category term='verdana'/><category term='chrome'/><category term='firefox'/><category term='dell'/><category term='test'/><category term='announcement'/><category term='job'/><category term='minimum'/><category term='python'/><category term='testoriented'/><category term='egg'/><category term='wedgie'/><category term='.net'/><category term='tv'/><category term='eclipse'/><category term='usability'/><category term='scripts'/><category term='laptop'/><category term='hardware'/><category term='code review'/><category term='ie9'/><category term='xml'/><category term='vs'/><category term='meme'/><category term='router'/><category term='business'/><category term='oss'/><category term='extensions'/><category term='platform'/><category term='1625'/><category term='java'/><category term='olpc'/><category term='howto'/><category term='programming'/><category term='shameless plug'/><category term='experience'/><category term='work ethic'/><category term='size'/><category term='xo'/><category term='school'/><category term='font'/><category term='networking'/><category term='william shatner'/><category term='C#'/><category term='NAT'/><category term='ironpython studio'/><category term='add-ons'/><category term='software'/><category term='microsoft'/><category term='design'/><category term='elegance'/><category term='chicken'/><category term='annoying'/><category term='error'/><category term='svn'/><category term='vs registry editor'/><title type='text'>public class Oli : ICool</title><subtitle type='html'>The life story of some guy who eats software engineering for breakfast.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>55</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-29787727.post-1709335716896473634</id><published>2011-12-27T22:03:00.004-05:00</published><updated>2011-12-31T12:19:11.022-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dell'/><category scheme='http://www.blogger.com/atom/ns#' term='wedgie'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='experience'/><title type='text'>Dell could not get your question</title><content type='html'>Dell has some "Windows 7 - Boxing Week Laptop &amp;amp; Desktop Deals", so I decided to check out their website.  Having used a Dell laptop recently, I remembered the lack of a "Menu key", so after poking around for a bit, this "chat with us" window started to scroll annoyingly in the way, so I thought I'd take advantage of it.  This is what happened next:&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" id="chattable" style="background-color: white; color: black; font-size: 12px; line-height: 13px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:17:51&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="System" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/system1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;System&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="systemtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-style: italic; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;&lt;a class="link" href="https://chatadengine.dell.com/chatadsengine/adengine/Default.aspx?Queue=046EE964-74E2-4918-8189-BACB2860C354" style="color: darkmagenta;" target="PushFrame"&gt;https://chatadengine.dell.com/chatadsengine/adengine/Default.aspx?Queue=046EE964-74E2-4918-8189-BACB2860C354&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:20:29&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="System" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/system1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;System&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="systemtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-style: italic; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;You are now being connected to an agent. Thank you for using Dell Chat&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:20:29&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="System" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/system1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr systemtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;System&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="systemtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-style: italic; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Connected with Gowrishankar G&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:20:29&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Welcome to Dell Canada Sales Chat! I hope you are doing well and thank you for waiting. My name is Gowrishankar (Extn:4161496) I will be your online Product advisor.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:20:34&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Gowrishankar G pushes page,&amp;nbsp;&lt;a class="link" href="http://www1.ca.dell.com/content/topics/reftopic.aspx/gen/en/setrepcode?c=ca&amp;amp;l=en&amp;amp;s=dhs&amp;amp;rep_id=4161496&amp;amp;rep_type=CHAT&amp;amp;redirect_url=http%3A//accessories.dell.com/sna/category.aspx%3Fc%3Dca%26category_id%3D5914%26cs%3Dcadhs1%26l%3Den%26navla%3D455%7E0%7E6018%26nf%3D455%7E0%7E6018%26s%3Ddhs%26%7Eck%3Danav" style="color: darkmagenta;" target="PushFrame"&gt;http://www1.ca.dell.com/content/topics/reftopic.aspx/gen/en/setrepcode?c=ca&amp;amp;l=en&amp;amp;s=dhs&amp;amp;rep_id=4161496&amp;amp;rep_type=CHAT&amp;amp;redirect_url=http%3A//accessories.dell.com/sna/category.aspx%3Fc%3Dca%26category_id%3D5914%26cs%3Dcadhs1%26l%3Den%26navla%3D455%7E0%7E6018%26nf%3D455%7E0%7E6018%26s%3Ddhs%26%7Eck%3Danav&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:20:49&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;hello Olivier&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:21:09&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Your link didn't work.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:21:45&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Not a problem&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:21:57&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Great! Glad you chatted in today. How can I help you today with the purchase&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:22:14&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Anyway, I would like to know if there is a page with pictures of all the available keyboard layouts for 17" laptops.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:22:34&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;I was looking at this:&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:22:35&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;&lt;a class="link" href="http://www.dell.com/ca/p/xps-l702x/pd?oc=nxps172_win_3e&amp;amp;model_id=xps-l702x" style="color: darkmagenta;" target="PushFrame"&gt;http://www.dell.com/ca/p/xps-l702x/pd?oc=nxps172_win_3e&amp;amp;model_id=xps-l702x&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:22:47&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;There's a picture of the keyboard on the right I can zoom into.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:22:53&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;I don't like that layout.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:23:09&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Give me a moment&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:23:13&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Sure.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:26:29&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Gowrishankar G pushes page,&amp;nbsp;&lt;a class="link" href="http://www.dell.com/ca/p/xps-l702x/pd?c=ca&amp;amp;cs=cadhs1&amp;amp;l=en&amp;amp;s=dhs&amp;amp;~ck=mn" style="color: darkmagenta;" target="PushFrame"&gt;http://www.dell.com/ca/p/xps-l702x/pd?c=ca&amp;amp;cs=cadhs1&amp;amp;l=en&amp;amp;s=dhs&amp;amp;~ck=mn&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:26:39&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;You can open the link and click on gallery&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:27:44&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;That's the same page I was at.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:27:56&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Where can I see the other available keyboard layouts?&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:28:15&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;you have to click on gallery&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:28:36&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;I did.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:28:42&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;There is only one picture of a keyboard there.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:30:47&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;did you find the option gallery&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:31:33&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Yes.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:31:39&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;It is not what I was looking for.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:32:48&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;okay&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:33:23&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/Menu_key" style="color: darkmagenta;" target="PushFrame"&gt;https://en.wikipedia.org/wiki/Menu_key&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:33:32&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;I am looking for a laptop keyboard that has the "Menu key"&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:33:48&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;It is usually to the right of the space bar, between Alt and Ctrl.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:35:44&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;could not get your question&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:36:41&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Does Dell make any laptops with the "Menu key" to the right of the space bar?&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:38:45&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;No we don't have the "Menu key"&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:38:54&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Customer" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/user1.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr custtext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Olivier Dagenais&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="custtext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Thank you. That is all.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="time" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook';"&gt;21:39:40&amp;nbsp;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="icon" style="vertical-align: middle; width: 16px;"&gt;&lt;img alt="Agent" src="https://chat6.us.dell.com/netagent/client/unified/classic/imgs/agent.png" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td class="brdr agenttext1" nowrap="" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(128, 255, 128); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(255, 255, 255); border-top-style: solid; border-top-width: 1px; font-weight: bold; margin-left: 6px; margin-right: 6px;"&gt;&amp;nbsp;&lt;span class="name" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-left: 2px;"&gt;Gowrishankar G&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&lt;td id="msgid" style="width: 560px;"&gt;&lt;div class="agenttext2" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-color: rgb(255, 255, 255); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; color: #0066cc; font-weight: bold; margin-bottom: 2px;"&gt;&lt;span class="text" style="font: normal normal normal 8pt/1.3 Tahoma, Arial, 'Times New Roman', 'Century Schoolbook'; margin-bottom: 1px; margin-left: 1px; margin-right: 1px; margin-top: 1px;"&gt;Thank you very much for your time&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;I keep poking around and notice that if you click &lt;b&gt;Customize&lt;/b&gt;, you eventually get to pick your keyboard! &amp;nbsp;Great, let's see what my options are:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" style="background-color: white;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="left" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="98%"&gt;&lt;b&gt;&lt;div id="mh_4"&gt;&lt;br class="Apple-interchange-newline" /&gt;Keyboard&lt;/div&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Arial; font-size: xx-small;"&gt;&lt;span style="font-size: x-small;"&gt;Multi-task any time of the day or night with a backlit keyboard.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial; font-size: xx-small;"&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="2" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td height="4px" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="Top" width=""&gt;&lt;img border="0" height="4px" src="http://i.dell.com/images/global/configurator/general/spacer.gif" width="" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="left"&gt;&lt;td align="left" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;table cellpadding="0" cellspacing="0" class="Mod_Selector_table_notselected" style="border-bottom-color: rgb(178, 178, 178); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(178, 178, 178); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(178, 178, 178); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(178, 178, 178); border-top-style: solid; border-top-width: 1px; cursor: pointer; height: 20px; margin-bottom: 0px; width: 592px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td height="25" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;img border="0" height="25" id="mod_selector_left_4" margin="0" src="http://i.dell.com/images/global/configurator/general/bevel_notselected.gif" width="10" /&gt;&lt;/td&gt;&lt;td align="left" class="Mod_Selector_cell_middle_notselected" height="25" id="mod_selector_middle_4" style="background-image: url(http://i.dell.com/images/global/configurator/general/bg_notselected.gif); cursor: pointer; font-family: arial, helvetica; font-size: 9pt; height: 20px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 554px;" valign="middle"&gt;&lt;a href="" id="m_4" name="m_4" style="color: #0066cc; font-family: arial, helvetica; text-decoration: none;"&gt;&lt;/a&gt;&lt;div class="Mod_Selection" id="mhd_m_4" name="mhd_m_4" style="cursor: default; font-family: Arial; font-size: 13px; font-weight: bold; margin-left: 5px;"&gt;Standard Keyboard - English&lt;/div&gt;&lt;/td&gt;&lt;td align="right" alt="View Options" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;img border="0" height="25" id="mod_selector_right_4" margin="0" src="http://i.dell.com/images/global/configurator/general/collapse_notselected.gif" width="28" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;table border="0" cellpadding="0" cellspacing="0" class="option_display_visible" id="module_options_4" style="border-bottom-color: rgb(178, 178, 178); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(178, 178, 178); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(178, 178, 178); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(178, 178, 178); border-top-style: solid; border-top-width: 1px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="middle" width="22"&gt;&lt;a class="lnk_iconic" href="http://configure.dell.com/dellstore/config.aspx?oc=nxps172_win_3e&amp;amp;c=ca&amp;amp;l=en&amp;amp;s=dhs&amp;amp;cs=cadhs1&amp;amp;model_id=xps-l702x" style="color: #245493; font-family: arial, helvetica; font-size: 9pt; text-decoration: none;"&gt;&lt;img alt="Learn More" border="0" height="17" src="http://i.dell.com/images/global/brand/icons/help.gif" width="17" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td align="left" nowrap="true" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="middle"&gt;&lt;a class="lnk_iconic" href="http://configure.dell.com/dellstore/config.aspx?oc=nxps172_win_3e&amp;amp;c=ca&amp;amp;l=en&amp;amp;s=dhs&amp;amp;cs=cadhs1&amp;amp;model_id=xps-l702x" style="color: #245493; font-family: arial, helvetica; font-size: 9pt; text-decoration: none;"&gt;Help Me Choose&amp;nbsp;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;img height="1" src="http://i.dell.com/images/global/configurator/general/linebr.gif" width="100%" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr id="tr_m_4:STKYBDE"&gt;&lt;td height="1" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="Top" width="1"&gt;&lt;img border="0" height="1" src="http://i.dell.com/images/global/configurator/general/spacer.gif" width="1" /&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;table border="0" cellpadding="0" cellspacing="0" id="t_m_4:STKYBDE" name="t_m_4:STKYBDE"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td height="1" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="Top" width="9"&gt;&lt;img border="0" height="1" src="http://i.dell.com/images/global/configurator/general/spacer.gif" width="9" /&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="top"&gt;&lt;a href="" id="m_4:STKYBDE" name="m_4:STKYBDE" style="color: #0066cc; font-family: arial, helvetica; text-decoration: none;"&gt;&lt;/a&gt;&lt;input checked="" id="m_4" name="m_4" type="radio" value="STKYBDE" /&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; line-height: 2; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;div&gt;&lt;span style="font-family: arial; font-size: xx-small;"&gt;Standard Keyboard - English&amp;nbsp;&lt;span id="op_m_4:STKYBDE" name="op_m_4:STKYBDE"&gt;[Included&amp;nbsp;in&amp;nbsp;Price]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="tr_m_4:BCKLITE"&gt;&lt;td height="1" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="Top" width="1"&gt;&lt;img border="0" height="1" src="http://i.dell.com/images/global/configurator/general/spacer.gif" width="1" /&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;table border="0" cellpadding="0" cellspacing="0" id="t_m_4:BCKLITE" name="t_m_4:BCKLITE"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td height="1" style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="Top" width="9"&gt;&lt;img border="0" height="1" src="http://i.dell.com/images/global/configurator/general/spacer.gif" width="9" /&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" valign="top"&gt;&lt;a href="" id="m_4:BCKLITE" name="m_4:BCKLITE" style="color: #0066cc; font-family: arial, helvetica; text-decoration: none;"&gt;&lt;/a&gt;&lt;input id="m_4" name="m_4" type="radio" value="BCKLITE" /&gt;&lt;/td&gt;&lt;td style="font-family: arial, helvetica; font-size: 9pt; line-height: 2; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" width="100%"&gt;&lt;div&gt;&lt;span style="font-family: arial; font-size: xx-small;"&gt;Backlit Keyboard - English&amp;nbsp;&lt;span id="op_m_4:BCKLITE" name="op_m_4:BCKLITE"&gt;[add&amp;nbsp;$25.00&amp;nbsp;or&amp;nbsp;$1.00/month&lt;sup&gt;1&lt;/sup&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Bummer.  I guess I'm out of luck if I wanted the bilingual keyboard that I'm seeing in stores everywhere these days (and I certainly do not! &amp;nbsp;I want a US English keyboard layout like my old &lt;a href="http://www.notebookreview.com/assets/11170.jpg"&gt;HP Pavilion dv8000&lt;/a&gt;.).&lt;br /&gt;&lt;br /&gt;At this stage, even if Dell laptops somehow eventually &lt;b&gt;do&lt;/b&gt; get a "Menu key", I'm not convinced I want to support an organization that hires "sales people" that can't understand English.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE:&lt;/b&gt;I found that HP's website contains manuals for its laptop series, including lists of part numbers for replacement keyboards, by language, as well as instructions for removing and replacing keyboards.  This is great if all you can find is a laptop with a French-Canadian keyboard; you can replace it after the purchase.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE 2:&lt;/b&gt;I ended up ordering a refurbished HP laptop that already has a US English keyboard.  It doesn't have the inverted T arrow keys, but I don't use those as often...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1709335716896473634?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1709335716896473634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1709335716896473634' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1709335716896473634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1709335716896473634'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2011/12/dell-could-not-get-your-question.html' title='Dell could not get your question'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-65693374848508241</id><published>2011-05-21T18:22:00.001-04:00</published><updated>2011-05-21T18:22:42.237-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>So you have a business idea...</title><content type='html'>&lt;p&gt;A friend of a friend has asked me to comment on a software business idea from a technical standpoint; if the proposed user story can be implemented, how much it would cost and if there already exists something similar that could be customized.&lt;/p&gt;  &lt;p&gt;Instead of responding directly, I thought I would &lt;a href="http://www.hanselman.com/blog/DoTheyDeserveTheGiftOfYourKeystrokes.aspx"&gt;conserve my keystrokes&lt;/a&gt; and blog about it, first answering the technical questions and secondly providing business suggestions.&amp;#160; I might not be a business expert, but I do play one on &lt;strike&gt;TV&lt;/strike&gt; the internet through my &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Observational_learning"&gt;vicarious learning&lt;/a&gt; from reading [articles linked from] &lt;a href="http://news.ycombinator.com/"&gt;Hacker News&lt;/a&gt; as well as blogs such as &lt;a href="http://www.joelonsoftware.com/"&gt;Joel On Software&lt;/a&gt;, &lt;a href="http://www.softwarebyrob.com/"&gt;Software by Rob&lt;/a&gt;, &lt;a href="http://businessofsoftware.org/"&gt;Business of Software&lt;/a&gt; and &lt;a href="http://blogs.balsamiq.com/product/"&gt;Balsamiq Mockups&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;The technical side of things&lt;/h1&gt;  &lt;p&gt;The idea is generally about internet video integration.&lt;/p&gt;  &lt;h2&gt;Can it be done?&lt;/h2&gt;  &lt;p&gt;The software to implement the idea is certainly possible (most ideas are, for a price!).&amp;#160; While I haven't built something exactly like what is described, I have worked on web applications before and nothing jumps out as difficult, aside from the video part.&lt;/p&gt;  &lt;p&gt;The video part sounds slightly scary because video files can be big, which makes the storage and transmission costs significant (compared to the ongoing costs of the rest of the application).&amp;#160; A few years ago, you would have had to worry about designing (and building!) a system to store all those files, receiving and sending them quickly across the internet, but nowadays, you can save on infrastructure costs by using &lt;a href="http://aws.amazon.com/"&gt;Amazon Web Services (AWS)&lt;/a&gt;, which is pretty neat because you only pay for what you use.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;How much would it cost?&lt;/h2&gt;  &lt;p&gt;A lot of it depends on the sophistication, which really boils down to the number and complexity of features.&amp;#160; It would be a matter of establishing priorities and deciding on a time box to work in, after which the software would be released to the first batch of potential customers for feedback.&amp;#160; Depending on how well that goes, the project could then be &lt;a href="http://www.amazon.com/Winning-New-Products-Accelerating-Process/dp/0738204633"&gt;killed&lt;/a&gt;, &lt;a href="http://www.gabrielweinberg.com/blog/2010/05/to-pivot-or-not-to-pivot.html"&gt;pivoted&lt;/a&gt; or &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Release_early%2C_release_often"&gt;evolved&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.softwarebyrob.com/2008/10/03/should-you-build-or-buy-your-micro-isv/"&gt;Rob Walling suggests&lt;/a&gt; a time frame of 2 months, which he estimates would cost about $40 000 if he did everything himself (based on his consulting rate) and between $8 000 and $27 000 if he hired out the work, depending on the cost of living where the work is done.&amp;#160; That's just to build the software and the website.&lt;/p&gt;  &lt;p&gt;I mentioned that video would add a noticeable cost for &lt;a href="http://aws.amazon.com/s3/pricing/"&gt;storage&lt;/a&gt; and &lt;a href="http://aws.amazon.com/cloudfront/pricing/"&gt;transmission&lt;/a&gt;, but that depends on the number of videos, their quality, their length and how often they are accessed.&amp;#160; If estimates can be provided for these factors, some numbers can then be plugged in to the &lt;a href="http://calculator.s3.amazonaws.com/calc5.html"&gt;AWS calculator&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Let's play along with this &lt;a href="http://www.youtube.com/watch?v=KmtzQCSh6xk"&gt;sample video&lt;/a&gt;: it is 1:40 long and clocks in at 6.61 megabytes (MB) (the YouTube page it is on is estimated at 1.12 MB, although that's only if you have never been to YouTube before - the cache will avoid the re-transmission of almost 1 MB).&amp;#160; YouTube calls this quality level &amp;quot;360p&amp;quot;; the video was resized (by YouTube) to 480x368.&amp;#160; Let's say a typical user would view 10 videos like this one every week and let's say you have 1000 active users doing that.&amp;#160; That gives us 6.61 * 10 * 1000 = 66 100 MB ~= 66 GB/week.&amp;#160; Let's assume you have 10 000 such video files to choose from, so that's 10 000 * 6.61 MB ~= 66 GB of storage.&amp;#160; I plugged those into the S3 and CloudFront calculators and came up with a monthly bill of $91.34.&amp;#160; That's not bad at all (almost downright cheap!), but remember that's &lt;em&gt;just&lt;/em&gt; to store and transmit video you &lt;em&gt;already have&lt;/em&gt; for 10 000 views/week (a similar exercise would have to be performed for uploading videos - it costs more to upload).&amp;#160; The hosting costs for the rest of the website (i.e. the parts around the video) would likely be much less, but that depends on the features and the technologies involved (i.e. do you want to resize the uploaded videos, too?).&lt;/p&gt;  &lt;p&gt;Lastly, there are costs around supporting and evolving the software.&amp;#160; Unfortunately, while the first might be stable, the second one is most certainly a race against your competitors, otherwise you might lose customers to the shiny new stuff the other guys added.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Is there a package that can be customized or adapted?&lt;/h2&gt;  &lt;p&gt;That part, I don't know.&amp;#160; This would require a decent amount of searching and evaluation.&amp;#160; If there is something out there, then the customizations done to it better be extensive, otherwise anybody else can come along and copy you.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;The business side of things&lt;/h1&gt;  &lt;p&gt;I figured I would provide a lot of information on the business side because I was afraid the idea could be easily copied by one of the existing players, making for a &lt;em&gt;very&lt;/em&gt; rough start.&lt;/p&gt;  &lt;h2&gt;How good is the idea?&lt;/h2&gt;  &lt;p&gt;Is the idea &lt;a href="http://www.joelonsoftware.com/items/2007/12/06.html"&gt;solving a gnarly problem&lt;/a&gt; or is it low-hanging fruit that a bigger company could simply copy?&amp;#160; Are you creating value for your users or &lt;a href="http://www.joelonsoftware.com/articles/fog0000000037.html"&gt;introducing a Rube Goldberg way of doing things&lt;/a&gt;?&amp;#160; If you are trying to compete with an existing player, &lt;a href="http://www.codinghorror.com/blog/2004/11/youll-never-have-enough-cheese.html"&gt;are you at least making the cheese bigger or reducing the electric shocks&lt;/a&gt;?&amp;#160; What market are you targeting and &lt;a href="http://www.kalzumeus.com/2011/03/26/software-for-underserved-markets/"&gt;should you target another one entirely&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;The idea sounds good to you, but have you tried asking your friends?&amp;#160; (oh, right!)&amp;#160; What about potential customers?&amp;#160; &lt;a href="http://www.johnchow.com/the-secret-to-success-case-study-solve-a-problem-and-build-something-you-would-use/"&gt;Is it something you would use&lt;/a&gt;?&amp;#160; If it already existed, would YOU pay for it?&amp;#160; The &lt;a href="http://www.startupbook.net/"&gt;Start Small, Stay Small&lt;/a&gt; book recommends testing the waters by creating a &amp;quot;coming soon&amp;quot; website that talks about and/or shows a preview of the idea and gives visitors the opportunity to provide their e-mail address to be notified of the release.&amp;#160; This is great because you either end up with a great list of leads or confirmation that people aren't even willing to give you their e-mail address.&lt;/p&gt;  &lt;p&gt;Don't worry too much about the idea, though:&amp;#160; &lt;a href="http://joel.is/post/5507881155/how-to-start-your-startup-in-4-steps"&gt;You might find that the idea changes or evolves as you get feedback&lt;/a&gt; or, better yet, customers!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;How will the idea spread?&lt;/h2&gt;  &lt;p&gt;What kind of &lt;a href="http://blog.fogcreek.com/the-very-most-basic-things-your-company-needs-to-know-about-sales-part-1-of-4/"&gt;sales &amp;amp; marketing&lt;/a&gt; are you planning?&amp;#160; Is the value of the idea &lt;a href="http://www.joelonsoftware.com/articles/fog0000000054.html"&gt;dependent on how many users you have&lt;/a&gt;?&amp;#160; This is called the &lt;a href="http://en.wikipedia.org/wiki/Network_effect"&gt;Network effect&lt;/a&gt; and you have to consider &lt;a href="http://news.ycombinator.com/item?id=1804583"&gt;how you will attract users&lt;/a&gt; regardless; the best case scenario is the idea is so awesome that users can't help but tell all their friends about it (i.e. &amp;quot;go viral&amp;quot;).&amp;#160; One trending idea is to encourage (and sometimes force!) the word-of-mouth by broadcasting to social networks use of the product or service (such as &amp;quot;I just started playing &lt;em&gt;Super Cabbage Town&lt;/em&gt;&amp;quot;) or - even better - achievements (such as &amp;quot;I just jogged 5 km with the help of &lt;em&gt;Jogz Pro&lt;/em&gt;&amp;quot;).&lt;/p&gt;  &lt;p&gt;If the idea requires users have an account, &lt;a href="http://www.jwz.org/doc/groupware.html"&gt;unless your idea has a seriously big cheese&lt;/a&gt;, sign-ups will be difficult, because &lt;span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; border-collapse: separate; font: medium &amp;#39;Times New Roman&amp;#39;; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"&gt;&lt;span style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 16px" class="Apple-style-span"&gt;&lt;a href="http://www.snpp.com/episodes/BABF01"&gt;for glaven out loud&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;, I don't want to have to remember yet another user name and password unless it's really worth it.&amp;#160; Thankfully, your service could probably piggy-back on top of Facebook Connect or &lt;a href="http://openid.net/"&gt;OpenID&lt;/a&gt;, the former giving you the aforementioned ability to &lt;strike&gt;spam&lt;/strike&gt; inform friends and family.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;How will you make money?&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.joelonsoftware.com/items/2004/10/26.html"&gt;Don't try to compete on price&lt;/a&gt; - especially if you copy a competitor - because you'll always be playing catch-up as they add new features (unless you enjoy that sort of thing or are somehow able to add features faster than they can).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://adage.com/article/digitalnext/social-media-engaging-good/226848/"&gt;Ads don't work if users are too engaged&lt;/a&gt;. There might be &lt;a href="http://webupon.com/social-networks/why-facebook-ads-dont-sell/"&gt;ways of making Facebook ads better&lt;/a&gt; but then again, &lt;a href="http://www.jperla.com/blog/post/facebook-is-a-ponzi-scheme"&gt;is Facebook a Ponzi Scheme&lt;/a&gt;?&amp;#160; Users will be &lt;a href="http://psoug.org/blogs/mike/2010/10/21/if-you-arent-paying-for-the-product-you-are-the-product/"&gt;paying for the product or service one way or another&lt;/a&gt;, you just have to decide on one or more of the following options:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;displaying ads&lt;/li&gt;    &lt;li&gt;selling user information, usage patterns, etc.&lt;/li&gt;    &lt;li&gt;have users pay first; lump sum, payment plan or subscription?&lt;/li&gt;    &lt;li&gt;&amp;quot;freenium&amp;quot; (offering free &amp;amp; premium versions, although &lt;a href="http://www.softwarebyrob.com/2010/08/18/why-free-plans-dont-work/"&gt;freenium doesn't always work&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;upselling (upgrades, add-ons, &lt;a href="http://www.joelonsoftware.com/articles/StrategyLetterV.html"&gt;complements&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.joelonsoftware.com/articles/CamelsandRubberDuckies.html"&gt;Pricing isn't easy, either&lt;/a&gt;.&amp;#160; Here's another point-of-view on the topic in the form of a &lt;em&gt;free(!)&lt;/em&gt; e-book called &lt;a href="http://www.neildavidson.com/dontjustrollthedice.html"&gt;Don't Just Roll the Dice&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;h2&gt;Shit happens&lt;/h2&gt;  &lt;p&gt;Sometimes you have an idea and &lt;a href="http://mercurygrove.com/2008/11/dex-hits-hard-times-delays-and-legal-troubles/"&gt;then evil corporate lawyers show up&lt;/a&gt;.&amp;#160; As a new and small business, you have the advantage of agility and &lt;a href="http://mercurygrove.com/2009/04/new-name-for-dex-networkhippo/"&gt;can adjust to something like that&lt;/a&gt;.&amp;#160; Speaking of &lt;a href="http://networkhippo.com/"&gt;Network Hippo&lt;/a&gt;, these guys have a way of reducing the &amp;quot;switching cost&amp;quot; (i.e. reducing the electric shocks) by importing your contact list from your LinkedIn network.&amp;#160; Facebook offers to do the same thing with their Friend Finder that scans your e-mail accounts.&amp;#160; Is there something you can do to make it easier for people to get started with your product or service?&amp;#160; &lt;strike&gt;If&lt;/strike&gt; When a competitor implements a similar &amp;quot;smooth transition&amp;quot; to their product or service (from yours!), will you have enough value to encourage your users to stay?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Closing links&lt;/h1&gt;  &lt;p&gt;&lt;a href="http://www.forbes.com/forbes/2010/1108/best-small-companies-10-y-combinator-paul-graham-ask-an-expert.html"&gt;Determination is key&lt;/a&gt;.&amp;#160; &lt;a href="http://www.inc.com/rob-adams/2010/06/ideas-commodity-but-execution-intelligence-matters.html"&gt;Execution is what matters.&lt;/a&gt;&amp;#160; &lt;a href="http://www.softwarebyrob.com/2009/11/19/passion-as-a-competitive-advantage/"&gt;Passion can be a competitive advantage.&lt;/a&gt;&amp;#160; &lt;a href="http://tom.preston-werner.com/2008/10/18/how-i-turned-down-300k?print"&gt;Channel your inner Leeroy Jenkins.&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-65693374848508241?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/65693374848508241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=65693374848508241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/65693374848508241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/65693374848508241'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2011/05/so-you-have-business-idea.html' title='So you have a business idea...'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-3653281254510815999</id><published>2011-04-19T22:13:00.000-04:00</published><updated>2011-04-19T22:13:19.954-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vs'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>I see you!</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" height="102" src="http://2.bp.blogspot.com/-bY9B6fLS7v4/Ta5AHcYM6_I/AAAAAAAAAIU/qwO_vTbAi4E/s400/Help%2BLibrary%2BAgent%2BInvisible%2BWindow.png" title="Help Library Agent Invisible Window" width="311" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-3653281254510815999?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/3653281254510815999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=3653281254510815999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3653281254510815999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3653281254510815999'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2011/04/i-see-you.html' title='I see you!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-bY9B6fLS7v4/Ta5AHcYM6_I/AAAAAAAAAIU/qwO_vTbAi4E/s72-c/Help%2BLibrary%2BAgent%2BInvisible%2BWindow.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8770969669746784745</id><published>2011-03-20T12:10:00.001-04:00</published><updated>2011-03-20T12:10:48.741-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='font'/><category scheme='http://www.blogger.com/atom/ns#' term='wedgie'/><category scheme='http://www.blogger.com/atom/ns#' term='ie9'/><category scheme='http://www.blogger.com/atom/ns#' term='verdana'/><title type='text'>Hacking IE9's font smoothing</title><content type='html'>&lt;p&gt;If you have been following my blog for a bit, you know &lt;a href="http://oliiscool.blogspot.com/2008/09/world-in-verdana.html"&gt;I am quite set on my web browser's content readability&lt;/a&gt;.&amp;#160; Well, it happened again with Internet Explorer 9 and this time, my font of choice was there but &lt;strong&gt;it was rendered with ClearType &lt;em&gt;even though I turned it off with the ClearType Text Tuner&lt;/em&gt;&lt;/strong&gt;:&lt;a href="http://lh5.ggpht.com/_QvEDZGglpqE/TYYnA4bXoHI/AAAAAAAAAIM/i6Gcbunezys/s1600-h/ClearType%20Text%20Tuner%20is%20clearly%20off%5B4%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="ClearType Text Tuner is clearly off" border="0" alt="ClearType Text Tuner is clearly off" src="http://lh3.ggpht.com/_QvEDZGglpqE/TYYnBU9jxzI/AAAAAAAAAIQ/J35IbktFPAE/ClearType%20Text%20Tuner%20is%20clearly%20off_thumb%5B2%5D.png?imgmax=800" width="792" height="562" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;See?&amp;#160; It's &lt;em&gt;clearly&lt;/em&gt;&amp;#160;&lt;strong&gt;off&lt;/strong&gt;, but noooo, someone's feeling waaaay too important to follow the operating system's settings.&lt;/p&gt;  &lt;p&gt;Anyway, after &lt;a href="http://blog.softwareninjas.ca/2011/03/how-to-take-control-of-internet.html"&gt;a Wednesday afternoon of mad hacking&lt;/a&gt; (followed by a Saturday afternoon of fixing and cleaning), the result is the &lt;a href="http://www.softwareninjas.ca/dwrite-dll-wrapper"&gt;DWrite.dll wrapper&lt;/a&gt;, which is available for free download.&lt;/p&gt;  &lt;p&gt;I just hope this doesn't turn into &lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2011/03/10/10138969.aspx"&gt;a game of walls and ladders&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8770969669746784745?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8770969669746784745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8770969669746784745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8770969669746784745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8770969669746784745'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2011/03/hacking-ie9-font-smoothing.html' title='Hacking IE9&amp;#39;s font smoothing'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_QvEDZGglpqE/TYYnBU9jxzI/AAAAAAAAAIQ/J35IbktFPAE/s72-c/ClearType%20Text%20Tuner%20is%20clearly%20off_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-3700984294500317106</id><published>2010-09-24T11:47:00.000-04:00</published><updated>2010-09-24T11:50:33.221-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Console2 and Altap Salamander: together at last!</title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p&gt;Not unlike &lt;a title="Homer: I&amp;#39;m a white male, age 18 to 49.  Everyone listens to me -- no matter how dumb my suggestions are. {[pulls out a &amp;#39;nuts and gum - together at last&amp;#39; mixture, starts chomping]}" href="http://www.snpp.com/episodes/1F12.html"&gt;Nuts and gum&lt;/a&gt;, I wanted &lt;a href="http://altap.cz/salam_en/index.html"&gt;Altap Salamander&lt;/a&gt; to play nice with &lt;a href="http://sourceforge.net/projects/console/"&gt;Console2&lt;/a&gt; by having the former launch the latter whenever I hit the &lt;tt&gt;/&lt;/tt&gt; key above the numeric keypad. Console2 is awesome: it supports using &lt;i&gt;Courier New&lt;/i&gt; as a font, has much more natural text selection, features copy &amp;amp; paste keyboard shortcuts, etc.&lt;/p&gt;  &lt;h2&gt;The problem&lt;/h2&gt;  &lt;p&gt;I used to connect the two together by &lt;a href="http://forum.altap.cz/viewtopic.php?f=3&amp;amp;t=1957&amp;amp;p=20575&amp;amp;hilit=comspec"&gt;launching Salamander with a batch file that would override the &lt;tt&gt;COMSPEC&lt;/tt&gt; environment variable&lt;/a&gt; to point to Console2, which mostly worked, until a process launched by Salamander itself would try to use a shell. It turns out &lt;a href="http://community.activestate.com/forum/solved-changing-default-console-cmdexe-console2#comment-11144"&gt;Console2 is NOT a shell&lt;/a&gt; and thus I would often get really weird behaviour out of those programs.&lt;/p&gt;  &lt;h2&gt;The solution, part 1&lt;/h2&gt;  &lt;p&gt;It turns out an &lt;i&gt;Automation&lt;/i&gt; plug-in now exists for Salamander. Using it, I wrote the following quick script, adapted from the &lt;tt&gt;Launch Elevated Command Prompt.vbs&lt;/tt&gt; sample script: &lt;/p&gt;  &lt;pre&gt;Set ShellApp = CreateObject(&amp;quot;Shell.Application&amp;quot;)&lt;br /&gt;ShellApp.ShellExecute &amp;quot;E:\Program Files (x86)\Altap Salamander 2.54\Console2\Console.exe&amp;quot;, &amp;quot;-d &amp;quot;&amp;quot;&amp;quot; &amp;amp; Salamander.SourcePanel.Path &amp;amp; &amp;quot;&amp;quot;&amp;quot;&amp;quot;, &amp;quot;&amp;quot;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The &lt;i&gt;Plugins Manager&lt;/i&gt; allows me to bind keyboard shortcuts to individual scripts, so I selected &lt;tt&gt;Alt+-&lt;/tt&gt; since just about everything else was taken and you can't use a shortcut key that Salamander itself already uses. A few dialog dismisses later and &lt;tt&gt;Alt+-&lt;/tt&gt; indeed opens up Console2 to the current panel's path. Not bad, but my brain has fused the &lt;tt&gt;numpad /&lt;/tt&gt; as the go-to key for opening a command prompt, so I need to fix that, too.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The solution, part 2&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Another thread in the Salamander forums suggested &lt;a href="http://forum.altap.cz/viewtopic.php?t=1424"&gt;using AutoHotKey to intercept &lt;tt&gt;NumpadDiv&lt;/tt&gt; when Salamander has focus&lt;/a&gt; and using it to launch Console2. That kind of works, minus having Console2 launched at the current panel's folder. Well, remember the shortcut key I gave my automation script earlier? I can get AutoHotKey to intercept the &lt;tt&gt;numpad /&lt;/tt&gt; and instead emit &lt;tt&gt;Alt+-&lt;/tt&gt; when Salamander has focus: &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#IfWinActive,ahk_class SalamanderMainWindowVer25&lt;br /&gt;NumpadDiv::SendEvent !-&lt;br /&gt;RETURN&lt;/pre&gt;&lt;br /&gt;&lt;strike&gt;&lt;a href="http://en.wikipedia.org/wiki/Kazaam"&gt;Kazaam!&lt;/a&gt;&lt;/strike&gt; &lt;a href="http://en.wikipedia.org/wiki/Shazam"&gt;Shazam!&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;All of this brouhaha could have been avoided if Salamander would simply let me configure what gets launched when I hit &lt;tt&gt;numpad /&lt;/tt&gt;, hint, hint, nudge, nudge.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-3700984294500317106?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/3700984294500317106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=3700984294500317106' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3700984294500317106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3700984294500317106'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/09/console2-and-altap-salamander-together.html' title='Console2 and Altap Salamander: together at last!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-6208055709274963224</id><published>2010-06-24T23:28:00.000-04:00</published><updated>2010-06-24T23:28:30.772-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='experience'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Don Norman at Business of Software 2009</title><content type='html'>There's &lt;a href="http://blog.businessofsoftware.org/2010/06/don-norman-at-business-of-software-2010.html"&gt;an excellent video&lt;/a&gt; at &lt;a href="http://blog.businessofsoftware.org/"&gt;Neil Davidson's blog&lt;/a&gt; of &lt;a href="http://www.jnd.org/"&gt;Don Norman&lt;/a&gt; talking about successful products and services, which he summarizes to the following ten points (1 and 10 are meant to be the same):&lt;ol&gt;  &lt;li&gt;It's all about the experience&lt;/li&gt;  &lt;li&gt;Design systems&lt;/li&gt;  &lt;li&gt;Everything is a service&lt;/li&gt;  &lt;li&gt;Everything is a product&lt;/li&gt;  &lt;li&gt;Don't be too logical&lt;/li&gt;  &lt;li&gt;Memory is more important than actuality&lt;/li&gt;  &lt;li&gt;Complexity is good: Complicated is bad&lt;/li&gt;  &lt;li&gt;Design for the real world&lt;/li&gt;  &lt;li&gt;Design for people&lt;/li&gt;  &lt;li&gt;It's all about the experience&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-6208055709274963224?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/6208055709274963224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=6208055709274963224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/6208055709274963224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/6208055709274963224'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/06/don-norman-at-business-of-software-2009.html' title='Don Norman at Business of Software 2009'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-5889805882978745202</id><published>2010-06-22T22:13:00.000-04:00</published><updated>2010-06-22T22:13:26.130-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oss'/><category scheme='http://www.blogger.com/atom/ns#' term='correctness'/><category scheme='http://www.blogger.com/atom/ns#' term='elegance'/><category scheme='http://www.blogger.com/atom/ns#' term='work ethic'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='code review'/><title type='text'>A case for code reviews</title><content type='html'>&lt;a href="http://thedailywtf.com/Articles/Thats-One-Way-to-Fulfill-a-Requirement.aspx"&gt;THIS&lt;/a&gt; is a fabulous example why your organization/team should be performing code reviews.&lt;br /&gt;&lt;br /&gt;We're not talking about poring over the entire code base once a month (that's just cruel); no, you check the code your teammate or colleague wrote or modified &lt;i&gt;before&lt;/i&gt; it even goes into the main branch of the source control repository, just like how open-source projects do it.&lt;br /&gt;&lt;br /&gt;Use &lt;a href="http://www.reviewboard.org/"&gt;Review Board&lt;/a&gt;:  it's free and works with the modern source control systems.  If you have one of the source control systems that isn't supported, have one of your teammates come to your desk to give your changes a once-over until you figure out a software solution that allows you to send them the changes so they can review it on their own time while you start working on something else.&lt;br /&gt;&lt;br /&gt;Seriously.  Stop the bad software madness in its tracks TODAY.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-5889805882978745202?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/5889805882978745202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=5889805882978745202' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/5889805882978745202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/5889805882978745202'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/06/case-for-code-reviews.html' title='A case for code reviews'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8063422924208271836</id><published>2010-05-24T22:41:00.002-04:00</published><updated>2010-05-24T22:44:39.008-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='elegance'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>The coolest code</title><content type='html'>At [&lt;a href="http://en.wikipedia.org/wiki/42_%28number%29"&gt;the appropriately-numbered&lt;/a&gt;] &lt;a href="http://code.google.com/p/softwareninjas/source/detail?r=42"&gt;revision 42&lt;/a&gt; in a certain source control repository lies, without a doubt, the biggest masterpiece of software ever written &lt;a href="http://en.wikipedia.org/wiki/Lisp"&gt;since the advent of the parentheses&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;public static IEnumerable&amp;lt;T&amp;gt; PreOrder&amp;lt;T&amp;gt;(this T startingPoint, Func&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; children)&lt;br /&gt;{&lt;br /&gt;    yield return startingPoint;&lt;br /&gt;    foreach (var child in children(startingPoint))&lt;br /&gt;    {&lt;br /&gt;        var preOrderedChildren = PreOrder(child, children);&lt;br /&gt;        foreach (var preOrderedChild in preOrderedChildren)&lt;br /&gt;        {&lt;br /&gt;            yield return preOrderedChild;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;"What is it?" you say?  It's a generic, recursive &lt;a href="http://en.wikipedia.org/wiki/Generator_%28computer_science%29"&gt;generator&lt;/a&gt;, implemented as an &lt;a href="http://en.wikipedia.org/wiki/Extension_method"&gt;extension method&lt;/a&gt; with a &lt;a href="http://en.wikipedia.org/wiki/Function_object"&gt;functor&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;"Uhh, so... what does it do?" you counter?  It traverses a tree of items (of type &lt;b&gt;T&lt;/b&gt;) by &lt;i&gt;yielding&lt;/i&gt; them, starting at the provided &lt;i&gt;startingPoint&lt;/i&gt; and obtaining the children of a given instance of &lt;b&gt;T&lt;/b&gt; using the provided &lt;i&gt;children&lt;/i&gt; function object.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sos.mo.gov/archives/history/slogan.asp"&gt;"I am from Missouri. You have got to show me."&lt;/a&gt;  Sure thing!  Suppose we have this &lt;b&gt;Node&lt;/b&gt; class:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;public class Node : IEnumerable&amp;lt;Node&amp;gt;&lt;br /&gt;{&lt;br /&gt;    private readonly IList&amp;lt;Node&amp;gt; _children = new List&amp;lt;Node&amp;gt;();&lt;br /&gt;    public IEnumerable&amp;lt;Node&amp;gt; Children { get { return _children; } }&lt;br /&gt;&lt;br /&gt;    private readonly string _name;&lt;br /&gt;    public string Name { get { return _name; } }&lt;br /&gt;&lt;br /&gt;    public Node(string name)&lt;br /&gt;    {&lt;br /&gt;        _name = name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Node Add(string nodeName)&lt;br /&gt;    {&lt;br /&gt;        return Add(new Node(nodeName));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Node Add(Node node)&lt;br /&gt;    {&lt;br /&gt;        _children.Add(node);&lt;br /&gt;        return node;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    #region IEnumerable&amp;lt;Node&amp;gt; Members&lt;br /&gt;    public IEnumerator&amp;lt;Node&amp;gt; GetEnumerator()&lt;br /&gt;    {&lt;br /&gt;        return Children.GetEnumerator();&lt;br /&gt;    }&lt;br /&gt;    #endregion&lt;br /&gt;&lt;br /&gt;    #region IEnumerable Members&lt;br /&gt;    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()&lt;br /&gt;    {&lt;br /&gt;        return Children.GetEnumerator();&lt;br /&gt;    }&lt;br /&gt;    #endregion&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;...we can then use the &lt;b&gt;Node&lt;/b&gt; class to represent its own high-level parse tree:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;var compilationUnit = new Node("Node.cs")&lt;br /&gt;{&lt;br /&gt;    new Node("namespace Test")&lt;br /&gt;    {&lt;br /&gt;        new Node("public class Node : IEnumerable&amp;lt;Node&amp;gt;")&lt;br /&gt;        {&lt;br /&gt;            new Node("public IEnumerable&amp;lt;Node&amp;gt; Children")&lt;br /&gt;            {&lt;br /&gt;                new Node("get;")&lt;br /&gt;            },&lt;br /&gt;            new Node("public string Name")&lt;br /&gt;            {&lt;br /&gt;                new Node("get;")&lt;br /&gt;            },&lt;br /&gt;            new Node("public Node(string name);"),&lt;br /&gt;            new Node("public Node Add(string nodeName);"),&lt;br /&gt;            new Node("public Node Add(Node node);"),&lt;br /&gt;            new Node("#region IEnumerable&amp;lt;Node&amp;gt; Members")&lt;br /&gt;            {&lt;br /&gt;                new Node("public IEnumerator&amp;lt;Node&amp;gt; GetEnumerator();"),&lt;br /&gt;            },&lt;br /&gt;            new Node("#region IEnumerable Members")&lt;br /&gt;            {&lt;br /&gt;                new Node("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator();"),&lt;br /&gt;            },&lt;br /&gt;        },&lt;br /&gt;    },&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Notice how the Node constructor accepts both regular arguments (in this case, a string representing the node's &lt;b&gt;Name&lt;/b&gt;) as well as a list of Node instances?  That feature -- &lt;a href="http://msdn.microsoft.com/en-us/library/bb384062.aspx"&gt;collection initializers&lt;/a&gt; -- is made available to classes that implement &lt;tt&gt;IEnumerable&lt;/tt&gt; as well as an &lt;tt&gt;Add&lt;/tt&gt; method.&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;PreOrder&lt;/b&gt; method can then be called on the &lt;i&gt;compilationUnit&lt;/i&gt; instance, as follows, due to the extension method feature:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;var sequenceOfNodes = compilationUnit.PreOrder(n =&amp;gt; n.Children);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;The second argument to the method is a &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;lambda expression&lt;/a&gt; that, given an instance of &lt;b&gt;Node&lt;/b&gt;, returns an &lt;b&gt;IEnumerable&amp;lt;Node&amp;gt;&lt;/b&gt;.  In other words, it explains to &lt;b&gt;PreOrder&lt;/b&gt; how to get a sequence of &lt;b&gt;Node&lt;/b&gt; instances given a single &lt;b&gt;Node&lt;/b&gt; instance.  In our case, it is rather simple, as the Node class has the &lt;b&gt;Children&lt;/b&gt; property for that purpose (and it could have been even simpler than that, since Node implements IEnumerable and thus the second parameter could have been written as &lt;tt&gt;n =&amp;gt; n&lt;/tt&gt;).&lt;br /&gt;&lt;br /&gt;Anyway, calling the PreOrder method looked like it did nothing and it almost did indeed do nothing, which is the point of a generator:  until you start pulling on the IEnumerable, no work is performed and no items are generated.  All that was done by calling PreOrder was setting up the generator instance in the &lt;tt&gt;sequenceOfNodes&lt;/tt&gt; variable.  Let's actually start generating (a.k.a. &lt;i&gt;yielding&lt;/i&gt;):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;foreach (var node in sequenceOfNodes)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(node.Name);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;...when that loop starts executing, the code in PreOrder kicks in and the first item yielded is the &lt;i&gt;startingPoint&lt;/i&gt;, which was initialized in &lt;i&gt;compilationUnit&lt;/i&gt;, so its &lt;b&gt;Name&lt;/b&gt; is printed to the console.  The children of &lt;i&gt;startingPoint&lt;/i&gt; are obtained by calling the &lt;i&gt;children&lt;/i&gt; functor on &lt;i&gt;startingPoint&lt;/i&gt; itself.  As you will remember, that's simply the &lt;b&gt;Children&lt;/b&gt; property.  The process repeats recursively behind the scenes, yielding a node, then its children, while our loop doesn't need to worry about all of that.  The loop will end up printing a flat list version of the original tree.&lt;br /&gt;&lt;h1&gt;Conclusion (a.k.a. Too long; didn't read)&lt;/h1&gt;In 12 lines of code, I made use of the following &lt;i&gt;groovy&lt;/i&gt; C# 3.5 compiler features:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;Extension methods&lt;/a&gt;: extend a closed type with a static method that appears like an instance method&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;Lambda expressions&lt;/a&gt;: inline, anonymous methods that replace private classes that implement an interface AND can operate on local variables&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dscyy5s0.aspx"&gt;Generators (a.k.a. Iterators)&lt;/a&gt;: the &lt;tt&gt;yield return&lt;/tt&gt; keyword in methods that return &lt;tt&gt;IEnumerable&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb384061.aspx"&gt;Implicitly-typed local variables&lt;/a&gt;: the &lt;tt&gt;var&lt;/tt&gt; keyword, to avoid repeating yourself&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h1&gt;Bonus&lt;/h1&gt;If this modest display of &lt;i&gt;mad skillz&lt;/i&gt; hasn't convinced you to switch to .NET 3.5, well, you don't even need to!  You can compile all this code with the C# 3.5 compiler but still target the .NET 2.0 runtime or even the JVM!&lt;br /&gt;&lt;h2&gt;Targetting the .NET 2.0 runtime&lt;/h2&gt;Not only can you make use of the new compiler features, you can also make use of the new IDE features, such as &lt;a href="http://msdn.microsoft.com/en-us/library/dd409859.aspx"&gt;call hierarchy&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ee349251.aspx"&gt;reference highlighting&lt;/a&gt;.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open &lt;b&gt;Visual Studio&lt;/b&gt; (this should work in Visual Studio 2008 and 2010)&lt;/li&gt;&lt;li&gt;File &amp;gt; New &amp;gt; Project...&lt;/li&gt;&lt;li&gt;Select &lt;b&gt;.NET Framework 2.0&lt;/b&gt; from the drop-down list on the right:&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_QvEDZGglpqE/S_s5VOX2coI/AAAAAAAAAGo/cwsLvs_gYWo/s1600/New+Visual+Studio+2008+project+for+.NET+2.0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="394" src="http://4.bp.blogspot.com/_QvEDZGglpqE/S_s5VOX2coI/AAAAAAAAAGo/cwsLvs_gYWo/s640/New+Visual+Studio+2008+project+for+.NET+2.0.png" width="640" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.danielmoth.com/Blog/Using-Extension-Methods-In-Fx-20-Projects.aspx"&gt;Create the &lt;tt&gt;ExtensionAttribute&lt;/tt&gt; replacement&lt;/a&gt; by adding a file called &lt;b&gt;ExtensionAttribute.cs&lt;/b&gt; in your project with the following contents:&lt;br /&gt;&lt;pre&gt;namespace System.Runtime.CompilerServices&lt;br /&gt;{&lt;br /&gt;   public class ExtensionAttribute : Attribute { }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Create a &lt;b&gt;Delegates.cs&lt;/b&gt; file that contains the missing &lt;a href="http://msdn.microsoft.com/en-us/library/system.aspx"&gt;&lt;tt&gt;Action&lt;/tt&gt; and &lt;tt&gt;Func&lt;/tt&gt; delegates from the &lt;tt&gt;System&lt;/tt&gt; namespace&lt;/a&gt; (you probably only need up to 4 arguments)&lt;/li&gt;&lt;li&gt;Start writing cool code!&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Targetting the JVM&lt;/h2&gt;This one is more complicated, but the tool you need to download is &lt;a href="http://dev.mainsoft.com/Default.aspx?tabid=267"&gt;Mainsoft Grasshopper&lt;/a&gt;.  You'll need to perform similar additions of missing attribute and delegates as above, but then you should be fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8063422924208271836?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8063422924208271836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8063422924208271836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8063422924208271836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8063422924208271836'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/05/coolest-code.html' title='The coolest code'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_QvEDZGglpqE/S_s5VOX2coI/AAAAAAAAAGo/cwsLvs_gYWo/s72-c/New+Visual+Studio+2008+project+for+.NET+2.0.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-5023989201313935001</id><published>2010-05-19T22:02:00.000-04:00</published><updated>2010-05-19T22:02:26.627-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='elegance'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='unit'/><title type='text'>Arrange, Act, Assert</title><content type='html'>There's a pattern in unit test writing that I noticed a few years back, but it wasn't until recently that I discovered this pattern actually has a name:  Arrange, Act, Assert.  These represent the three &lt;a href="http://www.imdb.com/title/tt0160277/"&gt;&lt;strike&gt;terrifying waves&lt;/strike&gt;&lt;/a&gt; distinct phases of a good unit test:  the first part prepares the necessary conditions that simulate a scenario or use-case (arrange), the second invokes the functionality being tested (act) and the third checks that some post-conditions hold (assert).&lt;br /&gt;&lt;br /&gt;Here's some Java code I was writing at the time I first noticed the pattern (November 2007):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;/**&lt;br /&gt; * Tests the &amp;lt;i&amp;gt;shuffle&amp;lt;/i&amp;gt; method against the Collections.shuffle(List&amp;lt;?&amp;gt;,&lt;br /&gt; * Random) implementation from which it was derived.&lt;br /&gt; */&lt;br /&gt;@Test&lt;br /&gt;public void shuffle_AgainstReference ( )&lt;br /&gt;{&lt;br /&gt;    // { initialization&lt;br /&gt;    Random randomSource;&lt;br /&gt;    int length = 20;&lt;br /&gt;    double[] sourceArray = new double[length];&lt;br /&gt;    List&amp;lt;Double&amp;gt; expectedList = new ArrayList&amp;lt;Double&amp;gt; ( length );&lt;br /&gt;    for ( int i = 0; i &amp;lt; length; i++ )&lt;br /&gt;    {&lt;br /&gt;        sourceArray[i] = i;&lt;br /&gt;        expectedList.add ( (double) i );&lt;br /&gt;    }&lt;br /&gt;    // }&lt;br /&gt;&lt;br /&gt;    // { double-check&lt;br /&gt;    for ( int i = 0; i &amp;lt; length; i++ )&lt;br /&gt;    {&lt;br /&gt;        String message = "Source array is different at index [" + i + "]";&lt;br /&gt;        assertEquals ( message, expectedList.get ( i ), sourceArray[i] );&lt;br /&gt;    }&lt;br /&gt;    // }&lt;br /&gt;&lt;br /&gt;    randomSource = new Random ( 42 );&lt;br /&gt;    ArrayUtil.shuffle ( sourceArray, randomSource );&lt;br /&gt;&lt;br /&gt;    randomSource = new Random ( 42 );&lt;br /&gt;    Collections.shuffle ( expectedList, randomSource );&lt;br /&gt;&lt;br /&gt;    // { validation&lt;br /&gt;    for ( int i = 0; i &amp;lt; length; i++ )&lt;br /&gt;    {&lt;br /&gt;        String message = "Shuffled array is different at index [" + i + "]";&lt;br /&gt;        assertEquals ( message, expectedList.get ( i ), sourceArray[i] );&lt;br /&gt;    }&lt;br /&gt;    // }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;That code tests that my implementation of ArrayUtil.shuffle() on an array of doubles works just like the implementation of Collections.shuffle().  One will notice that I called the first block or phase "initialization" and the last one "validation" (which, come to think of it, should have been called "verification" -- more on this &lt;a href="http://en.wikipedia.org/wiki/Verification_and_validation"&gt;at Wikipedia&lt;/a&gt;).  The block labeled "double-check" should probably have been taken out into its own test.&lt;br /&gt;&lt;br /&gt;I recently noticed the more formalized use in the &lt;a href="http://haacked.com/code/NamedStringFormatSolution.zip"&gt;NamedStringFormatSolution.zip&lt;/a&gt; project (more about this project at &lt;a href="http://haacked.com/"&gt;Phil Haack&lt;/a&gt;'s &lt;a href="http://haacked.com/archive/2009/01/14/named-formats-redux.aspx"&gt;Named Formats Redux&lt;/a&gt; blog post), where the 3 phases of unit testing were explicitly called out by comments in the code:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;[Fact]&lt;br /&gt;public void Eval_WithNamedExpressionAndFormat_EvalsPropertyOfExpression()&lt;br /&gt;{&lt;br /&gt;    //arrange&lt;br /&gt;    var expr = new FormatExpression("{foo:#.##}");&lt;br /&gt;&lt;br /&gt;    //act&lt;br /&gt;    string result = expr.Eval(new { foo = 1.23456 });&lt;br /&gt;&lt;br /&gt;    //assert&lt;br /&gt;    Assert.Equal("1.23", result);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;The &lt;i&gt;arrange&lt;/i&gt; phase is sometimes so trivial that its contents is folded into the &lt;i&gt;act&lt;/i&gt; phase, but unless a value is repeated in several tests that it becomes cleaner or less error-prone to extract it out in a constant, it should remain in the test for maximum clarity.&lt;br /&gt;&lt;br /&gt;So there you have it:  the next time you write a test, design it to execute in three distinct phases of arrangement, acting and assertion.  Your test will be better designed, easier to read and other maintainers will thank you for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-5023989201313935001?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/5023989201313935001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=5023989201313935001' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/5023989201313935001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/5023989201313935001'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/05/arrange-act-assert.html' title='Arrange, Act, Assert'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8532960491632037669</id><published>2010-04-10T14:56:00.001-04:00</published><updated>2010-04-10T14:56:37.176-04:00</updated><title type='text'>Reformulate to avoid misunderstandings</title><content type='html'>Some of the best advice on technical writing that I have ever read suggested the writer try to explain their ideas in more than one way, usually through the magical phrase &lt;i&gt;in other words&lt;/i&gt;.&lt;br&gt;&lt;br&gt;The technique works by introducing your topic in one writing style, vocabulary, point of view, abstraction level, etc. and then the following sentence conveys mostly the same information, but from a different angle, using synonyms, using more/less details and/or introducing requirements or consequences of the idea. (See how I did that?)&lt;br&gt;&lt;br&gt;It may seem like it is adding superfluous redundancy, but it helps avoid ambiguity &lt;i&gt;and&lt;/i&gt; the clever use of synonyms should help make your document easier to find by search engines.&amp;nbsp; Just be careful not to overuse the technique.&amp;nbsp; In other words, some ideas are simple enough that they do not need to be restated.&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8532960491632037669?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8532960491632037669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8532960491632037669' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8532960491632037669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8532960491632037669'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/04/reformulate-to-avoid-misunderstandings.html' title='Reformulate to avoid misunderstandings'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8077622003327675492</id><published>2010-04-08T22:16:00.001-04:00</published><updated>2010-04-08T22:16:30.973-04:00</updated><title type='text'>Jamie Cansdale is my hero</title><content type='html'>&lt;a href="http://weblogs.asp.net/nunitaddin/" id="dr1q" title="Jamie Cansdale"&gt;Jamie Cansdale&lt;/a&gt; (of Mutant Design) is the author of &lt;a href="http://testdriven.net/" id="q.za" title="TestDriven.Net"&gt;TestDriven.Net&lt;/a&gt;, a Visual Studio add-in that &amp;quot;makes it easy to run unit tests&amp;quot; (and it certainly lives up to that description). &amp;nbsp;A simple, casual feature request sent by e-mail two days ago was followed by fabulous customer support that culminated today in a private build that fully implements the feature, even with our unusual environment at work.&lt;br&gt;&lt;br&gt;&lt;div&gt;Jamie&amp;#39;s e-mails came in rapidly and always with offers for more help in getting me to better use his already-fantastic product. &amp;nbsp;I sometimes had trouble keeping up with him! &amp;nbsp;The conversation was to the point and I felt I was being treated as a very important customer, &lt;a href="http://thedailywtf.com/Articles/Mr-Keyboard,-Mr-Internet,-and-Support-from-Mr-James.aspx" id="mm.v" title="not just some [l]user who needs to be clued in to the basics of computers by some first tier customer support who gets paid minimum wage and doesn&amp;#39;t care about their job"&gt;not just some [l]user who needs to be clued in to the basics of computers by some first tier customer support who gets paid minimum wage and doesn&amp;#39;t care about their job&lt;/a&gt;.&lt;/div&gt;&lt;br&gt;&lt;div&gt;Jamie and I iterated through 6 private builds first by e-mail and then by instant messaging to explore the requirements and smash all the bugs in the implementation so that TD.Net could fully support the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.deploymentitemattribute(VS.100).aspx" id="xhai" title="DeploymentItemAttribute"&gt;DeploymentItemAttribute&lt;/a&gt;, just like MSTest, even when the files being referenced were marked as read-only due to the nature of the source control system in use. &amp;nbsp;I came out of this experience a very satisfied customer, as - even though I use the software as a student to write open-source software - I decided to put my money where my mouth is and purchased a professional license.&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;If you&amp;#39;re still reading, what are you waiting for? &amp;nbsp;Go buy the product and/or go provide customer service so good that your users will write blog posts about it!&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8077622003327675492?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8077622003327675492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8077622003327675492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8077622003327675492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8077622003327675492'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2010/04/jamie-cansdale-is-my-hero.html' title='Jamie Cansdale is my hero'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-3545595725351093895</id><published>2009-11-09T21:21:00.001-05:00</published><updated>2009-11-09T21:22:06.312-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='router'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>How to secure your wireless network</title><content type='html'>&lt;b&gt;Note&lt;/b&gt;:  The following is a repost of &lt;a href="http://sites.google.com/site/theitnotes/networking/how-to-secure-your-wireless-network"&gt;how-to of the same name&lt;/a&gt; I wrote tonight at my &lt;a href="http://sites.google.com/site/theitnotes/system/app/pages/sitemap/hierarchy"&gt;IT notes&lt;/a&gt; site.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Intro&lt;/h1&gt;&lt;div&gt;Do you have a wireless router and a wireless device and want to make sure your neighbours aren't freeloading your internet connection or snooping through your network?  Follow these instructions to lock down your wi-fi.&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;Get what you need&lt;/h1&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;A router that has both wired ports and wireless capability.&lt;/li&gt;&lt;li&gt;A computer with a wired connection to the router.&lt;/li&gt;&lt;li&gt;A computer with a wireless network connection (it could be the same computer as in #2).&lt;/li&gt;&lt;li&gt;A piece of paper large enough to write 5 lines of text on it.  You will be filling in the following template:&lt;br /&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0"&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="50%"&gt;IP Address&lt;br /&gt;&lt;/td&gt;&lt;td width="50%"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;User Name&lt;br /&gt;&lt;/td&gt;&lt;td width="50%"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;Password&lt;br /&gt;&lt;/td&gt;&lt;td width="50%"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;SSID&lt;br /&gt;&lt;/td&gt;&lt;td width="50%"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;Passphrase&lt;br /&gt;&lt;/td&gt;&lt;td width="50%"&gt;                           &lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/li&gt;&lt;li&gt;A pen.&lt;/li&gt;&lt;li&gt;Some adhesive if the paper in #4 did not have its own.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;h1&gt;Let's get started!&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;Plug your computer into the router (and switch off or unplug the wireless network adapter if your computer has both).  This makes sure you're configuring the right router (and not your neighbour's) as well as gives you a way to fix it if you accidentally lock yourself out.  Some routers only allow you to configure them through a wired connection anyway.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Find out what your gateway's &lt;b&gt;IP Address&lt;/b&gt; is.  It will be something like &lt;b&gt;192.168.0.1&lt;/b&gt; but it depends on the manufacturer and model, as well as the initial set-up.&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows XP:&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Start&lt;/b&gt; &gt; &lt;b&gt;Control Panel&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Double-click on &lt;b&gt;Network Connections&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Double-click on the &lt;b&gt;Local Area Connection&lt;/b&gt; icon&lt;/li&gt;&lt;li&gt;Click on the &lt;b&gt;Support&lt;/b&gt; tab&lt;/li&gt;&lt;li&gt;Write down the numbers that are next to &lt;b&gt;Default Gateway&lt;/b&gt; as the &lt;b&gt;IP Address&lt;/b&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows Vista and 7:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Show the &lt;b&gt;Start&lt;/b&gt; menu&lt;/li&gt;&lt;li&gt;Type &lt;b&gt;network connections&lt;/b&gt; in the search box and select &lt;b&gt;View network connections&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Double-click on the &lt;b&gt;Local Area Connection&lt;/b&gt; icon&lt;/li&gt;&lt;li&gt;Click on the &lt;b&gt;Details...&lt;/b&gt; button&lt;/li&gt;&lt;li&gt;Write down the numbers that are next to &lt;b&gt;IPv4 Default Gateway&lt;/b&gt; as the &lt;b&gt;IP Address&lt;/b&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;Open your web browser and in the address bar, type &lt;b&gt;http://&lt;/b&gt; followed immediately by the gateway's IP address.  For example:  &lt;b&gt;http://192.168.0.1&lt;/b&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You should be prompted for a user name and password.  If you have never set this, then you have a few options for figuring out what the default user name and password are:&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Find the little user's manual that came with the device.  It should have a section on administration or remote access.  Worst case, you flip through the 10-20 pages looking for either an image similar to what's on your screen right now or some mention of any of the following words: &lt;b&gt;admin&lt;/b&gt;, &lt;b&gt;login&lt;/b&gt;, &lt;b&gt;password&lt;/b&gt; or &lt;b&gt;user name&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Find a digital version of the user's manual:&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to the manufacturer's website.  If it's not printed on the router anywhere, search the web.&lt;/li&gt;&lt;li&gt;Navigate to their &lt;b&gt;Support&lt;/b&gt; section of the website.&lt;/li&gt;&lt;li&gt;Look for a &lt;b&gt;Product&lt;/b&gt; or &lt;b&gt;Model&lt;/b&gt; &lt;b&gt;Search&lt;/b&gt; and type in the model number of your router.&lt;/li&gt;&lt;li&gt;One of the links for your router's page (when you eventually find it) should be for the manual, usually as a PDF file.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;li&gt;Guess!  Here are some common combinations:&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;user name &lt;b&gt;admin&lt;/b&gt; and no password&lt;/li&gt;&lt;li&gt;no user name and &lt;b&gt;admin&lt;/b&gt; as the password&lt;/li&gt;&lt;li&gt;user name &lt;b&gt;admin&lt;/b&gt; and password &lt;b&gt;admin&lt;/b&gt;&lt;/li&gt;&lt;li&gt;no user name and no password&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;li&gt;Now that you have found the default user name and password, you should change them as soon as possible.  Look under &lt;b&gt;Tools&lt;/b&gt;, &lt;b&gt;Advanced&lt;/b&gt; or &lt;b&gt;Maintenance&lt;/b&gt;.  Invent a password you don't use for anything else and write both the &lt;b&gt;User Name&lt;/b&gt; and the &lt;b&gt;Password&lt;/b&gt; on your piece of paper.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;Look for a &lt;b&gt;Wireless&lt;/b&gt; or &lt;b&gt;WLAN&lt;/b&gt; menu.  You will know you have found the right page when you see words like &lt;b&gt;SSID&lt;/b&gt;, &lt;b&gt;WEP&lt;/b&gt;, &lt;b&gt;WPA&lt;/b&gt;, &lt;b&gt;Passphrase&lt;/b&gt; and &lt;b&gt;Channel&lt;/b&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Your &lt;b&gt;Network Name&lt;/b&gt; is commonly called &lt;b&gt;SSID&lt;/b&gt;.  You change this from its default of &lt;b&gt;default&lt;/b&gt; (or sometimes it's the manufacturer's name) and set it to something that's easy for you and your guests to know it's your router.  Keep it simple and a single word if possible, like the name of a pet.  Whatever you choose, write it down on your piece of paper.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The next part is a little trickier.  You usually need to select &lt;b&gt;what kind of security&lt;/b&gt; you want.  If you're reading this, you want to change it from &lt;b&gt;None&lt;/b&gt; or &lt;b&gt;Disabled&lt;/b&gt; to &lt;b&gt;WPA&lt;/b&gt;.&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Side note:  Avoid &lt;b&gt;WEP&lt;/b&gt; at all costs as it is too easy to break in.  Protecting your wireless network with &lt;b&gt;WEP&lt;/b&gt; is like putting a sign in front of a pool, kindly asking people not to go swimming.  Protecting your wireless network with &lt;b&gt;WPA&lt;/b&gt; is like building a fence around your pool.  The most determined swimmers can still climb your fence, but casual swimmers that would not have been deterred by the "please don't swim" sign will go look for easier pools to break into.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Side note number 2:  Your router might allow you to select &lt;b&gt;WPA2&lt;/b&gt;.  In my experience, this protocol is not as compatible with as many devices, so I would not recommend it.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;Now you get to pick a &lt;b&gt;Passphrase&lt;/b&gt; (also known as a &lt;b&gt;shared key&lt;/b&gt;).  A passphrase is like a password, but it's longer and it can contain spaces.  Pick an easy to spell one-liner that you and your guests can easily type, something like &lt;b&gt;I am one with everything&lt;/b&gt;.  It usually needs to be at least 8 characters long and, just like a password, it will be case-sensitive.  When you have typed it twice, click whatever &lt;b&gt;Save&lt;/b&gt; button there is and you're &lt;i&gt;almost done&lt;/i&gt;!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;At this point, your router might want to think for a few seconds or maybe it will automatically reboot.  In any case, wait 10-30 seconds and then try connecting to your router using a wireless-capable device.  If you are using the same computer, unplug the network cable and then switch on (or plug in) your wireless network adapter.  After another 10-15 seconds, you should get a message saying some wireless networks were detected and to click to see a list.  You should see your newly-named wireless network in that list with a little padlock indicating it needs a key.  If your network is not listed, you can wait another minute or two and then start over in case you got something wrong along the way.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It works!  Yeehaw!  Now attach your piece of paper under your router using some light adhesive so that the next time you need to fix something, you will be able to skip steps 2 and 4.  It will also be useful when you want to give your guests access to your wireless network; you won't have to try to remember anything, you can just lift up your router and read off the &lt;b&gt;SSID&lt;/b&gt; and &lt;b&gt;Passphrase&lt;/b&gt; to them.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-3545595725351093895?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/3545595725351093895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=3545595725351093895' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3545595725351093895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3545595725351093895'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2009/11/how-to-secure-your-wireless-network.html' title='How to secure your wireless network'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8289728576053162140</id><published>2009-08-19T22:21:00.000-04:00</published><updated>2009-08-19T22:22:01.279-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><title type='text'>HOWTO: Shop for a laptop</title><content type='html'>&lt;b&gt;Note:&lt;/b&gt; The following is taken verbatim from an e-mail I sent a relative who was interested in purchasing a laptop.  It's reposted here so I can share it with the world and subsequently link to it the next time I'm asked about it.  That and some feedback from the public at large couldn't hurt!&lt;br /&gt;&lt;br /&gt;The best way I found to shop for laptops is to find as many flyers as possible and cut them apart so you have playing-card sized pieces with the picture of the laptop, its price and its specs.  The Future Shop and Best Buy flyers are great for this and sometimes the Dell, The Source and Staples flyers are useful too.&lt;br /&gt;&lt;br /&gt;You then start to whittle it down by eliminating obviously too-expensive laptops and too-low end laptops.  (i.e. those in the $3000 range and those with less than 2 GB of RAM)  You just toss the pieces in the garbage.  For the next iteration, you start looking more carefully at the specifications, pictures, etc. and tossing out those that don't fit your wants and needs.  Repeat until you have about two or three left.&lt;br /&gt;&lt;br /&gt;What you do next is you go to the stores, find where the two or three you have left are, and play with them for 5-10 minutes to see if there's a clear winner.  If you can't tell the difference between the them, well, the least expensive wins.  I recommend you sleep on it at this point.&lt;br /&gt;&lt;br /&gt;Laptops usually come with a one-year warranty and you can purchase a few more years after that for up to 3 or 4, depending on the store. That can easily add $300 to the cost of the laptop, so you may want to decide on that before you even step into the store, otherwise you'll be asked to decide at check-out and making a decision about something that's almost 1/3 the cost of the product is not something you want to do quickly.&lt;br /&gt;&lt;br /&gt;I would not recommend purchasing a laptop (over a desktop) unless the computer needs to be mobile and moved around a lot.  You'll pay more for the privilege of having small pieces that fit inside a portable package and thus the same money could be spent on something more powerful with a bigger screen, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8289728576053162140?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8289728576053162140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8289728576053162140' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8289728576053162140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8289728576053162140'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2009/08/howto-shop-for-laptop.html' title='HOWTO: Shop for a laptop'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1636253944279259652</id><published>2009-04-22T21:07:00.000-04:00</published><updated>2009-04-22T21:07:59.939-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='platform'/><category scheme='http://www.blogger.com/atom/ns#' term='add-ons'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='egg'/><title type='text'>On uninstalling Google Chrome</title><content type='html'>I finally gave up with Google Chrome on my laptop.  Here's what popped up when I completed the uninstallation process, with my answers:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;b&gt;Google Chrome has been uninstalled.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Thanks for trying out Google Chrome. Please help us improve Google Chrome by telling us why you uninstalled it. Your feedback is much appreciated.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Which of the following best describes you?&lt;/strong&gt;&lt;br /&gt;&lt;input name="extra.reason" value="maytry" type="radio"&gt;I am uninstalling Google Chrome for now, but I may try it again in the future&lt;br /&gt;&lt;input name="extra.reason" value="permanently" checked="checked" type="radio"&gt;I am permanently uninstalling Google Chrome&lt;br /&gt;&lt;input name="extra.reason" value="temporarily" type="radio"&gt;I am only uninstalling briefly. I am going to reinstall straight away (e.g. changing computer, upgrading operating system)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why are you uninstalling Google Chrome?&lt;/strong&gt; Please check all that apply&lt;br /&gt;&lt;input name="extra.uninstall2" value="noload" type="checkbox"&gt;It doesn't load some web pages properly (please list any examples below)&lt;br /&gt;&lt;input name="extra.uninstall3" value="no_feature" checked="checked" type="checkbox"&gt;It's missing some features that I use (please provide detail in the box below)&lt;br /&gt;&lt;input name="extra.uninstall4" value="too_privacy" type="checkbox"&gt;I'm concerned about privacy (please provide detail in the box below)&lt;br /&gt;&lt;input name="extra.uninstall5" value="too_slow" checked="checked" type="checkbox"&gt;It seems to slow down my computer&lt;br /&gt;&lt;input name="extra.uninstall1" value="crashes" type="checkbox"&gt;It crashes too often&lt;br /&gt;&lt;input name="extra.uninstall6" value="Otherreason" type="checkbox"&gt;Other (please provide more details in the text box below)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Please provide any additional detail on your reason for uninstalling:&lt;/strong&gt;&lt;br /&gt;&lt;div style="border:thin solid black;"&gt;&lt;br /&gt;There are too many Firefox add-ons that I have come to rely on and using Chrome just leaves me "naked" in comparison.  I blogged about this potential problem when Chrome initially came out:  http://oliiscool.blogspot.com/2008/09/world-in-verdana.html&lt;br /&gt;&lt;br /&gt;I first installed Chrome when I heard Gmail and Google Reader had exceptionally good performance in Chrome.  This was true, but as soon as I clicked a 3rd-party link from within either, I felt I was abandoned and frequently would end up copy/pasting the URL into Firefox and continue from there.&lt;br /&gt;&lt;br /&gt;I definitely appreciate the engineering skills and value of having a process-per-tab kind of browser, but that functionality alone is not sufficient for a heavy add-on user such as myself.  In fact, I have checked the "slow down" checkbox since that model seems to in fact be a liability when viewing YouTube videos:  I definitely notice much higher CPU usage from Chrome when visiting a site containing an embedded video than visiting the same page with Firefox.&lt;br /&gt;&lt;br /&gt;Perhaps not all is lost:  the process-per-tab model could still be applied to Firefox and a "Chromium Tab" Firefox add-on that worked similarly to the "IE Tab" add-on (in that it would enable the Webkit/Chromium engine on a per-tab basis) would be fantastic in my books.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So maybe I'll eventually re-install it.  There's definitely value in the "application mode" as well, which hides the address bar and makes a "tab" its own window using the site/application's "favico" as the application window's icon, but that breaks quickly - as I described above - when you need to go outside that site/application.  That "application mode" would also be a neat add-on/extension for Firefox.  :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1636253944279259652?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1636253944279259652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1636253944279259652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1636253944279259652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1636253944279259652'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2009/04/on-uninstalling-google-chrome.html' title='On uninstalling Google Chrome'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-7250864360142393586</id><published>2009-04-03T15:30:00.000-04:00</published><updated>2009-04-03T15:30:50.277-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NAT'/><category scheme='http://www.blogger.com/atom/ns#' term='router'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>Do you still not use a router?</title><content type='html'>I was helping out an extended family member over the phone the other night when I realized he would connect one of his two computers directly to the cable modem, in turn, depending on which computer he was going to use to get internet access.&lt;br /&gt;&lt;br /&gt;This struck me as being very odd.  Ten years ago, I was using hubs and later migrated to switches and then router/switch combinations to network computers.  I just can't imagine what life would be like to have more than one computer in a house and not some sort of network between them.&lt;br /&gt;&lt;br /&gt;More scary was that he called me on April 1st, the day the &lt;a href="http://www.microsoft.com/security/portal/Entry.aspx?name=Worm:Win32/Conficker.D"&gt;Conficker&lt;/a&gt; author(s) decided to freak everyone out.  Since &lt;a href="http://en.wikipedia.org/wiki/Conficker#Initial_infection"&gt;Conficker's primary infection mechanism&lt;/a&gt; was to exploit a vulnerability in a Windows service and he had &lt;em&gt;just reinstalled Windows&lt;/em&gt; on that computer, I was worried he could get infected and warned him about the dangers of doing so.&lt;br /&gt;&lt;br /&gt;In this case, a router would have not only removed the "unplug this computer, plug that computer" inconvenience but also have acted as a firewall between his computer(s) and the internet, therefore making it difficult to get infected by worms like Conficker &lt;b&gt;just because your computer is connected to a [hostile] network&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Thankfully, I have an extra router lying around that I'll give him the next time I see him, but &lt;em&gt;seriously&lt;/em&gt;, if you don't have a router, go spend $50 on a networking device that doubles as a firewall.  Most internet software is NAT-aware these days, so you're no longer trading off convenience for security.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-7250864360142393586?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/7250864360142393586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=7250864360142393586' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7250864360142393586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7250864360142393586'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2009/04/do-you-still-not-use-router.html' title='Do you still not use a router?'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-6619211530384080414</id><published>2009-02-02T23:00:00.001-05:00</published><updated>2009-02-02T23:00:00.679-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='correctness'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='vs'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='ironpython studio'/><category scheme='http://www.blogger.com/atom/ns#' term='ironpython'/><category scheme='http://www.blogger.com/atom/ns#' term='annoying'/><category scheme='http://www.blogger.com/atom/ns#' term='wedgie'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Ego-driven software development</title><content type='html'>(or "How M.C. Escher Would Have Packaged His Software")&lt;br /&gt;&lt;br /&gt;This was too "good" to &lt;em&gt;not&lt;/em&gt; blog about.  I heard about &lt;a href="http://www.codeplex.com/IronPythonStudio/"&gt;IronPython Studio&lt;/a&gt;, a Visual Studio-based IDE for writing Python code for/with .NET tools.  In order to install this interesting gem, you first need to install &lt;a href="http://www.codeplex.com/IronPythonStudio/Wiki/View.aspx?title=Pre-requisites&amp;referringTitle=Home"&gt;its pre-requisites&lt;/a&gt;, which is one of flavors of the "Visual Studio 2008 Shell":  &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=ACA38719-F449-4937-9BAC-45A9F8A73822&amp;displaylang=en"&gt;Isolated Mode&lt;/a&gt; or &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=40646580-97FA-4698-B65F-620D4B4B1ED7&amp;displaylang=en"&gt;Integrated Mode&lt;/a&gt;.  Sounds easy, right?  &lt;strong&gt;Wrong!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The actual downloads seem innocent enough (I got both, just to be safe -- as an aside it was hard to tell which one would suit me best):  they arrive as executables.  Here's how many levels of "packaging" there are:&lt;ol&gt;&lt;li&gt;Running either of &lt;tt&gt;vs_AppEnvRedist.exe&lt;/tt&gt; or &lt;tt&gt;vs_ideredist.exe&lt;/tt&gt; will create a temporary directory where the EXE's files are extracted and an "installer" is launched&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You accept the EULA and click next a few times and what do you end up with?  "The redistributable package has been installed".  That's right, you ran an installer that installed another installer.  Total disk space needed for this (at apogee):  400 MB for the original download, 400 MB for the temporary files and 400 MB for the "redistributable package" = 1200 MB&lt;/li&gt;&lt;br /&gt;&lt;li&gt;As you finish the first "installer", the temporary files are cleaned up, so we're back to consuming 800 MB.  You run the &lt;em&gt;second&lt;/em&gt; installer and the first thing it does is check its signature, which consumes 400 MB of RAM. &lt;strong&gt; It then proceeds to extract files to &lt;em&gt;another&lt;/em&gt; temporary directory&lt;/strong&gt; (400 MB again, although this time it's in a bunch of smaller files - 286 MB of which is various versions of the .NET framework), thus bringing our used disk space back up to 1200 MB.  Those of you following at home will notice that I haven't actually &lt;em&gt;installed&lt;/em&gt; anything useful yet.  Accept another EULA, select the only feature (&lt;a href="http://lolwut.com/"&gt;wut?&lt;/a&gt;), pick the destination folder and go (again)!  At apogee:  400 MB + 400 MB + 400 MB + whatever installed size it was (I didn't check)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Oh, it looks like we're actually done!  What was I installing, again?&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I'm reminded of Adobe Acrobat Reader installers &lt;strong&gt;from, oh, I don't know, &lt;em&gt;ten years ago&lt;/em&gt;&lt;/strong&gt;, before &lt;a href="http://msdn.microsoft.com/en-us/library/aa372866.aspx"&gt;one-file installers&lt;/a&gt; were even invented.  &lt;a href="http://www.codeplex.com/IronPython"&gt;IronPython&lt;/a&gt; itself is available in &lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365#ReleaseFiles"&gt;a single MSI file&lt;/a&gt;, while IronPython Studio's download options are both available as &lt;a href="http://www.codeplex.com/IronPythonStudio/Release/ProjectReleases.aspx?ReleaseId=8934#ReleaseFiles"&gt;an MSI file in a ZIP file&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There is no technical reason for this.  There simply is no excuse for these &lt;a href="http://www.mcescher.com/Gallery/switz-bmp/LW310.jpg"&gt;fractal installers&lt;/a&gt; except that someone (or an entire team of someones) at Microsoft decided they needed to be involved in the supply chain that brings us &lt;a href="http://en.wikipedia.org/wiki/Internet_users"&gt;internauts&lt;/a&gt; &lt;strong&gt;this &lt;a href="http://www.eclipse.org/downloads/packages/eclipse-classic-341/ganymedesr1"&gt;bare Eclipse&lt;/a&gt;-wannabe that does not &lt;em&gt;even&lt;/em&gt; include a text editor&lt;/strong&gt;.  I mean, seriously, the only thing that could have been worse would have been to wrap the whole thing in a "downloader" (like Visual Studio Express) or in an ISO 9660 file (like Visual Studio 2008 Service Pack 1).&lt;br /&gt;&lt;br /&gt;I have a &lt;strong&gt;special offer for the person in charge of the Visual Studio team:  &lt;em&gt;I will personally come over and deliver &lt;a href="http://images.google.ca/images?q=%22bob+the+dinosaur%22"&gt;atomic wedgies&lt;/a&gt; to everyone responsible for these shenanigans!&lt;/em&gt;&lt;/strong&gt;  Just give me a call; you know how to find me.&lt;br /&gt;&lt;br /&gt;There &lt;em&gt;is&lt;/em&gt; some good news after all this:  IronPython Studio not only just works, but so does its debugger.  Kudos to &lt;em&gt;that&lt;/em&gt; team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-6619211530384080414?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/6619211530384080414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=6619211530384080414' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/6619211530384080414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/6619211530384080414'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2009/02/ego-driven-software-development.html' title='Ego-driven software development'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-376978462672591899</id><published>2008-10-25T22:00:00.000-04:00</published><updated>2008-10-25T22:00:34.735-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='xsl'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Apple sucks at XML</title><content type='html'>OK, I've officially &lt;i&gt;had&lt;/i&gt; it with &lt;a href="http://www.apple.com/"&gt;Apple&lt;/a&gt;.  Steve Jobs may have style down cold, but his programmers were smoking something fierce when they designed the XML format for their so-called &lt;a href="http://en.wikipedia.org/wiki/Property_list#Mac_OS_X"&gt;Property list&lt;/a&gt;.  Don't let that Wikipedia page fool you on the apparent simplicity of the format.  Take a look at one of &lt;a href="http://www.apple.com/applescript/features/propertylists.html"&gt;Apple's own samples&lt;/a&gt;.  Still not convinced?  How about a real-world use-case:  the emoticon definition file for &lt;a href="http://www.adiumxtras.com/index.php?a=xtras&amp;xtra_id=3715"&gt;an Adium theme&lt;/a&gt;, a portion of which is reproduced below:&lt;blockquote&gt;&lt;pre&gt;&amp;lt;plist version="1.0"&amp;gt;&lt;br /&gt;&amp;lt;dict&amp;gt;&lt;br /&gt;  &amp;lt;key&amp;gt;AdiumSetVersion&amp;lt;/key&amp;gt;&lt;br /&gt;  &amp;lt;integer&amp;gt;1&amp;lt;/integer&amp;gt;&lt;br /&gt;  &amp;lt;key&amp;gt;Emoticons&amp;lt;/key&amp;gt;&lt;br /&gt;  &amp;lt;dict&amp;gt;&lt;br /&gt;    &amp;lt;key&amp;gt;amazing.png&amp;lt;/key&amp;gt;&lt;br /&gt;    &amp;lt;dict&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Equivalents&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;array&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;=-o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;=-O&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-O&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Name&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;string&amp;gt;Surprised&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    &amp;lt;key&amp;gt;anger.png&amp;lt;/key&amp;gt;&lt;br /&gt;    &amp;lt;dict&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Equivalents&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;array&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;:o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-@&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:@&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;X(&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Name&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;string&amp;gt;Angry&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    &amp;lt;key&amp;gt;bad_egg.png&amp;lt;/key&amp;gt;&lt;br /&gt;    &amp;lt;dict&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Equivalents&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;array&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;-[&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;-(&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Name&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;string&amp;gt;Nervous&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    (...snip...)&lt;br /&gt;  &amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/plist&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;Do you see what the problem is?  For those of you playing at home, here's a hint:  &lt;b&gt;how would you write an XPath expression to obtain the "equivalents" of a given image file&lt;/b&gt;?&lt;br /&gt;&lt;br /&gt;Yes, it's not &lt;i&gt;impossible&lt;/i&gt; to grab a value for a given key, but &lt;b&gt;did they have to make it so hard when XML can express the same idea in a much easier format&lt;/b&gt;?  Or, rather, did they have to be so lazy when writing the code that serializes these property lists to/from XML?&lt;br /&gt;&lt;br /&gt;In any case, if you ever have the need to process an XML file created by an Apple program, the &lt;b&gt;following stylesheet will (likely) help restore your sanity&lt;/b&gt;.  Simply pre-process the XML with my stylesheet and then &lt;b&gt;your XML code or stylesheet will be &lt;i&gt;much&lt;/i&gt; easier to write (and read!)&lt;/b&gt;:&lt;blockquote&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:output method="xml" encoding="utf-8" indent="yes" /&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template match="* | @* | node()"&amp;gt;&lt;br /&gt;    &amp;lt;xsl:copy&amp;gt;&lt;br /&gt;      &amp;lt;!-- if the previous sibling is a 'key' element --&amp;gt;&lt;br /&gt;      &amp;lt;xsl:if test="name(preceding-sibling::*[position()=1]) = 'key'"&amp;gt;&lt;br /&gt;        &amp;lt;xsl:attribute name="key"&amp;gt;&lt;br /&gt;          &amp;lt;xsl:value-of select="preceding-sibling::key[position()=1]/text()" /&amp;gt;&lt;br /&gt;        &amp;lt;/xsl:attribute&amp;gt;&lt;br /&gt;      &amp;lt;/xsl:if&amp;gt;&lt;br /&gt;      &amp;lt;xsl:apply-templates select="* | @* | node()" /&amp;gt;&lt;br /&gt;    &amp;lt;/xsl:copy&amp;gt;&lt;br /&gt;  &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template match="key" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;For an example, let's take another look at the sample XML I showed earlier and compare that with the &lt;i&gt;XML sexiness&lt;/i&gt; that is generated by applying my stylesheet against it (some spacing was added to the "after" version to better illustrate how they compare to each other):&lt;table border="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align="center"&gt;Before&lt;/th&gt;&lt;th align="center"&gt;After&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;pre&gt;&amp;lt;plist version="1.0"&amp;gt;&lt;br /&gt;&amp;lt;dict&amp;gt;&lt;br /&gt;  &amp;lt;key&amp;gt;AdiumSetVersion&amp;lt;/key&amp;gt;&lt;br /&gt;  &amp;lt;integer&amp;gt;1&amp;lt;/integer&amp;gt;&lt;br /&gt;  &amp;lt;key&amp;gt;Emoticons&amp;lt;/key&amp;gt;&lt;br /&gt;  &amp;lt;dict&amp;gt;&lt;br /&gt;    &amp;lt;key&amp;gt;amazing.png&amp;lt;/key&amp;gt;&lt;br /&gt;    &amp;lt;dict&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Equivalents&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;array&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;=-o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;=-O&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-O&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Name&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;string&amp;gt;Surprised&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    &amp;lt;key&amp;gt;anger.png&amp;lt;/key&amp;gt;&lt;br /&gt;    &amp;lt;dict&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Equivalents&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;array&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;:o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-@&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:@&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;X(&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Name&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;string&amp;gt;Angry&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    &amp;lt;key&amp;gt;bad_egg.png&amp;lt;/key&amp;gt;&lt;br /&gt;    &amp;lt;dict&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Equivalents&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;array&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;-[&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;-(&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;Name&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;string&amp;gt;Nervous&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    (...snip...)&lt;br /&gt;  &amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/plist&amp;gt;&lt;/pre&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;pre&gt;&amp;lt;plist version="1.0"&amp;gt;&lt;br /&gt;&amp;lt;dict&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;integer key="AdiumSetVersion"&amp;gt;1&amp;lt;/integer&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;dict key="Emoticons"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;dict key="amazing.png"&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;array key="Equivalents"&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;=-o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;=-O&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-O&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;string key="Name"&amp;gt;Surprised&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;dict key="anger.png"&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;array key="Equivalents"&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;:o&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:-@&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;:@&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;X(&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;string key="Name"&amp;gt;Angry&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;dict key="bad_egg"&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;array key="Equivalents"&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;-[&amp;lt;/string&amp;gt;&lt;br /&gt;        &amp;lt;string&amp;gt;&amp;amp;gt;-(&amp;lt;/string&amp;gt;&lt;br /&gt;      &amp;lt;/array&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;string key="Name"&amp;gt;Nervous&amp;lt;/string&amp;gt;&lt;br /&gt;    &amp;lt;/dict&amp;gt;&lt;br /&gt;    (...snip...)&lt;br /&gt;  &amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/plist&amp;gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;...isn't &lt;i&gt;that&lt;/i&gt; a sight for sore eyes?  You're welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-376978462672591899?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/376978462672591899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=376978462672591899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/376978462672591899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/376978462672591899'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/10/apple-sucks-at-xml.html' title='Apple sucks at XML'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1684454206997263682</id><published>2008-09-03T23:30:00.002-04:00</published><updated>2008-09-03T23:30:00.808-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='1625'/><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='oss'/><category scheme='http://www.blogger.com/atom/ns#' term='platform'/><category scheme='http://www.blogger.com/atom/ns#' term='add-ons'/><category scheme='http://www.blogger.com/atom/ns#' term='error'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='egg'/><category scheme='http://www.blogger.com/atom/ns#' term='minimum'/><category scheme='http://www.blogger.com/atom/ns#' term='extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='plug-ins'/><category scheme='http://www.blogger.com/atom/ns#' term='font'/><category scheme='http://www.blogger.com/atom/ns#' term='size'/><category scheme='http://www.blogger.com/atom/ns#' term='verdana'/><title type='text'>The world in Verdana</title><content type='html'>OK, by now &lt;i&gt;everybody&lt;/i&gt; and their cat has heard about Google Chrome.  The general buzz on Slashdot and blogs seems to be "it's not Firefox" and, more specifically, a general lament of the &lt;a href="http://www.joelonsoftware.com/articles/fog0000000054.html"&gt;chicken and egg problem&lt;/a&gt; surrounding the release of a new platform when there isn't any software (in this case "plug-ins" or "add-ons") to run on it.  Well, OK, &lt;a href="http://www.google.com/support/chrome/bin/answer.py?answer=95697"&gt;there are &lt;i&gt;some&lt;/i&gt; Chrome plug-ins available&lt;/a&gt;, but &lt;a href="http://www.google.com/support/chrome/bin/answer.py?answer=95695&amp;topic=14683"&gt;Chrome &lt;i&gt;extensions&lt;/i&gt; are currently NOT supported&lt;/a&gt;.  On the other hand, &lt;a href="http://dev.chromium.org/developers/how-tos/getting-started"&gt;the source code is out there&lt;/a&gt; and given that it has the "Google brand", it won't be hard to find motivated geeks hacking some neat software to [eventually] bring Chrome on par with Firefox, with said geeks' hidden agenda of being noticed by Google and be offered a nice googlejob where they get to sit on their &lt;a href="http://www.joelonsoftware.com/items/2007/09/18.html"&gt;googlechair&lt;/a&gt;, etc.&lt;br /&gt;&lt;br /&gt;It's technically not such a &lt;a href="http://www.joelonsoftware.com/articles/fog0000000011.html"&gt;bad chicken-and-egg situation&lt;/a&gt;, with the &lt;a href="http://blogoscoped.com/google-chrome/9"&gt;massive&lt;/a&gt; and &lt;a href="http://blogoscoped.com/google-chrome/10"&gt;thorough&lt;/a&gt; testing Google [claims to] have performed.  Plus, the browser is more than a fine replacement for users of Internet Explorer or &lt;i&gt;plain, out-of-the-box&lt;/i&gt; Firefox, thus making all us geeks appear crazy when non-techies ask us why &lt;i&gt;we're&lt;/i&gt; not using Google Chrome, when we use &lt;a href="http://labs.google.com/"&gt;everything else Google throws at us&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Anyway, I didn't set out to write &lt;i&gt;yet another review&lt;/i&gt;, but to post &lt;b&gt;solutions to problems I encountered&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Installing Chrome as a non-administrator&lt;/h2&gt;&lt;br /&gt;I hit issue 119 ( &lt;a href="http://code.google.com/p/chromium/issues/detail?id=119"&gt;Install Fails on W2K8 with low-rights user&lt;/a&gt; ) when I tried to install on my computer as a non-administrator and got the following:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_QvEDZGglpqE/SL9RFAGvVEI/AAAAAAAAACg/DcEXQ9jusjU/s1600-h/ChromeSetupError1625.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_QvEDZGglpqE/SL9RFAGvVEI/AAAAAAAAACg/DcEXQ9jusjU/s400/ChromeSetupError1625.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241997637652010050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thankfully, the &lt;a href="http://code.google.com/p/chromium/issues/detail?id=119#c6"&gt;work-around by stephen.oakman in comment 6&lt;/a&gt; worked and I found the elusive &lt;tt&gt;chrome_installer.exe&lt;/tt&gt; in a folder matching the pattern &lt;b&gt;C:\Documents and Settings\[user]\Local Settings\Application Data\Google\Update\Download\[guid]\chrome_installer.exe&lt;/b&gt; and was able to install it successfully.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Setting the minimum font size&lt;/h2&gt;&lt;br /&gt;I also had the same &lt;a href="http://asocialstudies.wordpress.com/2008/09/02/google-chrome-lacks-something/"&gt;accessibility lament&lt;/a&gt; about minimum font sizes and font family overrides.  For example, here is the &lt;a href="http://dev.chromium.org/developers/how-tos/getting-started"&gt;Getting Started&lt;/a&gt; page in Firefox 2, with Verdana @ 14pt bliss:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_QvEDZGglpqE/SL9RiEuq6hI/AAAAAAAAACw/9YXeyond7uM/s1600-h/Firefox2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_QvEDZGglpqE/SL9RiEuq6hI/AAAAAAAAACw/9YXeyond7uM/s400/Firefox2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241998137109441042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;...and this is what Chrome gave me with the same page:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_QvEDZGglpqE/SL9RV90TLtI/AAAAAAAAACo/f72jrAlB0pU/s1600-h/ChromeBefore.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_QvEDZGglpqE/SL9RV90TLtI/AAAAAAAAACo/f72jrAlB0pU/s400/ChromeBefore.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241997929095573202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;OK, yes, the Firefox version looks weird with the title text not lining up with the logo, etc. but all the &lt;i&gt;content&lt;/i&gt; is perfectly legible, which is more important to me.  Well, more legible than the fonts picked by the web developer.&lt;br /&gt;&lt;br /&gt;Thankfully, I have solved the first half the problem with a few quick searches in the source code and now my &lt;b&gt;C:\Documents and Settings\[user]\Local Settings\Application Data\Google\Chrome\User Data\Default\Preferences&lt;/b&gt; file contains this little gem:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   "webkit": {&lt;br /&gt;      "webprefs": {&lt;br /&gt;         "cursive_font_family": "Verdana",&lt;br /&gt;         "default_fixed_font_size": 14,&lt;br /&gt;         "default_font_size": 14,&lt;br /&gt;         "fantasy_font_family": "Verdana",&lt;br /&gt;         "fixed_font_family": "Courier New",&lt;br /&gt;         "minimum_font_size": 14,&lt;br /&gt;         "minimum_logical_font_size": 14,&lt;br /&gt;         "sansserif_font_family": "Verdana",&lt;br /&gt;         "serif_font_family": "Verdana"&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;...which gives me a slight improvement in readability in Chrome:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_QvEDZGglpqE/SL9Rp8x73JI/AAAAAAAAAC4/ZkRMiZO1rQ8/s1600-h/ChromeAfter.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_QvEDZGglpqE/SL9Rp8x73JI/AAAAAAAAAC4/ZkRMiZO1rQ8/s400/ChromeAfter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241998272414604434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can find out what the names of the [other] supported hidden preferences are by peeking into &lt;a href="http://src.chromium.org/svn/trunk/src/chrome/common/pref_names.cc"&gt;chrome/common/pref_names.cc&lt;/a&gt; and cross-referencing with WebContents::GetWebkitPrefs() in &lt;a href="http://src.chromium.org/svn/trunk/src/chrome/browser/web_contents.cc"&gt;chrome/browser/web_contents.cc&lt;/a&gt;.  In particular, you'll find (as of this writing) that the other half of my problem is already identified in a comment:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  // User CSS is currently disabled because it crashes chrome.  See&lt;br /&gt;  // webkit/glue/webpreferences.h for more details.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;...with the more details being:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  // TODO(tc): User style sheets will not work in chrome because it tries to&lt;br /&gt;  // load the style sheet using a request without a frame.&lt;br /&gt;  bool user_style_sheet_enabled;&lt;br /&gt;  GURL user_style_sheet_location;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;D'oh.  Maybe this will inspire someone else to fix that part of the code or otherwise provide the elusive "let me choose my own damn fonts" setting that I rely on for keeping my sight and posture in good shape.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1684454206997263682?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1684454206997263682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1684454206997263682' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1684454206997263682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1684454206997263682'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/09/world-in-verdana.html' title='The world in Verdana'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_QvEDZGglpqE/SL9RFAGvVEI/AAAAAAAAACg/DcEXQ9jusjU/s72-c/ChromeSetupError1625.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-7931825536422869239</id><published>2008-08-08T15:48:00.000-04:00</published><updated>2008-08-08T15:48:16.941-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='correctness'/><category scheme='http://www.blogger.com/atom/ns#' term='work ethic'/><category scheme='http://www.blogger.com/atom/ns#' term='job'/><title type='text'>Effort vs. Results</title><content type='html'>I remember having a conversation with my father when I was a kid about his company's employees.  I was &lt;em&gt;shocked&lt;/em&gt; to discover they were being paid &lt;strong&gt;by the hour&lt;/strong&gt;.  I remember following up with a question along the lines of &lt;em&gt;"Wouldn't that encourage them to take lots of time to do their work?"&lt;/em&gt;  He assured me that, although it was a possibility, it didn't happen very often. (and presumably he explained that people who did that could lose their job, so it was to their long-term advantage to not slack off)&lt;br /&gt;&lt;br /&gt;Fast forward a few years later, when I'm in high-school and a student asks the teacher - after she explained a homework assignment - if any marks would be given for effort.  I couldn't help but laugh out loud, thinking he was pulling the teacher's leg.  He didn't join me in laughing or smiling (and probably shot me a dirty look).  Uh oh.  He was &lt;em&gt;serious&lt;/em&gt;!?!?&lt;br /&gt;&lt;br /&gt;Maybe I found that proposition silly because I figured there was no way for it to be reliably measured:  it would have to be self-reported.  How hard would it be to say "I spent 100 hours on this" when handing it in?  And if I had completed the assignment in 10 hours and produced equivalent results to his, would that mean he would get more marks than I got because he spent more time??  Worse yet, even if it wasn't self-reported, how &lt;em&gt;would&lt;/em&gt; it be measured???  And what about the &lt;a href="http://www.google.ca/search?q=%22brain+time%22+%22body+time%22"&gt;difference between "brain time" and "body time"&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Nowadays, I understand why &lt;a href="http://www.paulgraham.com/gap.html"&gt;people are [usually] compensated by how much their skills are in demand&lt;/a&gt; and that &lt;a href="http://www.joelonsoftware.com/articles/HighNotes.html"&gt;it is possible to be 10 times better&lt;/a&gt; than someone else at what you do.  Maybe I also did as a kid?  That might explain my reaction in both instances.  Could it also explain my drive for correctness?  My passion for getting things done and done right??  Now here's a doozy for you: would this knowledge at a younger age have helped other students???  Or maybe I'm just being arrogant and that I should just shut up for being the nerd that didn't have any trouble with his assignments????&lt;br /&gt;&lt;br /&gt;Discuss.&lt;br /&gt;&lt;br /&gt;P.S.:  Please go easy on me as I have been working on this blog post since November and it's only now that I have been able to finish it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-7931825536422869239?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/7931825536422869239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=7931825536422869239' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7931825536422869239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7931825536422869239'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/08/effort-vs-results.html' title='Effort vs. Results'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-570843692647845678</id><published>2008-07-26T00:30:00.003-04:00</published><updated>2008-07-26T00:38:32.534-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='vs'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>I got in a "jam"...</title><content type='html'>Round 1A of &lt;a href="http://code.google.com/codejam/contest/"&gt;Google's Code Jam&lt;/a&gt; programming contest (in which I participated) ended about an hour-and-a-half ago (there are three sub-rounds of Round 1 and contestants can compete in two of them to try to move on to Round 2).&lt;br /&gt;&lt;br /&gt;A failure (on my part) to pay close attention to the requirements of the first problem meant I implemented an algorithm with a complexity of &lt;code&gt;O(n! * n!)&lt;/code&gt;, which means 25 401 600 iterations for &lt;code&gt;n = 7&lt;/code&gt; (sort of reasonable) but &lt;b&gt;1 625 702 400 iterations&lt;/b&gt; for &lt;code&gt;n = 8&lt;/code&gt;, something my laptop wouldn't be able to finish in any reasonable amount of time.  It's much worse when you consider that &lt;b&gt;n was expected to go as high as 800&lt;/b&gt;!  Once I read that, it occurred to me that I had been going at it entirely the wrong way...  About &lt;em&gt;an hour-and-a-half of going the wrong way&lt;/em&gt;, which involved implementing (and debugging) a nice "permute the items of this list" method.&lt;br /&gt;&lt;br /&gt;You see, there was a trick to the problem.  Once I realized this, I replaced the double permutation loop with two calls to Sort() and a single &lt;code&gt;O(n)&lt;/code&gt; loop.   D'oh!  My solution to the small input was judged as correct, so I proceeded to the large input.  It ran just as fast and so I submitted its output, too.  Well, again, I screwed up with the requirements and it turns out my math was overflowing left, right and center and thus, when the contest ended, I got a measly 5 points (out of a possible 15 for that problem and out of a possible 100 for all 3 problems!), which means I ranked 2363 out of 2394.  (you don't find out if your submission to the large version is correct until the end of the contest - I also only attempted the first problem)&lt;br /&gt;&lt;br /&gt;Oh, well...  I might try again in Round 1C (Sunday at 05:00 local time!), but in the meantime I thought I'd publish some of the source code that came out of this.  I used Visual Studio 2008, which meant I could try out the neat features of the C# that came out with .NET 3.5, such as:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the &lt;code&gt;var&lt;/code&gt; keyword&lt;/li&gt;&lt;li&gt;extension methods&lt;/li&gt;&lt;li&gt;LINQ&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;OK, so I didn't need to use LINQ, nor did I use extension methods until &lt;em&gt;after&lt;/em&gt; the contest, but here's my touched-up &lt;code&gt;Permutations&lt;/code&gt; iterator method, generalized to any &lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt; instance:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;public static class Extension {&lt;br /&gt;  public static IEnumerable&amp;lt;IList&amp;lt;T&amp;gt;&amp;gt; Permutations&amp;lt;T&amp;gt; ( this IList&amp;lt;T&amp;gt; input ) {&lt;br /&gt;    int numElements = input.Count;&lt;br /&gt;    var slotOffsets = new int[numElements];&lt;br /&gt;    var slotBusy = new bool[numElements];&lt;br /&gt;    bool allDone = false;&lt;br /&gt;    while ( !allDone ) {&lt;br /&gt;      #region Set slotBusy flags to false&lt;br /&gt;      for ( int i = 0; i &amp;lt; numElements; i++ ) {&lt;br /&gt;        slotBusy[i] = false;&lt;br /&gt;      }&lt;br /&gt;      #endregion&lt;br /&gt;&lt;br /&gt;      IList&amp;lt;T&amp;gt; permutation = new List&amp;lt;T&amp;gt; ( numElements );&lt;br /&gt;      int lastSelected = -1;&lt;br /&gt;      for ( int i = 0; i &amp;lt; numElements; i++ ) {&lt;br /&gt;        for ( int j = 0; j &amp;lt; numElements; j++ ) {&lt;br /&gt;          int selectedSlot = ( lastSelected + 1 + j + slotOffsets[i] ) % numElements;&lt;br /&gt;          if ( !slotBusy[selectedSlot] ) {&lt;br /&gt;            slotBusy[selectedSlot] = true;&lt;br /&gt;            permutation.Add ( input[selectedSlot] );&lt;br /&gt;            lastSelected = selectedSlot;&lt;br /&gt;            break;&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      yield return permutation;&lt;br /&gt;&lt;br /&gt;      #region Update offsets&lt;br /&gt;      for ( int i = 0; i &amp;lt; numElements; i++ ) {&lt;br /&gt;        slotOffsets[i]++;&lt;br /&gt;        if ( slotOffsets[i] &amp;lt; ( numElements - i ) ) {&lt;br /&gt;          break;&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;          if ( i == numElements - 1 ) {&lt;br /&gt;            allDone = true;&lt;br /&gt;          }&lt;br /&gt;          else {&lt;br /&gt;            slotOffsets[i] = 0;&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      #endregion&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;...which you can use as follows (notice how it's magically a method on any IList&amp;lt;&amp;gt; implementation?):&lt;br /&gt;&lt;code&gt;&lt;pre&gt;IList&amp;lt;int&amp;gt; inputList = new List&amp;lt;int&amp;gt; ( new int[] { 1, 2, 3 } );&lt;br /&gt;foreach ( List&amp;lt;int&amp;gt; permutation in inputList.Permutations ( ) ) {&lt;br /&gt;  StringBuilder sb = new StringBuilder ( );&lt;br /&gt;  sb.Append ( "[" );&lt;br /&gt;  bool isFirst = true;&lt;br /&gt;  foreach ( var item in permutation ) {&lt;br /&gt;    if ( !isFirst ) {&lt;br /&gt;      sb.Append ( ", " );&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;      isFirst = false;&lt;br /&gt;    }&lt;br /&gt;    sb.Append ( item );&lt;br /&gt;  }&lt;br /&gt;  sb.Append ( "]" );&lt;br /&gt;  Console.WriteLine ( sb.ToString() );&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;...and it should produce the following output:&lt;br /&gt;&lt;pre&gt;[1, 2, 3]&lt;br /&gt;[2, 3, 1]&lt;br /&gt;[3, 1, 2]&lt;br /&gt;[1, 3, 2]&lt;br /&gt;[2, 1, 3]&lt;br /&gt;[3, 2, 1]&lt;/pre&gt;&lt;br /&gt;I just wish I had prepared this method &lt;em&gt;before&lt;/em&gt; the contest, although I think some actual practice in solving these kinds of problems would have helped me more.  Maybe next time... :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-570843692647845678?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/570843692647845678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=570843692647845678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/570843692647845678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/570843692647845678'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/07/i-got-in-jam.html' title='I got in a &quot;jam&quot;...'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-7800459772947714730</id><published>2008-06-10T22:00:00.001-04:00</published><updated>2008-06-10T22:20:11.511-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oss'/><category scheme='http://www.blogger.com/atom/ns#' term='shameless plug'/><category scheme='http://www.blogger.com/atom/ns#' term='announcement'/><title type='text'>Announcing the web-screen-saver project</title><content type='html'>I &lt;i&gt;finally&lt;/i&gt; got around to posting a little tidbit of source code I had lying around on my computer as the new open-source project &lt;a href="http://web-screen-saver.googlecode.com/"&gt;web-screen-saver&lt;/a&gt; (really lame name, I know).  Not only that, but the premise seems a bit lame, too.  Who would want a screen-saver that runs in their web browser?&lt;br /&gt;&lt;br /&gt;It turns out &lt;b&gt;I&lt;/b&gt; do!  I have been learning about aviation weather and the &lt;i&gt;best&lt;/i&gt; way to stay fresh is to practice every day, so I took a &lt;i&gt;really&lt;/i&gt; old Toshiba laptop (Pentium MMX @ 166 MHz, 16 MB RAM and a 2.1 GB HD), got it running again (which involved &lt;strike&gt;soldering&lt;/strike&gt; &lt;i&gt;&lt;a href="http://www.google.com/search?q=frankensteining"&gt;frankensteining&lt;/a&gt;&lt;/i&gt; an equally-as-old power supply from a Futjitsu laptop, not to mention putting the disassembled laptop back together from memory) and set it on top of my refrigerator.  This way, whenever I'm preparing meals, washing dishes, feeding the cat, etc. in the kitchen, I can take a minute or so to browse the latest weather.&lt;br /&gt;&lt;br /&gt;Next up was figuring out how to get various semi-frequently-updated images to show up on the screen on a cycle.  Various options popped up, such as:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;a &lt;code&gt;cron&lt;/code&gt; job that would trigger &lt;code&gt;wget&lt;/code&gt; on a few URLs with one of:&lt;br /&gt;    &lt;ol&gt;&lt;br /&gt;      &lt;li&gt;a companion program that would convert the HTML pages to images and rescale pure images appropriately and a corresponding client (any of many file-system-based screen-savers)&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;a static page that would cycle the &lt;i&gt;pre-downloaded&lt;/i&gt; pages or images using a bit of JavaScript&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;a number of static pages that serve up one &lt;i&gt;pre-downloaded&lt;/i&gt; page or image for a little bit of time before redirecting to the next&lt;/li&gt;&lt;br /&gt;    &lt;/ol&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;a static page that would cycle the &lt;i&gt;live&lt;/i&gt; pages or images using a bit of JavaScript&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;a number of static pages that serve up one &lt;i&gt;live&lt;/i&gt; page or image for a little bit of time before redirecting to the next&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Some of the above options don't make that much sense until you consider that aviation weather is the kind of information that's sensitive to updates (or the lack thereof) and so it is of the utmost importance to always have the latest version of, say, a TAF or a GFA cloud &amp; weather map.  With some web browsers reportedly overzealously caching pages or images coupled with sometimes unreliable internet connections, I was trying to explore the space of options so that I could potentially detect the worse case and do something about it.&lt;br /&gt;&lt;br /&gt;I ended up deciding to see whether the current browsers that I use/care about indeed [still] suffered from that problem, since it would eliminate an entire class of problems/solutions.  Turns out that &lt;b&gt;improper browser caching no longer appears to be a problem&lt;/b&gt;, although this could also be due to proper &lt;strike&gt;configuration&lt;/strike&gt; programming at the server end.  That, and the prospect of having to write client-server code that scanned files coming from remote computers sounded more stupid every second I continued to think about it since, you know, &lt;b&gt;web browsers do that sort of thing already!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A few evenings of light programming (i.e. tweaking a few lines of code here and there during a few boring moments of TV watching) and I've got what I think is "version 1.0"-worthy.  It's running right now on the trusty laptop in Internet Explorer 6&lt;sup&gt;&lt;a href="#web-screen-saver-note1"&gt;[1]&lt;/a&gt;&lt;/sup&gt; in full-screen mode (hide the status bar, hit F11, then right-click on the toolbars to select auto-hide), although with this much RAM it just swaps and thrashes like hell for a minute or two on every reload.  I also need to reboot it every so often because the USB wireless adapter's driver is as stable as the U.S. economy.  &lt;b&gt;*cough*&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Download&lt;/h2&gt;&lt;br /&gt;Download version 1.0: &lt;a href="http://web-screen-saver.googlecode.com/files/awesome-web-screen-saver-1.0.html"&gt;awesome-web-screen-saver-1.0.html&lt;/a&gt;.&lt;br /&gt;View source of version 1.0: &lt;a href="http://web-screen-saver.googlecode.com/svn/tags/web-screen-saver-1.0/index.html"&gt;index.html&lt;/a&gt;&lt;br /&gt;Live demo (latest version): &lt;a href="http://web-screen-saver.googlecode.com/svn/trunk/index.html"&gt;Aviation Weather Electronic Summary Of Major Events&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;How to use&lt;/h2&gt;&lt;br /&gt;Once everything loads, all but the first page/image will be "hidden" (it's really a &lt;strike&gt;clever&lt;/strike&gt; lame container resizing trick).   After 2 minutes, the next page/image will be shown, etc. until about 33 minutes at which point the whole thing will reload.  You can, of course, scroll up and down, but you may want to use the left and right arrow keys, since they are programmed to jump back and forward (respectively) at page/image boundaries.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Roadmap for future versions&lt;/h2&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;JavaScript code to live in its own file&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;META-based refresh to be adjusted based on the number of "pages"&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;better handling of unavailable content (i.e. keep retrying - with suitable back-off - iframes or images that returned anything other than HTTP 200)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;use Google App Engine for the following features:&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;      &lt;li&gt;configurable content profiles (i.e. pick your own frequently-changing content)&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;content caching (i.e. Google's servers can withstand more hits and will probably replicate content to various globally-distributed data centers for higher availability)&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;content download scheduling (i.e. while you have both of the previous two features, you might as well configure content with an expected lifetime or scheduled release, so that it is only pulled &lt;i&gt;once&lt;/i&gt;, per publishing, from its source)&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;stats collection&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;general geekiness&lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Notes&lt;/h2&gt;&lt;br /&gt;&lt;sup&gt;&lt;a name="web-screen-saver-note1"&gt;&lt;/a&gt;[1]&lt;/sup&gt; This will probably cost me a few geek points, but the laptop is &lt;i&gt;still&lt;/i&gt; running the Windows 98 copy it came with - I couldn't get any GNU/Linux distro to boot/install and I have better things to do with my time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-7800459772947714730?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/7800459772947714730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=7800459772947714730' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7800459772947714730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7800459772947714730'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/06/announcing-web-screen-saver-project.html' title='Announcing the web-screen-saver project'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1676906338398853009</id><published>2008-05-08T21:27:00.005-04:00</published><updated>2008-05-08T21:44:34.819-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='annoying'/><title type='text'>"I must use this power only to annoy"</title><content type='html'>I clicked on an Amazon link to a product the other day and it lead me to &lt;a href="http://www.amazon.com/gp/product/B000JV6TQY"&gt;its product page&lt;/a&gt;.  Everything there is fine, except instead of a price, there was a link that read "Click here to see the price".  There was also another link that read &lt;a href="http://www.amazon.com/gp/product/help/help.html/ref=map_popup?ie=UTF8&amp;topic=map"&gt;(Why don't we show the price?)&lt;/a&gt; which contained the following text:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;br /&gt;&lt;b&gt;Why Don't We Show the Price?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Manufacturers sometimes ask that retailers not display a price if it drops below a certain amount. The "click here to see price" message indicates that the price of the item is so low that the manufacturer requested that it not be advertised (that is, displayed). In a brick-and-mortar store, you would probably have to ask a salesperson what the price of the product is. At Amazon, by clicking on "click here to see price" you are essentially asking to see the price, at which point we show it to you.&lt;br /&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Ummm... WTF?  If I didn't see a price in a brick-and-mortar store, &lt;b&gt;I wouldn't buy the item&lt;/b&gt;!  You forcing me to click just to replicate that have-to-ask experience is forcing me to replicate my wouldn't-buy-the-item reaction.  I hope you're happy about &lt;a href="http://www.useit.com/alertbox/user-skills.html"&gt;your lost sale&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1676906338398853009?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1676906338398853009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1676906338398853009' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1676906338398853009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1676906338398853009'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/05/i-must-use-this-power-only-to-annoy.html' title='&quot;I must use this power only to annoy&quot;'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-5215227625311251558</id><published>2008-04-29T22:19:00.001-04:00</published><updated>2008-04-30T08:27:31.922-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meta-blogging'/><category scheme='http://www.blogger.com/atom/ns#' term='meme'/><category scheme='http://www.blogger.com/atom/ns#' term='job'/><title type='text'>Hi-tech alumni</title><content type='html'>What appeared to be a joke article at first glance (Cravath sounds like the &lt;a title="french word for a tie" href="http://www.google.ca/search?q=cravate"&gt;french word for a tie&lt;/a&gt;) turned out to be &lt;a title="Up or Out: Solving the IT Turnover Crisis" href="http://thedailywtf.com/Articles/Up-or-Out-Solving-the-IT-Turnover-Crisis.aspx"&gt;a very insightful post by Alex&lt;/a&gt; on the topic of quitting and more generally about the habits of a certain class of software developers.  I couldn't agree more!  In fact, I have found myself proud to announce to my peers that I have worked at Microsoft and Macadamian; that I'm an alumnus or a graduate of sorts from their respective schools [of thought], that I embody some/most of their best practices and serve as a kind of unofficial ambassador.&lt;br /&gt;&lt;br /&gt;I can relate to the &lt;a title="How Open Source Projects Survive Poisonous People (And You Can Too)" href="http://video.google.com/videoplay?docid=-4216011961522818645"&gt;"bus factor" concept&lt;/a&gt; and can even suggest a tangible metric:  fantastic developers (who are thus likely to quit) are usually top contributors to corporate wikis, since they are constantly externalizing their knowledge for future colleagues/replacements.  This, ironically, increases their value since they can spend more of their [precious] time solving new problems instead of being constantly disturbed for knowledge and acting as a "walking wiki" (which Alex calls "unskilled people").  It's not hard to see how true synergy is achieved by having all documentation at everybody's fingertips. &lt;i&gt;This&lt;/i&gt;&lt;/span&gt; is what Bill Gates called a Digital Nervous System.&lt;br /&gt;&lt;br /&gt;The next logical step to documenting is automating.  So even if you feel your "bus factor" is low because everything is documented and your team spends a lot/most of their time solving new problems (which is, by itself, &lt;a title="If They Come, How Will They Build It?" href="http://www.hacknot.info/hacknot/action/showEntry?eid=97"&gt;an excellent start&lt;/a&gt;) documented AND &lt;a title="Daily Builds Are Your Friend" href="http://www.joelonsoftware.com/articles/fog0000000023.html"&gt;automated processes&lt;/a&gt; are the true mark of excellent talent.&lt;br /&gt;&lt;br /&gt;So, in the spirit of the topic, &lt;i&gt;I will quit my job (and there's nothing wrong with that&lt;/i&gt;), but I just haven't decided when.  And if I start a company, I &lt;i&gt;will&lt;/i&gt; include a link to this article in the corporate wiki.&lt;br /&gt;&lt;br /&gt;P.S.:  I'm posting this to my blog from Google Docs.  I had this idea that it would be great to be able to do so and, lo and behold, there it was, under &lt;code&gt;Share/Publish as web page...&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt;  Ok, it posted, but without a title and the HTML was definitely not clean, but it's a start.  I probably just need to tweak a few styles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-5215227625311251558?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/5215227625311251558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=5215227625311251558' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/5215227625311251558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/5215227625311251558'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/04/what-appeared-to-be-joke-article-at.html' title='Hi-tech alumni'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8995042144229829019</id><published>2008-02-29T15:59:00.001-05:00</published><updated>2008-02-29T16:01:28.841-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='olpc'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='xo'/><title type='text'>PalmPilot Jr</title><content type='html'>Having received my XO's developer key, I immediately upgraded the operating system to build number "Joyride 1638", using one of those "USB-based memory sticks".  The large PDA/small laptop now appears to switch to some form of low-power mode whenever the lid is closed, when in "Reader mode" and in the middle of yum-based downloads.  A tad too aggressive, if you ask me, but that's life when installing unstable software.  It may have had something to do with having the Reader activity opened at the same time, but in any case, I don't think suspending is necessary when the laptop is plugged in.  Maybe it would be OK after a much longer timeout, say 10 minutes.&lt;br /&gt;&lt;br /&gt;Other than that, the new power management features (coming from build 653 -- which I think had absolutely none, except maybe for the "blank screen" screensaver -- these features are totally new) are really spiffy, and allowed me to go from a full charge this morning and still be going after a ride on the bus, followed by a full day of work (where it spent most of that time closed up).  Hmmm...  Maybe I didn't explain that correctly, so I'll switch to rough pseudo-code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; laptop.powerMode = PowerMode.OnBattery;&lt;br /&gt; laptop.radio = RadioMode.Off;&lt;br /&gt; me.use ( laptop, 30 /* minutes */ );&lt;br /&gt; laptop.powerMode = PowerMode.Suspend;&lt;br /&gt; Thread.sleep ( 1000 * 60 * 60 * 8 /* 8 hours in milliseconds */ );&lt;br /&gt; laptop.powerMode = PowerMode.OnBattery;&lt;br /&gt; me.use ( laptop, 30 /* minutes */ );&lt;br /&gt; // because I didn't have to shutdown and boot up the laptop again&lt;br /&gt; me.mood = Mood.Happy;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;...there.  I swear those "I write code" t-shirts were invented for me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway, there are still a few quirks, but the software is definitely getting there, which brings me to the whole point of this post:  the XO should [eventually] be sold around the world.  I'm thinking it could be ready and in all the stores where laptops and/or educational toys are normally sold (such as Walmart, Toys 'R' Us, ThinkGeek, Amazon.com, Future Shop, Best Buy, Fry's Electronics, Radio Shack, etc.) by next Christmas.&lt;br /&gt;&lt;br /&gt;This form of distribution could expand their user base in a way that's not too dissimilar to the G1G1 program, minus the &lt;a href="http://hardware.slashdot.org/article.pl?sid=08/01/25/0625206"&gt;logistics nightmares associated with selling and shipping 80 000 units individually&lt;/a&gt;.  This way, they ship say, 250 000 units in chunks of 10 or 20 thousand to a few retailers with established distribution channels and the foundation can then focus their efforts on what they do best (designing and building the laptop, marketing to governments of poor countries, etc.), instead of trying to also be a mass-distributor.&lt;br /&gt;&lt;br /&gt;Of course, this assumes that the sale of XOs at retail would bring enough revenue to not only make this affordable to the foundation, but also to make money.  I don't think they could pitch it for $400 (as in the G1G1 campaign) with a straight face (some Acer laptops are available now for $600), but they could probably do it for less than $200.  At that price, they are starting to compete with other educational toys, as well as traditional PDAs that also come with a keyboard, word processing software, a web browser and an extended battery life.&lt;br /&gt;&lt;br /&gt;I'm totally serious about this:  it could be the source of volume they have been after to bring the price of the units down, not to mention the associated network effects.  Think of it this way:  as a parent, would you rather get your child an expensive, fragile computer made for adults or an inexpensive, rugged computer made for kids?  ("hand-me-down clunkers" and sources of free tech support notwithstanding)  How many people missed out due to the G1G1 campaign's short lifespan or high barrier of entry (i.e. you &lt;i&gt;must&lt;/i&gt; create a PayPal account - even though the error message only said your credit card was not valid - and then have it authorized for large amounts - which means having it linked to a bank account - on top of the amateur-looking website and the uncertainty of shipping dates, etc.)?&lt;br /&gt;&lt;br /&gt;Let's hope they read my blog and credit me after the associated success boom from implementing my master plan.  You're welcome.  :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8995042144229829019?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8995042144229829019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8995042144229829019' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8995042144229829019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8995042144229829019'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/02/palmpilot-jr.html' title='PalmPilot Jr'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1364533177589345274</id><published>2008-01-29T21:25:00.000-05:00</published><updated>2008-01-29T21:26:01.818-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meta-blogging'/><category scheme='http://www.blogger.com/atom/ns#' term='olpc'/><category scheme='http://www.blogger.com/atom/ns#' term='testoriented'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='xo'/><title type='text'>Blogging resumes (and other news)</title><content type='html'>After far too long of not blogging, I have arranged the circumstances to make it more likely I would blog through the use of an innovative concept I like to call "Blogging on the bus".  Such a thing is now possible since the arrival of my late Christmas/early birthday present: an XO laptop (and about an hour of travel by bus to/from work every weekday).&lt;br /&gt;&lt;br /&gt;I participated in the &lt;a href="http://www.laptopgiving.org/en/index.php"&gt;G1G1&lt;/a&gt; (give one, get one) &lt;a href="http://hardware.slashdot.org/hardware/07/11/12/138246.shtml"&gt;campaign&lt;/a&gt; and received the small laptop/large PDA device shortly two months after ordering it.  Apart from being too small to allow me to touchtype, I really like it.  It should be at least faster to write with than with my crusty old Palm III and also easier to read RSS feeds, etc. than same.  I'm not sure I have figured out how to have it sleep and wake up (suspend/resume) really fast like my Palm did (thus never having to boot up/shutdown), but the &lt;a href="http://wiki.laptop.org/go/Home"&gt;OLPC wiki&lt;/a&gt; is nice and should have the answer.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE:&lt;/b&gt;  The software that shipped with my unit does not support this yet:&lt;br /&gt;&lt;a href="http://wiki.laptop.org/go/Support_FAQ#How_do_I_put_an_XO_laptop_to_sleep.3F"&gt;How do I put an XO laptop to sleep?&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The sleep feature is not enabled in software provided on XOs shipped starting December 2007 in the Give1Get1 program. A software upgrade early in 2008 will support suspend/resume sleep features, for much improved battery life.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also worthy of noting is the successful completion of the courses part of my master's program at Carleton University.  I now have to pick a decent topic and a supervisor to get started on this "other half".  I'm hoping to add neat features to T.O.D.D. (a.k.a. &lt;a href="http://testoriented.googlecode.com"&gt;testoriented&lt;/a&gt;), such as automatic testing, thus effectively putting me out of a day job. (ha ha)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lastly, I would like to thank everybody who left words of thanks for my posting about &lt;a href="http://oliiscool.blogspot.com/2006/11/hacking-microsoft-natural-ergonomic.html"&gt;Hacking the Microsoft Natural keyboard 4000, redux&lt;/a&gt;, as well as whoever drove all that traffic to my blog.  I think we now have enough evidence to say that Microsoft definitely shipped the wrong mapping for that slider.  I wonder if I should also start selling a little "Scroll" sticker (or, really, just a piece of electrical tape - such as &lt;a href="http://thedailywtf.com/Swag/Sticker-Patch-Kit.aspx"&gt;this patch kit&lt;/a&gt;) alongside a floppy disk containing an automated and friendly version of the software I had posted, calling it an "upgrade kit" of some sort.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1364533177589345274?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1364533177589345274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1364533177589345274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1364533177589345274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1364533177589345274'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2008/01/blogging-resumes-and-other-news.html' title='Blogging resumes (and other news)'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-4593768114436189916</id><published>2007-05-08T21:34:00.001-04:00</published><updated>2008-12-11T03:10:40.820-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meme'/><category scheme='http://www.blogger.com/atom/ns#' term='shameless plug'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Your code is suboptimal!</title><content type='html'>I'm a &lt;a href="http://www.joelonsoftware.com/articles/fog0000000050.html"&gt;sucker for t-shirts&lt;/a&gt;.  Since I'm a geek &lt;a href="http://it.slashdot.org/article.pl?sid=07/05/07/1235250"&gt;with too much time on my hands&lt;/a&gt;, I'm part of an &lt;a href="http://www.google.com/search?q=tech+blog"&gt;exclusive club&lt;/a&gt;.  Then, because I read &lt;a href="http://software.ericsink.com/"&gt;Eric Sink's Weblog&lt;/a&gt;, that makes me part of an even &lt;em&gt;exclusiver&lt;/em&gt; club.  Lastly, when I saw that Eric was &lt;a href="http://software.ericsink.com/entries/sdwest_trip_report.html"&gt;offering to send some of his excellent t-shirts&lt;/a&gt; to people who were willing to mimic the character in a &lt;em&gt;public&lt;/em&gt; photo plugging &lt;a href="http://sourcegear.com/"&gt;SourceGear&lt;/a&gt;'s upcoming &lt;a href="http://www.sourcegear.com/fortress/"&gt;Fortress&lt;/a&gt; software, I couldn't resist the opportunity to sign up. &lt;a href="http://www.snpp.com/episodes/DABF02"&gt;&lt;strike&gt;6-8&lt;/strike&gt; 4-6 weeks later&lt;/a&gt;, here it is!&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;The t-shirt with the "Evil Mastermind" saying "YOUR CODE IS SUBOPTIMAL!" is part of an &lt;a href="http://software.ericsink.com/entries/Mag_Ads_March2007.html"&gt;excellent marketing campaign&lt;/a&gt;.&lt;img src="http://software.ericsink.com/entries/1653_image001.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_QvEDZGglpqE/RkEXNPd46jI/AAAAAAAAAAw/nOLYAORfhiA/s1600-h/Suboptimal.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_QvEDZGglpqE/RkEXNPd46jI/AAAAAAAAAAw/nOLYAORfhiA/s400/Suboptimal.jpg" alt="" id="BLOGGER_PHOTO_ID_5062352972398783026" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-4593768114436189916?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/4593768114436189916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=4593768114436189916' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/4593768114436189916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/4593768114436189916'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/05/your-code-is-suboptimal.html' title='Your code is suboptimal!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_QvEDZGglpqE/RkEXNPd46jI/AAAAAAAAAAw/nOLYAORfhiA/s72-c/Suboptimal.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8239184072373685513</id><published>2007-04-01T13:58:00.000-04:00</published><updated>2008-12-11T03:10:41.019-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Please turn to page F%</title><content type='html'>I was reading the "Tech Weekly" section of a newspaper when I noticed that the staff are still typing page numbers by hand.  How else could you explain page F5  (with page F3 folded up under it), as &lt;a title="Web 0.1 on WorseThanFailure.com" href="http://worsethanfailure.com/Articles/Web_0_0x2e_1.aspx"&gt;illustrated in this scan of a printout of a picture of a wooden table&lt;/a&gt;?&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_QvEDZGglpqE/Rg_zEqCBtZI/AAAAAAAAAAo/48Do_6RLCtg/s1600-h/F%25+(500x824).jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_QvEDZGglpqE/Rg_zEqCBtZI/AAAAAAAAAAo/48Do_6RLCtg/s400/F%25+(500x824).jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5048520968633431442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; My submission to the &lt;a href="http://worsethanfailure.com/"&gt;Worse Than Failure&lt;/a&gt; website has finally &lt;a href="http://worsethanfailure.com/Articles/Please-Turn-to-Page-F-.aspx"&gt;appeared&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8239184072373685513?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8239184072373685513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8239184072373685513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8239184072373685513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8239184072373685513'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/04/please-turn-to-page-f.html' title='Please turn to page F%'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_QvEDZGglpqE/Rg_zEqCBtZI/AAAAAAAAAAo/48Do_6RLCtg/s72-c/F%25+(500x824).jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-7722322387453636766</id><published>2007-03-31T20:28:00.000-04:00</published><updated>2007-03-31T20:29:16.205-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vs registry editor'/><title type='text'>They're more like guidelines...</title><content type='html'>Finally!  An equivalent to SciTE's &lt;a href="http://scintilla.sourceforge.net/SciTEDoc.html"&gt;edge.*&lt;/a&gt; settings in Visual Studio!  Trouble is, it's not called "edge" or "margin" (Eclipse), but &lt;a href="http://www.imdb.com/title/tt0325980/quotes"&gt;"guidelines"&lt;/a&gt;.  No wonder I couldn't find anything on the topic when I was searching online!&lt;br /&gt;&lt;br /&gt;Thanks go out to Sara Ford who &lt;a href="http://blogs.msdn.com/saraford/archive/2004/05/05/257953.aspx"&gt;blogged about this wonderful feature&lt;/a&gt;.  If only I had known about this, oh, &lt;em&gt;three years&lt;/em&gt; ago!  :)&lt;br /&gt;&lt;br /&gt;Here you go.  Just copy/paste the following into a &lt;code&gt;.reg&lt;/code&gt; file and import it.  You can change the colour (currently a very pale green) and at which column you want it to show (currently at &lt;strong&gt;80&lt;/strong&gt;).  You can even add more columns apparently, but that's getting a little silly.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Windows Registry Editor Version 5.00&lt;br /&gt;&lt;br /&gt;[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Text Editor]&lt;br /&gt;"Guides"="RGB(192,220,192) 80"&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-7722322387453636766?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/7722322387453636766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=7722322387453636766' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7722322387453636766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/7722322387453636766'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/03/theyre-more-like-guidelines.html' title='They&apos;re more like guidelines...'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-87144316570415009</id><published>2007-02-26T16:57:00.000-05:00</published><updated>2007-02-26T17:08:57.244-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meme'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>My name</title><content type='html'>It looks like &lt;a href="http://ebersys.blogspot.com/"&gt;Eber Irigoyen&lt;/a&gt; &lt;a href="http://ebersys.blogspot.com/2007/02/my-name.html"&gt;might be on to a new meme&lt;/a&gt;.  I &lt;em&gt;must&lt;/em&gt; propagate it by joining them in lamenting the mis-pronunciations of my names:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;aw li vee eh&lt;/li&gt;&lt;li&gt;aw liver&lt;/li&gt;&lt;li&gt;dah gue naiz&lt;/li&gt;&lt;li&gt;dah gue nah&lt;/li&gt;&lt;li&gt;day je naiz&lt;/li&gt;&lt;li&gt;day je neh&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;As a result, I try to go by &lt;strong&gt;Oli&lt;/strong&gt;, but this has proven to be equally as elusive as &lt;em&gt;many&lt;/em&gt; people will write down &lt;strong&gt;Ali&lt;/strong&gt; or even &lt;strong&gt;Holly&lt;/strong&gt;! (&lt;a href="http://worsethanfailure.com/"&gt;WTF&lt;/a&gt;?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-87144316570415009?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/87144316570415009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=87144316570415009' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/87144316570415009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/87144316570415009'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/02/my-name.html' title='My name'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1346376562251643927</id><published>2007-02-20T23:34:00.001-05:00</published><updated>2008-12-11T03:10:41.289-05:00</updated><title type='text'>Thanks for ruining it for the rest of us, guys!</title><content type='html'>&lt;p&gt;Behold the power of stupidity on the internet, as I tried to e-mail a university computer science assignment to my professor:&lt;/p&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_QvEDZGglpqE/RdvMBYf0AjI/AAAAAAAAAAY/OZWgvGx2TyU/s1600-h/attachment+contains+an+executable+file.png"&gt;&lt;img src="http://3.bp.blogspot.com/_QvEDZGglpqE/RdvMBYf0AjI/AAAAAAAAAAY/OZWgvGx2TyU/s400/attachment+contains+an+executable+file.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5033841332644479538" /&gt;&lt;/a&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="https://mail.google.com"&gt;https://mail.google.com&lt;/a&gt;&lt;/p&gt; &lt;p&gt;OlivierDagenais-Assignment1.zip contains an executable file. For security reasons, Gmail does not allow you to send this type of file.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I can sort of see how something like this could have come about: logs show users e-mailing executable files of various degrees of maliciousness.&amp;nbsp; Google reacts by deciding one malicious executable file is one too many and refuses to accept executable files as Gmail attachments.&lt;/p&gt; &lt;p&gt;Some clever user then thinks "My nefarious H@xx0Rz.EXE &lt;em&gt;must&lt;/em&gt; be e-mailed to my clueless buddies... I know: I'll just &lt;em&gt;zip it&lt;/em&gt;!".&amp;nbsp; Google notices again and here we are.&amp;nbsp; Encrypting my ZIP file would probably do nothing as you can list the names of the files without the key and so Google's clever little &lt;code&gt;ZipSecurityPeeker.py&lt;/code&gt; only needs to check for the presence of files ending with &lt;code&gt;.exe&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;I ended up submitting the assignment using another e-mail account. I bet I could have CCed my GMail account and received the "insecure" attachment no problem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Whoa! I didn't even have a &lt;code&gt;.exe&lt;/code&gt; file in my ZIP archive! I have some &lt;code&gt;.bat&lt;/code&gt;, some &lt;code&gt;.cmd&lt;/code&gt; and some &lt;code&gt;.pl&lt;/code&gt;, as well as one or two shell scripts without an extension. Most of those files, incidentally, shipped as part of Apache Ant, which I included in my assignment's ZIP archive so the professor wouldn't have to go hunt it down, install it, etc.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;UPDATE 2:&lt;/strong&gt; Nope, I can't receive it either because I apparently &lt;em&gt;broke the law&lt;/em&gt;:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;Your message cannot be delivered to the following recipients:&lt;br /&gt;&lt;br /&gt;  (...)&lt;br /&gt;  Reason: SMTP transmission failure has occurred&lt;br /&gt;  Diagnostic code: smtp;552 5.7.0 Illegal Attachment c5si5493294qbc&lt;br /&gt;  (...)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1346376562251643927?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1346376562251643927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1346376562251643927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1346376562251643927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1346376562251643927'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/02/thanks-for-ruining-it-for-rest-of-us.html' title='Thanks for ruining it for the rest of us, guys!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_QvEDZGglpqE/RdvMBYf0AjI/AAAAAAAAAAY/OZWgvGx2TyU/s72-c/attachment+contains+an+executable+file.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-3911922824858857672</id><published>2007-02-10T22:28:00.001-05:00</published><updated>2007-02-07T00:19:05.721-05:00</updated><title type='text'>Unit tests can be fun!</title><content type='html'>&lt;p&gt;Here's a snippet of testing code from a university assignment I did last term where we had to create a model of an alarm clock using finite state machines and then test using the FSM testing techniques we learned in class. This is Java 5 code with some &lt;a href="http://junit.org"&gt;JUnit&lt;/a&gt; goodness.&lt;/p&gt;&lt;code&gt;&lt;pre&gt;/**&lt;br /&gt; * It's 21:30 and I'm going to bed.  I set the alarm time for 06:00 and then&lt;br /&gt; * sleep until the damn thing wakes me up, but I don't want to get up just&lt;br /&gt; * yet and I think 4 more minutes will change my mood today from&lt;br /&gt; * "didn't get enough sleep" to "downright chipper" and so I slam my hand in&lt;br /&gt; * the general direction of the drowse button (it has an 80%, no 70% chance&lt;br /&gt; * of hitting it the first time) and then wake up a new man 4.2 minutes&lt;br /&gt; * later, turning off the alarm functionality until I need it again the&lt;br /&gt; * following night.&lt;br /&gt; */&lt;br /&gt;@Test&lt;br /&gt;public void SetTickRingDrowseTickRingStop ( ) {&lt;br /&gt;	// set clock time from 01:00 to 21:30&lt;br /&gt;	super.SwitchTimeSet();&lt;br /&gt;	// that is to say add 20 hours&lt;br /&gt;	for (int c = 0; c &amp;lt; 20; c++) {&lt;br /&gt;		super.HourButtonClick();&lt;br /&gt;	}&lt;br /&gt;	// and 30 minutes&lt;br /&gt;	for (int c = 0; c &amp;lt; 30; c++) {&lt;br /&gt;		super.MinuteButtonClick();&lt;br /&gt;	}&lt;br /&gt;	areEqual(21, 30, super.clockTime);&lt;br /&gt;	&lt;br /&gt;	// set switch to Run&lt;br /&gt;	super.SwitchRun();&lt;br /&gt;&lt;br /&gt;	// set alarm time from 13:00 to 06:00&lt;br /&gt;	super.SwitchAlarmSet();&lt;br /&gt;	// which is to add 11 + 6 hours&lt;br /&gt;	for (int c = 0; c &amp;lt; 11 + 6; c++) {&lt;br /&gt;		super.HourButtonClick();&lt;br /&gt;	}&lt;br /&gt;	areEqual(06, 00, super.alarmTime);&lt;br /&gt;&lt;br /&gt;	// set switch to Run&lt;br /&gt;	super.SwitchRun();&lt;br /&gt;	assertTrue(super.IsAlarmOn());&lt;br /&gt;&lt;br /&gt;	// go to sleep for 8.5 hours&lt;br /&gt;	for (int c= 0; c &amp;lt; 8.5 * 60; c++) {&lt;br /&gt;		super.TickMinute();&lt;br /&gt;	}&lt;br /&gt;	areEqual(06, 00, super.clockTime);&lt;br /&gt;	&lt;br /&gt;	// whoa, it's ringing!&lt;br /&gt;	assertTrue(super.IsTriggered());&lt;br /&gt;	assertTrue(super.IsRinging());&lt;br /&gt;	assertFalse(super.IsDrowsing());&lt;br /&gt;	&lt;br /&gt;	// leave me alone for 240 more seconds!&lt;br /&gt;	super.DrowseButtonClick();&lt;br /&gt;	for ( int c = 0; c &amp;lt; 4; c++ ) {&lt;br /&gt;		assertTrue(super.IsTriggered());&lt;br /&gt;		assertFalse(super.IsRinging());&lt;br /&gt;		assertTrue(super.IsDrowsing());&lt;br /&gt;		super.TickMinute();&lt;br /&gt;	}&lt;br /&gt;	areEqual(06, 04, super.clockTime);&lt;br /&gt;&lt;br /&gt;	// whoa, it's ringing again!&lt;br /&gt;	assertTrue(super.IsTriggered());&lt;br /&gt;	assertTrue(super.IsRinging());&lt;br /&gt;	assertFalse(super.IsDrowsing());&lt;br /&gt;	&lt;br /&gt;	// that's it, I'm getting up and turning this thing off&lt;br /&gt;	super.SwitchAlarmOff();&lt;br /&gt;	assertFalse(super.IsAlarmOn());&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;p&gt;The test depends on some @Before method which resets the model (i.e. makes it just like the alarm clock just had batteries put in for the first time) and thus the the initial clock time is 01:00 and the initial alarm time is 13:00.&amp;nbsp; The model was created from observing the behaviour of an old &lt;a title="Images of a Westclox model 47539" href="http://images.google.ca/images?q=47539%20%20westclox"&gt;Westclox travel alarm clock&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-3911922824858857672?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/3911922824858857672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=3911922824858857672' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3911922824858857672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3911922824858857672'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/02/unit-tests-can-be-fun.html' title='Unit tests can be fun!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1678280650024005084</id><published>2007-02-07T00:19:00.000-05:00</published><updated>2007-02-07T00:19:05.765-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Backups of Subversion repositories</title><content type='html'>Here's the scenario:  you are running a Subversion server and like all serious geeks, you want it backed up.  This here post will show you how I do it for Windows and *nix _simultaneously_.  I'm making the following assumptions:&lt;br /&gt;&lt;br /&gt;&lt;table style="border:1px solid black"&gt;&lt;tr&gt;&lt;th&gt;Path type&lt;/th&gt;&lt;th&gt;Windows&lt;/th&gt;&lt;th&gt;*nix&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;the subversion repositories are located&lt;/td&gt;&lt;td&gt;&lt;code&gt;d:\svnrepo&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;/home/svn&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;the backup root folder&lt;/td&gt;&lt;td&gt;&lt;code&gt;d:\backups&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;/home/backups&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;the subversion CLI&lt;/td&gt;&lt;td&gt;(in the path)&lt;/td&gt;&lt;td&gt;(in the path)&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The first script performs not only a &lt;strong&gt;hotcopy&lt;/strong&gt; backup of a repository (provided as the first parameter), but also first erases whatever backup might have been there (with a special provision for the very first time around) and creates a "dump" of the repository's contents, along with a final clean-up to save space.  The reason we are keeping a dump over the contents of the &lt;strong&gt;db&lt;/strong&gt; folder is that you can then "restore" your backup with a &lt;em&gt;different&lt;/em&gt; version of Subversion.  (trust me, I've lived through a catastrophic failure of a Subversion server and the dump format stays the same across versions while whatever's in the &lt;strong&gt;db&lt;/strong&gt; folder doesn't necessarily)&lt;br /&gt;&lt;table style="border:1px solid black"&gt;&lt;tr&gt;&lt;th&gt;Windows&lt;/th&gt;&lt;th&gt;*nix&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;BackupAndDump.bat&lt;code&gt;&lt;br /&gt;@echo off&lt;br /&gt;mkdir d:\backups\Subversion\%1\_backup&lt;br /&gt;rmdir d:\backups\Subversion\%1 /s /q&lt;br /&gt;svnadmin.exe hotcopy d:/SvnRepo/%1/ d:/backups/Subversion/%1/&lt;br /&gt;svnadmin.exe dump d:/backups/Subversion/%1/ &gt; d:/backups/Subversion/%1.svndump&lt;br /&gt;rmdir d:\backups\Subversion\%1\db /s /q&lt;br /&gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;backupanddump&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;mkdir -p /home/backups/svn/$1/_backup&lt;br /&gt;rm -rf /home/backups/svn/$1&lt;br /&gt;svnadmin hotcopy /home/svn/$1/ /home/backups/svn/$1/&lt;br /&gt;svnadmin dump /home/backups/svn/$1/ &gt; /home/backups/svn/$1.svndump&lt;br /&gt;rm -rf /home/backups/svn/$1/db&lt;br /&gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The second script iterates through all the repositories in a root folder and calls the first script (which, BTW, is located in the backup root folder) for each one.&lt;br /&gt;&lt;table style="border:1px solid black"&gt;&lt;tr&gt;&lt;th&gt;Windows&lt;/th&gt;&lt;th&gt;*nix&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SubversionBackup.bat&lt;code&gt;&lt;br /&gt;@echo off&lt;br /&gt;d:&lt;br /&gt;cd \svnrepo&lt;br /&gt;for /D %%d in (*) do d:\Backups\BackupAndDump %%d&lt;br /&gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;svnbackup&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;cd /home/svn&lt;br /&gt;for d in *; do /home/backups/backupanddump $d; done&lt;br /&gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Well, that's enough for tonight.  I'm sure &lt;a href="http://slashdot.org"&gt;all you Linux gurus&lt;/a&gt; out there are pointing and laughing at my noob-skills.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1678280650024005084?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1678280650024005084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1678280650024005084' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1678280650024005084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1678280650024005084'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/02/backups-of-subversion-repositories.html' title='Backups of Subversion repositories'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-2241897331212439431</id><published>2007-02-06T08:32:00.000-05:00</published><updated>2007-02-06T08:49:42.756-05:00</updated><title type='text'>A new oxymoron: cybersurf reliability</title><content type='html'>Go head. &lt;a href="http://www.google.com/search?q=cybersurf%20reliability"&gt;Google it&lt;/a&gt; and, even there, you'll see enough of the following: (emphasis mine)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://signup.cia.com/TellMeMore.do?event=headerFooter&amp;amp;linkName=link.partners"&gt;CIA.com : The Freedom of Choice&lt;/a&gt;&lt;br /&gt;&lt;em&gt;Cybersurf's premium Internet service utilizes the fibre backbones of Call-Net and Bell Canada for speed and stability, and the latest CISCO remote access equipment (modems) for &lt;strong&gt;state-of-the-art&lt;/strong&gt; digital access and &lt;strong&gt;reliability&lt;/strong&gt;.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;...yet ONE link down, there's the sign-up page (emphasis mine):&lt;br /&gt;&lt;br /&gt;&lt;a href="https://secure.cybersurf.net/HighSpeedSignup/signup.jsp"&gt;Welcome to Cybersurf&lt;/a&gt;&lt;br /&gt;&lt;em&gt;Cybersurf, ITS PARTNERS, AFFILIATE PARTNERS AND CARRIERS &lt;strong&gt;MAKE NO REPRESENTATIONS ABOUT&lt;/strong&gt; SUITABILITY, &lt;strong&gt;RELIABILITY&lt;/strong&gt;, AVAILABILITY, TIMELINESS, AND ACCURACY OF THE SERVICES OR ANY UNDERLYING FACILITIES USED IN THE PROVISION OF THE SERVICES FOR ANY PURPOSE.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Err... aside from the "yes reliability, no reliability", they don't even acknowledge that future customers will be able to use the phone or internet to do anything?  Legal and marketing need to have lunch together a little more often.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(Yes, yes, I know, standard "bait &amp; switch"... I'm just pointing out it sucks, that's all...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-2241897331212439431?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/2241897331212439431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=2241897331212439431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2241897331212439431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2241897331212439431'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/02/new-oxymoron-cybersurf-reliability.html' title='A new oxymoron: cybersurf reliability'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1999023718494808367</id><published>2007-01-13T19:57:00.000-05:00</published><updated>2007-01-13T20:45:58.477-05:00</updated><title type='text'>That was easy!</title><content type='html'>So this [oldish] computer stopped booting properly about six months ago.  It would start, but then mysteriously die during the sequence.  I finally had a bit of time to check it out tonight, so I powered it up and noticed the POST would not only show a garbled version of "Maxtor" (and the model number), but also identify this 40 GB disk as about 8 GB.  At this point, it would refuse to even boot and instead barf up with &lt;code&gt;INVALID SYSTEM DISK, INSERT BOOT DISK AND HIT ENTER TO RETRY&lt;/code&gt; (or something just like it).&lt;br /&gt;&lt;br /&gt;Anyway, I figured the hard disk wasn't &lt;em&gt;that&lt;/em&gt; old and so I powered down and unplugged it.  I noticed the ribbon cable wasn't quite straight (it was sort of folded onto itself, but not perpendicular to the wires), so being obsessive-compulsive as I usually am, I straightened it out, carefully plugged it back in and decided to give it a shot.  Lo and behold, I'm blogging this from that computer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1999023718494808367?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1999023718494808367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1999023718494808367' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1999023718494808367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1999023718494808367'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/01/that-was-easy.html' title='That was easy!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-2679640201438274917</id><published>2007-01-08T08:45:00.000-05:00</published><updated>2007-01-08T08:46:53.582-05:00</updated><title type='text'>Handy equivalents of Outlook Express keyboard shortcuts for Outlook 2007 users</title><content type='html'>Outlook 2007 is pretty neat but it's also a little awkward if you've been using Outlook Express a lot (or maybe even previous versions of Outlook).  Since I'm a keyboard freak, here's my cheat-sheet of stuff that was really hard to find in the documentation (*cough* context sensitive help my ass! *cough*):&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;th&gt;Action&lt;/th&gt;&lt;th&gt;Outlook Express&lt;/th&gt;&lt;th&gt;Outlook 2007&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Switch from plain text to HTML (while viewing a message and plain text is the default - which is what &lt;em&gt;everybody&lt;/em&gt; should do)&lt;/td&gt;&lt;td&gt;&lt;code&gt;Alt+Shift+H&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Ctrl+Shift+W, D&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Focus on the folder tree (while in the main interface)&lt;/td&gt;&lt;td&gt;&lt;code&gt;TAB&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Ctrl+1&lt;/code&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Insert default signature (while composing)&lt;/td&gt;&lt;td&gt;&lt;code&gt;Alt+I, S&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Alt+N, G, ENTER&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Invoke smart tag (i.e. AutoCorrect Options)'s drop-down menu&lt;/td&gt;&lt;td&gt;&lt;em&gt;not applicable&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Alt+Shift+F10&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update:&lt;/strong&gt; Until I put all the HTML code on one line, the spacing was way off, sorry.  My "Preview" button doesn't really Preview.  :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-2679640201438274917?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/2679640201438274917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=2679640201438274917' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2679640201438274917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2679640201438274917'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2007/01/handy-equivalents-of-outlook-express.html' title='Handy equivalents of Outlook Express keyboard shortcuts for Outlook 2007 users'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8853510168393590212</id><published>2006-12-20T08:45:00.000-05:00</published><updated>2006-12-20T08:45:43.203-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Say what?</title><content type='html'>From Picasa's &lt;a href="http://picasa.google.com/intl/en_US/web/tos.html"&gt;Terms of Service&lt;/a&gt; (emphasis mine):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;Upon the termination of your use of Picasa Web Albums, including upon receipt of a certificate or other legal document &lt;strong&gt;confirming your death&lt;/strong&gt;, Google will close your account and &lt;strong&gt;you will no longer be able to retrieve content&lt;/strong&gt; contained in that account.&lt;/em&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Errr...  If I'm dead, do I care if &lt;em&gt;I&lt;/em&gt; can't access content?&lt;br /&gt;&lt;br /&gt;I'm afraid to ask if this rule is &lt;a href="http://www.joelonsoftware.com/uibook/chapters/fog0000000059.html"&gt;the result of a precedent&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8853510168393590212?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8853510168393590212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8853510168393590212' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8853510168393590212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8853510168393590212'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/12/say-what.html' title='Say what?'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-335275793764316023</id><published>2006-12-13T16:54:00.000-05:00</published><updated>2008-12-11T03:10:41.538-05:00</updated><title type='text'>What are my choices for "no"?</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_QvEDZGglpqE/RYB2taT8f6I/AAAAAAAAAAM/W-rFUs6Z3EQ/s1600-h/Automatic+Update+Choices.PNG"&gt; &lt;p dir="ltr" style="margin-right: 0px"&gt;&lt;br&gt;&lt;/p&gt;&lt;img id="BLOGGER_PHOTO_ID_5008133308165160866" style="display: block; margin: 0px auto 10px; text-align: center" alt="" src="http://4.bp.blogspot.com/_QvEDZGglpqE/RYB2taT8f6I/AAAAAAAAAAM/W-rFUs6Z3EQ/s400/Automatic+Update+Choices.PNG" border="0"&gt;  &lt;blockquote&gt; &lt;p&gt;&lt;/a&gt;"Automatic Updates&lt;/p&gt; &lt;p&gt;Updating your computer is almost complete. You must restart your computer for the updates to take effect.&lt;/p&gt; &lt;p&gt;Do you want to restart your computer now?&lt;/p&gt; &lt;p&gt;[Restart Now]"&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;font color="#666666"&gt;Whoa!&amp;nbsp; At least it's better than that "Your computer will restart in 5 minutes no matter what and I don't care if your name is &lt;em&gt;Bill Gates&lt;/em&gt; and you're in the middle of a very important demonstration at the moment,&amp;nbsp;so TOUGH LUCK."&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#666666"&gt;For those of you who might be wondering how this could have happened, I run as a non-administrator&amp;nbsp;on that computer&amp;nbsp;and I "Remote Desktoped" back to my own machine as the administrator to install this Patch Tuesday's set of updates.&amp;nbsp; I wasn't quite ready to reboot, but Windows just needed to &lt;em&gt;insist&lt;/em&gt;.&lt;/font&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-335275793764316023?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/335275793764316023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=335275793764316023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/335275793764316023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/335275793764316023'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/12/what-are-my-choices-for.html' title='What are my choices for &amp;quot;no&amp;quot;?'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_QvEDZGglpqE/RYB2taT8f6I/AAAAAAAAAAM/W-rFUs6Z3EQ/s72-c/Automatic+Update+Choices.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-604591141444740525</id><published>2006-11-30T08:22:00.000-05:00</published><updated>2006-11-30T08:24:14.346-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meta-blogging'/><title type='text'>Do what Technorati tells you to...</title><content type='html'>Oh, great.  I think I just got suckered into another one of those linking schemes by accidentally creating a &lt;a href="http://www.technorati.com/claim/jy9vqmwrt4" rel="me"&gt;Technorati Profile&lt;/a&gt; so that I could post my picture somewhere or something.&lt;br /&gt;&lt;br /&gt;Meh...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-604591141444740525?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/604591141444740525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=604591141444740525' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/604591141444740525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/604591141444740525'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/11/do-what-technorati-tells-you-to.html' title='Do what Technorati tells you to...'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-2786502648643899395</id><published>2006-11-30T08:13:00.000-05:00</published><updated>2006-11-30T08:19:37.658-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meta-blogging'/><category scheme='http://www.blogger.com/atom/ns#' term='meme'/><category scheme='http://www.blogger.com/atom/ns#' term='shameless plug'/><title type='text'>Do what the interweb tells you to</title><content type='html'>So I'm reading &lt;a href="http://www.knowing.net/PermaLink,guid,8e922366-d28c-4c66-9b5f-1b64557243ef.aspx"&gt;Larry O'Brien's blog&lt;/a&gt; and he tells me (well, not &lt;em&gt;me personally&lt;/em&gt;, but you know what I mean) to not only click on a link, but also to link to it in my own blog.  &lt;a href="http://acephalous.typepad.com/acephalous/2006/11/measuring_the_s.html"&gt;The destination&lt;/a&gt; page says the same, plus:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;Ask your readers to do the same.  Beg them.  Relate sob stories about poor graduate students in desperate circumstances.  Imply I'm one of them.  (Do whatever you have to.  If that fails, try whatever it takes.)&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;...&lt;a href="http://www.imdb.com/title/tt0127357/"&gt;who am I&lt;/a&gt; to resist orders from the internet and random blogs?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-2786502648643899395?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/2786502648643899395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=2786502648643899395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2786502648643899395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2786502648643899395'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/11/do-what-interweb-tells-you-to.html' title='Do what the interweb tells you to'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-4082077260797464074</id><published>2006-11-29T20:20:00.000-05:00</published><updated>2006-11-29T21:31:52.120-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='william shatner'/><category scheme='http://www.blogger.com/atom/ns#' term='tv'/><title type='text'>$how me the Shatner!</title><content type='html'>This show called &lt;a href="http://abc.go.com/primetime/showmethemoney/index.html"&gt;Show Me The Money&lt;/a&gt; recently came out on ABC.  It is hosted by &lt;a href="http://www.imdb.com/name/nm0000638/"&gt;William Shatner&lt;/a&gt; and feels like a cross between &lt;a href="http://www.imdb.com/title/tt0360318/"&gt;Who Wants to Be a Millionaire&lt;/a&gt; and &lt;a href="http://www.imdb.com/title/tt0493378/"&gt;Deal or No Deal&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Unsurprisingly - and appropriately enough but most likely on purpose - &lt;a href="http://www.cafepress.com/cp/store.aspx?s=wfs2"&gt;WFS&lt;/a&gt; feels like a cross between &lt;a href="http://www.imdb.com/name/nm0005310/"&gt;Regis Philbin&lt;/a&gt; and &lt;a href="http://www.imdb.com/name/nm0005177/"&gt;Howie Mandel&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Go....watch.....it!  You know....you....want....to!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-4082077260797464074?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/4082077260797464074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=4082077260797464074' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/4082077260797464074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/4082077260797464074'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/11/how-me-shatner.html' title='$how me the Shatner!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-1557289626248753708</id><published>2006-11-29T14:47:00.000-05:00</published><updated>2006-11-29T15:13:29.212-05:00</updated><title type='text'>Hacking the Microsoft Natural Ergonomic Keyboard 4000, redux</title><content type='html'>Earlier I wrote about &lt;a href="http://oliiscool.blogspot.com/2006/09/hacking-microsoft-natural-ergonomic.html"&gt;hacking IntelliType's &lt;code&gt;commands.xml&lt;/code&gt; file&lt;/a&gt; to enable the use of the "Zoom slider" as a "Scroll slider".  Having recently &lt;a href="http://blogs.msdn.com/larryosterman/archive/2006/11/16/flattening-the-world.aspx"&gt;repaved&lt;/a&gt; my computer, I found myself installing the latest version of &lt;a href="http://www.microsoft.com/hardware/mouseandkeyboard/Download.mspx"&gt;Microsoft IntelliType Pro&lt;/a&gt; (version 6.02, a.k.a. 6.02.303.0) and trying to apply the patch I posted earlier:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\Program Files\Microsoft IntelliType Pro&gt;patch -p0 &lt; command.patch&lt;br /&gt;patching file `commands.xml'&lt;br /&gt;Hunk #1 FAILED at 1606.&lt;br /&gt;Hunk #2 FAILED at 1694.&lt;br /&gt;Hunk #3 FAILED at 2122.&lt;br /&gt;Hunk #4 FAILED at 2134.&lt;br /&gt;Hunk #5 FAILED at 2152.&lt;br /&gt;Hunk #6 FAILED at 2182.&lt;br /&gt;patch unexpectedly ends in middle of line&lt;br /&gt;Hunk #7 FAILED at 2224.&lt;br /&gt;7 out of 7 hunks FAILED -- saving rejects to commands.xml.rej&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.snpp.com/episodes/1F16.html"&gt;B'oh!&lt;/a&gt;  Err... I mean:  D'oh!  Ok, time for plan B:  &lt;em&gt;Zoom2Scroll.xsl&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;xsl:output method="xml" encoding="UTF-8" indent="yes" /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Pass-through (identity transform) template --&amp;gt;&lt;br /&gt; &amp;lt;xsl:template match="* | @* | node()"&amp;gt;&lt;br /&gt;  &amp;lt;xsl:copy&amp;gt;&lt;br /&gt;   &amp;lt;xsl:apply-templates select="* | @* | node()" /&amp;gt;&lt;br /&gt;  &amp;lt;/xsl:copy&amp;gt;&lt;br /&gt; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;xsl:template match="C319"&amp;gt;&lt;br /&gt;  &amp;lt;C319 Type="6" Activator="ScrollUp" /&amp;gt;&lt;br /&gt; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;xsl:template match="C320"&amp;gt;&lt;br /&gt;  &amp;lt;C320 Type="6" Activator="ScrollDown" /&amp;gt;&lt;br /&gt; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There.  A quick trip to the command-line with my trusty &lt;em&gt;xsl.exe&lt;/em&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\Program Files\Microsoft IntelliType Pro&gt;xsl commands.old Zoom2Scroll.xsl commands.xml&lt;br /&gt;&lt;br /&gt;C:\Program Files\Microsoft IntelliType Pro&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...and killing the &lt;code&gt;IType.exe&lt;/code&gt; process, then re-launching that EXE again... it works!  &lt;a href="http://neil.fraser.name/software/diff_match_patch/"&gt;In your face&lt;/a&gt;, &lt;a href="http://www.gnu.org/software/diffutils/"&gt;Larry Wall&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Oh, right.  This post wouldn't be complete without the source code to &lt;em&gt;xsl.exe&lt;/em&gt;.  It's a JScript.NET program:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import System.Xml;&lt;br /&gt;import System.Xml.Schema;&lt;br /&gt;&lt;br /&gt;var src : String = System.Environment.GetCommandLineArgs()[1];&lt;br /&gt;&lt;br /&gt;var transformer : System.Xml.Xsl.XslTransform = new System.Xml.Xsl.XslTransform ( );&lt;br /&gt;var stylesheet : String = System.Environment.GetCommandLineArgs()[2];&lt;br /&gt;transformer.Load ( stylesheet );&lt;br /&gt;&lt;br /&gt;transformer.Transform ( src, System.Environment.GetCommandLineArgs()[3], null );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...which you can compile as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322&gt;jsc /nologo xsl.jsn&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thanks go out to the folks at &lt;a href="http://www.cuteoverload.com/"&gt;Cute Overload&lt;/a&gt; for providing me with a [semi-]random web page to test the [new] scrolling capabilities of my "slider" in Internet Explorer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-1557289626248753708?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/1557289626248753708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=1557289626248753708' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1557289626248753708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/1557289626248753708'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/11/hacking-microsoft-natural-ergonomic.html' title='Hacking the Microsoft Natural Ergonomic Keyboard 4000, redux'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-8060094780769957588</id><published>2006-10-25T21:57:00.000-04:00</published><updated>2006-10-25T22:11:15.754-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><title type='text'>SET CLASSPATH=SUCKS</title><content type='html'>From &lt;a href="www.knowing.net"&gt;Larry O'Brien&lt;/a&gt;'s blog, &lt;a href="http://www.knowing.net/PermaLink,guid,f210e53e-d6c8-40d8-85c4-b02f12526e32.aspx "&gt;God, I Hate Classpaths&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;I've spent the past 3 hours trying to figure out freaking classpath issues: something about a ClassCastException from a org.apache.commons.logging.LogFactory. I'm giving up for the day. Stupid freaking classpaths.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The feeling is mutual, brother.  I've recently lost plenty of hours to weird errors that turned out to be classpath-related.  Maybe I've simply gotten used to putting all my assemblies in the same local folder (and not having to re-create that list elsewhere) or using the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpgrfFusionLogViewerFuslogvwexe.asp"&gt;Fusion Log&lt;/a&gt;, which will tell you what the runtime is trying to load, even if it's hidden by another exception or a silent failure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-8060094780769957588?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/8060094780769957588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=8060094780769957588' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8060094780769957588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/8060094780769957588'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/10/set-classpathsucks.html' title='SET CLASSPATH=SUCKS'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-512736205838697973</id><published>2006-10-11T10:46:00.001-04:00</published><updated>2006-10-11T10:46:27.098-04:00</updated><title type='text'>Upgrades...</title><content type='html'>&lt;p&gt;I apologize for the recent feed duplications.&amp;nbsp; First, I upgraded to &lt;a href="https://beta.blogger.com/start"&gt;Blogger Beta&lt;/a&gt;&amp;nbsp;(gone are the endless refreshes when "publishing"), then I started using &lt;a href="http://windowslivewriter.spaces.live.com/"&gt;Windows Live Writer (Beta)&lt;/a&gt;.&amp;nbsp; In theory, everything should be good now...&lt;/p&gt; &lt;p&gt;&lt;img src="http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg"&gt;&lt;/p&gt; &lt;p&gt;...until the next round of betas, I suppose. :p&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-512736205838697973?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/512736205838697973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=512736205838697973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/512736205838697973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/512736205838697973'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/10/upgrades.html' title='Upgrades...'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-397874431820149854</id><published>2006-10-11T08:52:00.000-04:00</published><updated>2007-04-06T19:59:38.603-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oss'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><title type='text'>Comparison of Open-Source Licenses</title><content type='html'>&lt;div id="PageContent"&gt;                   &lt;div class="wiki-content"&gt;&lt;!-- wiki content --&gt;                   &lt;table class="tipMacro" align="center" border="0" cellpadding="5" cellspacing="8" width="85%"&gt;                     &lt;colgroup&gt;                     &lt;col width="24"&gt;                     &lt;col&gt;&lt;/colgroup&gt;                     &lt;tbody&gt;                     &lt;tr&gt;                       &lt;td valign="top"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td&gt;&lt;b class="strong"&gt;Note&lt;/b&gt;&lt;br /&gt;&lt;p&gt;This is a copy of an essay I wrote for an assignment in the Open-Source Software Engineering course I'm taking.  The deadline was yesterday, so it's safe to post today. :)  I wrote this essay using Confluence, so the HTML is a little weird when I try to copy/paste it here.  The assignment was:&lt;/p&gt;&lt;br /&gt;                    &lt;p&gt;Compare and contrast (1500-2000 words) the open                         source licenses MIT, BSD, GPL, LGPL, Creative Commons to                         the Eclipse Public License. Make sure to include a table                         (rows heading is feature, column heading is license)                         that summaries your discussion. Submit the answer to                         this question as an HTML                   document.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;                   &lt;h1&gt;&lt;a name="Assignment1-FeaturetoLicensematrix"&gt;&lt;/a&gt;Feature to                   License matrix&lt;/h1&gt;                   &lt;table border="1"&gt;                     &lt;tbody&gt;                     &lt;tr&gt;                       &lt;td class="confluenceTd"&gt;# &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Feature name \ License &lt;/td&gt;                       &lt;th class="confluenceTh"&gt;&lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/licenses/mit-license.php"&gt;MIT&lt;/a&gt;&lt;/span&gt; &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;&lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/licenses/bsd-license.php"&gt;BSD&lt;/a&gt;&lt;/span&gt; &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;&lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/licenses/gpl-license.php"&gt;GPL&lt;/a&gt;&lt;/span&gt; &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;&lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/licenses/lgpl-license.php"&gt;LGPL&lt;/a&gt;&lt;/span&gt; &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;&lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://creativecommons.org/about/licenses/meet-the-licenses"&gt;Creative                         Commons&lt;/a&gt;&lt;/span&gt; &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;&lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.eclipse.org/legal/epl-v10.html"&gt;EPL&lt;/a&gt;&lt;/span&gt; &lt;/th&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;1 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Number of paragraphs &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;4 &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;6 &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;56 &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;69 &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Average of 31 &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;20 &lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;2 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Distribute modified/derived work?                       &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Depends on "nd" option &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;3 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Must release source?&lt;br /&gt;&lt;/th&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;4 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Must identify all modifications?                       &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;5 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Is attribution required? &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;Preserve copyright notice &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Preserve copyright notice &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Preserve copyright notice &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Preserve copyright notice &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Preserve copyright notice &lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;6 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Is endorsement or promotion                         permitted? &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Not without permission &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;7 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Is commercial use or distribution                         authorized? &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Depends on "nc" option &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;8 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Allows re-licensing? &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Only by special permission &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Only to GPL, or by special                         permission &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Depends on "sa" option &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;&lt;/tr&gt;                     &lt;tr&gt;                       &lt;th class="confluenceTh"&gt;9 &lt;/th&gt;                       &lt;th class="confluenceTh"&gt;Requires patents be licensed to                         recipients? &lt;/th&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;                       &lt;td class="confluenceTd"&gt;&lt;br /&gt;&lt;/td&gt;                       &lt;td class="confluenceTd"&gt;Yes &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;                   &lt;h1&gt;&lt;a name="Assignment1-Introduction"&gt;&lt;/a&gt;Introduction&lt;/h1&gt;                   &lt;p&gt;The open source licenses involved in this study have been                   analyzed and – although similar in the spirit of "no charge                   but no warranty" copyright licensing – were found to be                   primarily different in what they are specific or explicit                   about. It is speculated that this is representative of the                   values and interests of the license authors and therefore the                   level of detail surrounding a topic is assumed to reflect the                   degree to which the interests and values affected by said                   topic are important to the authors and the amount of effort                   willing to be exerted in order to ensure said interests and                   value are protected.&lt;/p&gt;                   &lt;p&gt;Examples of such interests and values are "equality",                   "merit", "freedom", "public good", "continuous improvement",                   "standardization" and "accountability". This analysis will                   examine these values, how they can be traced back to license                   features and finally how individual licenses emphasize these                   values by the use of the features and the requirements or                   conditions they attach to said features.&lt;/p&gt;                   &lt;h1&gt;&lt;a name="Assignment1-Features"&gt;&lt;/a&gt;Features&lt;/h1&gt;                   &lt;p&gt;The matrix, and correspondingly this analysis, only                   examines the major differences observed between the licenses.                   Similarities are outside the scope of this study. It should be                   noted, also, that the matrix only contains entries for                   feature-license pairs when such a feature was explicitly                   mentioned in the license. As identified in the introduction,                   the licenses aren't always specific on all features and a                   lawyer may be able to interpret the licenses according to the                   local laws to make a definitive determination for each                   feature. That said, even a "Yes" is slightly misleading as                   there are often conditions or requirements attached to the                   permissions before they can be implemented.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-1.Numberofparagraphs"&gt;&lt;/a&gt;1. Number of                   paragraphs&lt;/h2&gt;                   &lt;p&gt;Although one of the more questionable choice of features,                   it is actually pretty representative of the level of detail of                   the licenses. The count was done quickly, by hand.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-2.Distributemodified/derivedwork?"&gt;&lt;/a&gt;2.                   Distribute modified/derived work?&lt;/h2&gt;                   &lt;p&gt;Since all licenses permit royalty-free redistribution, the                   distinction here is whether the work can be distributed with                   modifications or as part of a derived work. This feature is                   present because the Creative Commons licenses can restrict                   this activity with the "nd" (No Derivatives) option.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-3.Mustreleasesource?"&gt;&lt;/a&gt;3. Must                   release source?&lt;/h2&gt;                   &lt;p&gt;This feature is more accurately the requirement of making                   available, upon request, the source code of any binary                   re-distribution, independent of whether the work was modified                   or not. It may be sufficient to make an offer for the source                   code or to pass on the same offer to recipients. The GPL and                   LGPL are explicit about this.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-4.Mustidentifyallmodifications?"&gt;&lt;/a&gt;4. Must                   identify all modifications?&lt;/h2&gt;                   &lt;p&gt;Also known as "delta notification", this is a requirement                   that modifications be traceable back to contributors, usually                   in the case of derivative works. Again, strong features of GPL                   and LGPL.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-5.Isattributionrequired?"&gt;&lt;/a&gt;5. Is                   attribution required?&lt;/h2&gt;                   &lt;p&gt;Another feature that appears to stem out of nit-pick, the                   Creative Commons licenses stand out in that they require more                   than simply preserving the copyright notice but to make                   efforts to link back to the original work. This could be                   considered a special case of delta notification.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-6.Isendorsementorpromotionpermitted?"&gt;&lt;/a&gt;6.                   Is endorsement or promotion permitted?&lt;/h2&gt;                   &lt;p&gt;A special case of attribution, in the case of derived works                   the BSD license makes a point of requiring "specific prior                   written permission" before using the names of the original                   project's organization or contributors for promotional or                   endorsement purposes. The Creative Commons licenses give this                   permission by default, but section 4.a reserves the right to                   the Licensor to request credit be removed.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-7.Iscommercialuseordistributionauthorized?"&gt;&lt;/a&gt;7.                   Is commercial use or distribution authorized?&lt;/h2&gt;                   &lt;p&gt;This feature is about the license granting permission to                   use or distribute the work (or portions thereof) in a trade                   for something of value between two entities &lt;sup&gt;[3]&lt;/sup&gt;.                   The MIT and BSD licenses are not specific about this and the                   Creative Commons licenses offer this permission as the "nc"                   (Non-Commercial) option.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-8.Allowsrelicensing?"&gt;&lt;/a&gt;8. Allows                   re-licensing?&lt;/h2&gt;                   &lt;p&gt;It may be desirable, during the construction of a derived                   work, to license said derived work under different terms. The                   GPL and LGPL offer this possibility as an exception, the EPL                   offers it under certain conditions and the Creative Commons                   licenses grant it if the "sa" (Share Alike) option is not                   used.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-9.Requirespatentsbelicensedtorecipients?"&gt;&lt;/a&gt;9.                   Requires patents be licensed to recipients?&lt;/h2&gt;                   &lt;p&gt;Where patents are concerned, the GPL and LGPL, through                   sections 7 and 11, respectively, state clearly that any                   patents owned by contributors be licensed royalty-free to all                   recipients, direct or indirect. The EPL, on the other hand,                   only requires that patents on contributions be licensed                   royalty-free when combined with "the Program", although the                   EPL joins the MIT and Creative Commons licenses in reminding                   the recipient that there is no guarantee the work does not                   infringe on patents owned by third parties. The EPL goes                   furthest by stating it is the responsibility of the recipients                   to acquire any third-party patent licenses that may be                   required for the use or distribution of the work.&lt;/p&gt;                   &lt;h1&gt;&lt;a name="Assignment1-InterestsandValues"&gt;&lt;/a&gt;Interests and                   Values&lt;/h1&gt;                   &lt;p&gt;These values were derived from the perceived intents of the                   license features identified earlier and form the basis of the                   respective philosophy behind each license.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-1.Equality"&gt;&lt;/a&gt;1. Equality&lt;/h2&gt;                   &lt;blockquote&gt;                     &lt;p&gt;Equality is a social state of affairs in which certain                     different people have the same status in a certain                     respect.&lt;sup&gt;[1]&lt;/sup&gt;&lt;/p&gt;&lt;/blockquote&gt;                   &lt;p&gt;This form of inclusiveness aims to fairly make available                   the work to all possible recipients and ensuring this                   possibility through various conditions, such as ensuring the                   re-distributed work is licensed "as a whole at no charge"                   &lt;sup&gt;[2]&lt;/sup&gt;. While this is generally the primary principle                   behind open-source licensing, half of the Creative Commons                   licenses stand out here because the "nc" option – identified                   in feature #7 – prohibits the use of the work in a commercial                   fashion and thus can be interpreted as introducing inequality.                   It could also, on the other hand, be argued that such a                   restriction may be an attempt to restore equality among                   non-commercial entities relative to their commercial                   counterparts.&lt;/p&gt;                   &lt;p&gt;Another factor potentially affecting equality is the                   Creative Commons licenses' "sa" option – identified in feature                   #8 – that seeks to ensure recipients have as much freedom with                   the derived work as with the original, much the same way                   sections 2b and 6 of the GPL and sections 2c and 10 of the                   LGPL try to ensure the propagation of the rights and freedom                   of the original work to all recipients at all levels of                   distribution.&lt;/p&gt;                &lt;br /&gt;&lt;p&gt;Lastly, feature #9 ensures that no person or groups of                   person be excluded from using the work by having the GPL and                   LGPL require that all patents be licensed royalty free to                   everybody. &lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-2.Merit"&gt;&lt;/a&gt;2. Merit&lt;/h2&gt;                   &lt;p&gt;This value can be understood to mean the desire for                   recognition or acknowledgement, such that a reputation can be                   earned and preserved. We can especially see the expression of                   this value through feature #5 but also through feature #6                   where the authors of the BSD license imagined the possibility                   of mis-use or of sub-optimal derivative works that could                   potentially – albeit unintentionally – reflect badly upon the                   original authors. We can also see a similar attitude with                   section 4a of the Creative Commons licenses where endorsement                   is considered granted in the form of the attribution                   requirement, but for which the Licensor has veto rights                   over.&lt;/p&gt;                   &lt;p&gt;It can also be argued that feature #4 helps support the                   notion of individual merit and reputation by the GPL and LGPL                   requiring that all modifications be identified, even though                   all licenses disclaim any warranties to protect the same                   individuals from damage claims.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-3.Freedom"&gt;&lt;/a&gt;3. Freedom&lt;/h2&gt;                   &lt;p&gt;Although all open-source licenses generally try to increase                   the freedoms of the recipients, the most fervent in its                   attempts to do so is the GPL, especially through feature #8.                   This value is highly regarded as it can help avoid vendor                   lock-in where critical or popular fixes and improvements could                   otherwise be withheld, delayed or prevented by the original                   authors. There are obvious similarities to value #1                   (Equality).&lt;/p&gt;                   &lt;p&gt;Feature #3 tries to make sure recipients (direct or                   indirect) are as able or free to make changes to the work as                   the original authors, provided some conditions are satisfied.                   Again, this is the stated spirit of the GPL and LGPL, although                   the latter trades a few freedoms – hence the "Lesser" in the                   name – to support value #6 (Standardization). Some Creative                   Commons licenses are definitely at odds with this value as the                   "nd" option could be seen as taking away freedom, relatively                   speaking.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-4.Publicgood"&gt;&lt;/a&gt;4. Public good&lt;/h2&gt;                   &lt;p&gt;It is seen as an effort to help the development of the                   greater community and encourage cooperation to emphasize                   elements of feature #3. Similar to value #1, this value                   distinguishes itself from Equality by not only providing equal                   access to the work, but to improvements to the work, such that                   said improvements are done cooperatively and as a community so                   as to best reflect the needs of the many. That is not to say                   that the act of not making available the source code hinders                   public good per se – although some may argue otherwise – but                   that the public good is &lt;em&gt;best&lt;/em&gt; served when the source                   code is also made available.&lt;/p&gt;                   &lt;p&gt;Feature #7 can play a role here, in that allowing                   commercial use and redistribution may also help accelerate the                   development of a popular work, as the LGPL. One could also                   argue the applicability of features #4, #5 and #6 in that they                   could help identify fraudulent or sub-optimal versions of a                   popular work.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-5.Continuousimprovement"&gt;&lt;/a&gt;5.                   Continuous improvement&lt;/h2&gt;                   &lt;p&gt;The permission to re-distribute modified/derived works                   (feature #2), coupled with the guaranteed freedom to make                   modifications (feature #3) help support this special case of                   value #4 (Public Good) where the software is able to be                   evolved and improved. This is where works licensed under the                   GPL have the best chance for continuous improvements and No                   Derivative Creative Commons-licensed content the least                   chance.&lt;/p&gt;                   &lt;p&gt;It could also be argued that the ability to make                   improvements in secret could mean there is less overhead                   involved and the improvements themselves progress faster, but                   such modifications may not be for the greater Public good. In                   those cases the MIT, BSD and EPL licenses offer that                   opportunity and similar, more "open" projects may be created                   to emulate the more secretive counterparts.&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-6.Standardization"&gt;&lt;/a&gt;6.                   Standardization&lt;/h2&gt;                   &lt;p&gt;It may be that it is important a work become popular or                   widely-used. In such cases, the "lesser" conditions attached                   to feature #3 by the LGPL (or by other licenses) may allow                   works such as function libraries to flourish by being used by                   more recipients than otherwise would be possible if said                   recipients had to also release their source code, even if it                   only used the original work. &lt;sup&gt;[5]&lt;/sup&gt;&lt;/p&gt;                   &lt;h2&gt;&lt;a name="Assignment1-7.Accountability"&gt;&lt;/a&gt;7.                   Accountability&lt;/h2&gt;                   &lt;p&gt;Feature #5 helps identify the authors and contributors to                   works and feature #4 enables an order of magnitude better                   traceability to help establish exactly who did what, generally                   to help track down problems and/or defects with the work That                   information could also, in theory, be used to assign blame,                   although all licenses try to avoid this situation by providing                   no warranty of any kind and attempting to shield authors and                   contributors from damage claims.&lt;/p&gt;                   &lt;p&gt;The GPL, LGPL and EPL, however, have an exception that                   permits, through feature #7, the exchange of a warranty for a                   fee, under the condition that the warranty protection can not                   affect other contributors.&lt;/p&gt;                   &lt;p&gt;Lastly, although some patents are licensed for use as per                   feature #9, not all possible patents necessarily are. The EPL                   and MIT licenses are the only two that specifically point out                   the fact that third-party patents may need to be licensed,                   mostly because there is no warranty of non-infringement. The                   GPL and LGPL, on the other hand, are specific about obtaining                   royalty-free patent licensing from all involved parties before                   distributing the work.&lt;/p&gt;                   &lt;h1&gt;&lt;a name="Assignment1-Conclusion"&gt;&lt;/a&gt;Conclusion&lt;/h1&gt;                   &lt;p&gt;As was demonstrated in this study, the licenses vary wildly                   in what they are specific or explicit about, which helps to                   emphasize the differences in values and interests shared by                   the authors of said licenses. It is thus difficult to fully                   compare the chosen set of open source licenses because they do                   not generally disagree on many points, but rather delve into                   different facets of those points at different intensities.&lt;/p&gt;                   &lt;p&gt;It is thus recommended that the choice of an open-source                   license for a new work be made according to the compatibility                   of the author(s)' values with those implied from the licenses.                   An abstraction at this level is thought to deliver the best                   suitability and match.&lt;/p&gt;                   &lt;h1&gt;&lt;a name="Assignment1-References"&gt;&lt;/a&gt;References&lt;/h1&gt;                   &lt;p&gt;1. &lt;b&gt;Social equality&lt;/b&gt;, Wikipedia. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://en.wikipedia.org/wiki/Equality_%28law%29"&gt;http://en.wikipedia.org/wiki/Equality_(law)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;2. &lt;b&gt;The GNU General Public License&lt;/b&gt;, Free Software                   Foundation, Inc. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/licenses/gpl-license.php"&gt;http://www.opensource.org/licenses/gpl-license.php&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;3. &lt;b&gt;Commerce&lt;/b&gt;, Wikipedia. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://en.wikipedia.org/wiki/Commercialization"&gt;http://en.wikipedia.org/wiki/Commercialization&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;4. &lt;b&gt;The Open Source Definition&lt;/b&gt;, Open Source                   Initiative. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/docs/definition.php"&gt;http://www.opensource.org/docs/definition.php&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;5. &lt;b&gt;GNU Lesser General Public License&lt;/b&gt;, Free Software                   Foundation, Inc. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.opensource.org/licenses/lgpl-license.php"&gt;http://www.opensource.org/licenses/lgpl-license.php&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;6. &lt;b&gt;Licensing HOWTO&lt;/b&gt;, Raymond, Eric S. &amp;amp; Catherine                   O. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://www.catb.org/%7Eesr/Licensing-HOWTO.html"&gt;http://www.catb.org/%7Eesr/Licensing%2DHOWTO.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;7. &lt;b&gt;The Power of Personal Values&lt;/b&gt;, Posner, Roy. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://gurusoftware.com/Gurunet/Personal/Topics/Values.htm"&gt;http://gurusoftware.com/Gurunet/Personal/Topics/Values.htm&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;                   &lt;p&gt;8. &lt;b&gt;Commerce&lt;/b&gt;, Wikipedia. &lt;span class="nobr"&gt;&lt;a title="Visit page outside Confluence" href="http://en.wikipedia.org/wiki/Commercialization"&gt;http://en.wikipedia.org/wiki/Commercialization&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-397874431820149854?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/397874431820149854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=397874431820149854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/397874431820149854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/397874431820149854'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/10/comparison-of-open-source-licenses.html' title='Comparison of Open-Source Licenses'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-3446380744703124335</id><published>2006-10-09T08:00:00.001-04:00</published><updated>2006-10-09T08:00:45.900-04:00</updated><title type='text'>DMA is a Good Thing (TM)</title><content type='html'>I was recently ripping audio CDs until I reached a point where it didn't work so well anymore.  Symptoms:  CPU usage would go through the roof (even after changing the process' priority to Low), my pointing device would be erratic, I couldn't play audio at the same time and the ripping itself didn't seem to go as fast as it used to.&lt;br /&gt;&lt;br /&gt;Since the pointer was erratic, I suspected an interrupt problem.  It turns out the drive had was now being accessed in &lt;code&gt;PIO mode&lt;/code&gt;.  I tried the usual "switch to DMA" trick, but it didn't work!  Fortunately, I ran into &lt;a href="http://www.cdrlabs.com/phpBB/viewtopic.php?t=6645"&gt;this forum posting&lt;/a&gt; over at CDRLabs.com where the third post detailed a procedure which seemed less scary than the first one and which worked, to boot!&lt;br /&gt;&lt;br /&gt;Quick recap, in case that forum vanishes into thin bandwidth (hardy har har), because &lt;em&gt;everybody&lt;/em&gt; knows all the forums eventually get &lt;a href="http://en.wikipedia.org/wiki/Pwn3d"&gt;pwn3d&lt;/a&gt; by spoiled twelve-year-olds-who-should-really-be-doing-their-homework-instead-of-saving-the-public-good-from-useful-information-and-loitering-on-my-damn-lawn:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Open your registry to the key:&lt;br /&gt;&lt;code&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96A-E325-11CE-BFC1-08002BE10318}&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Navigate under the sub-key &lt;code&gt;0001&lt;/code&gt; or &lt;code&gt;0002&lt;/code&gt; (representing the &lt;code&gt;primary&lt;/code&gt; and &lt;code&gt;secondary&lt;/code&gt; IDE channels, respectively), whichever one represents the channel for which your device isn't getting DMA-enabled&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Delete the value &lt;code&gt;MasterIdDataChecksum&lt;/code&gt; or &lt;code&gt;SlaveIdDataChecksum&lt;/code&gt;, again depending on whether your DMA-deficient device is the &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;slave&lt;/code&gt;, respectively.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Reboot!&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, this momentary trip to the pre-DMA days &lt;em&gt;really&lt;/em&gt; scared me and made me be thankful for DMA on this day of thanksgiving.  I suspect one of my CDs was scratched or otherwise damaged and my operating system decided it was safer to switch to PIO mode.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-3446380744703124335?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/3446380744703124335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=3446380744703124335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3446380744703124335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/3446380744703124335'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/10/dma-is-good-thing-tm.html' title='DMA is a Good Thing (TM)'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-2466827599708772779</id><published>2006-10-06T09:31:00.000-04:00</published><updated>2006-10-06T09:38:39.957-04:00</updated><title type='text'>Software Horror Stories</title><content type='html'>&lt;a href="http://forums.programming-designs.com/viewtopic.php?pid=3354"&gt;From Programming-Designs.com's forums&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Here are 107 software horror stories where making a programming mistake can cost you your job or even your, or even somebody else's life. Many of these listed provide links to stories about the horrific event while others contain book or magazine references where you can read more about them.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;We heard of the worst of these in our &lt;a href="http://www.carleton.ca/cuuc/courses/COMP/3004.html"&gt;Software Engineering&lt;/a&gt; course at Carleton U.  Many of the events include a link to the &lt;a href="http://catless.ncl.ac.uk/risks"&gt;RISKS digest&lt;/a&gt;, which is a &lt;em&gt;must-read&lt;/em&gt; for every self-respecting software engineer out there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-2466827599708772779?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/2466827599708772779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=2466827599708772779' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2466827599708772779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/2466827599708772779'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/10/software-horror-stories.html' title='Software Horror Stories'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115677693451651611</id><published>2006-09-28T23:45:00.000-04:00</published><updated>2006-08-28T10:55:34.530-04:00</updated><title type='text'>The future of compilers: right now!</title><content type='html'>From &lt;a href="http://www.softwarebyrob.com"&gt;Software by Rob's&lt;/a&gt; post on &lt;a href="http://www.softwarebyrob.com/articles/The_Future_of_Compilers.aspx"&gt;The Future of Compilers&lt;/a&gt;...  The part where he talks about logic errors being detected by compilers can probably &lt;em&gt;already&lt;/em&gt; be done with &lt;a href="http://en.wikipedia.org/wiki/XUnit"&gt;xUnit&lt;/a&gt;, as we (at work) have NUnit running almost like a compiler, right after the actual compilation, in the build script.  That way, if we have a "minus sign in the wrong place", a unit test will catch it, if not prevent it from happening again.&lt;br /&gt;&lt;br /&gt;Some software like &lt;a href="http://www.gotdotnet.com/team/fxcop/"&gt;FxCop&lt;/a&gt; (&lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt; in the Java world) can also help here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115677693451651611?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115677693451651611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115677693451651611' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115677693451651611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115677693451651611'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/08/future-of-compilers.html' title='The future of compilers: right now!'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115950016881120132</id><published>2006-09-28T23:15:00.000-04:00</published><updated>2007-04-06T20:00:04.155-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oss'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><title type='text'>Gopher the Demo Player</title><content type='html'>As part of a &lt;a href="http://www.scs.carleton.ca/~deugo/comp5900/"&gt;university course&lt;/a&gt; I am taking (I've gone back to &lt;a href="http://www.carleton.ca/"&gt;Carleton U&lt;/a&gt; for a &lt;a href="http://ocics.site.uottawa.ca/"&gt;M.C.S.&lt;/a&gt;), I am to make a presentation on some open-source software.  I picked my own project, &lt;a href="http://sf.net/projects/gopherdemoplayer"&gt;Gopher the Demo Player&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The presentation slides can be downloaded &lt;a href="http://opendemogroup.dyndns.org/confluence/download/attachments/268/Gopher+the+Demo+Player.pdf"&gt;here&lt;/a&gt; (PDF, 693 902 bytes).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115950016881120132?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115950016881120132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115950016881120132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115950016881120132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115950016881120132'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/09/gopher-demo-player_28.html' title='Gopher the Demo Player'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115930173281846663</id><published>2006-09-28T22:50:00.000-04:00</published><updated>2006-09-28T22:54:58.286-04:00</updated><title type='text'>Hacking the Microsoft Natural Ergonomic Keyboard 4000</title><content type='html'>I am very happy with my &lt;a href="http://www.microsoft.com/hardware/mouseandkeyboard/productdetails.aspx?pid=043"&gt;Microsoft Natural Ergonomic Keyboard 4000&lt;/a&gt; as it's &lt;em&gt;finally&lt;/em&gt; a natural keyboard that (again) has the inverted T arrow keypad and the standard-size insert key, just like the good ol' 101-key days.  In other words, it's like the original Microsoft Natural keyboard, but with "new interweb buttons", an even more natural layout (the "comfort curve design" makes more sense for the way fingers are laid out) and a "zooming thingy".&lt;br /&gt;&lt;br /&gt;That "Zoom slider", however, should have been sold/marketed as a "Scroll rocker button", because I do far more scrolling than zooming and, besides, you can usually zoom by scrolling and holding down the &lt;code&gt;Ctrl&lt;/code&gt; key in most programs.  Well, those by Microsoft anyway.&lt;br /&gt;&lt;br /&gt;Anyway, it turns out it's configurable if you:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;don't mind editing some XML&lt;/li&gt;&lt;br /&gt;&lt;li&gt;don't mind that it's not &lt;em&gt;really&lt;/em&gt; XML&lt;br /&gt;&lt;blockquote&gt;Just try adding an XML comment to document your changes (like &lt;code&gt;&amp;lt;!-- changed by Oli --&amp;gt;&lt;/code&gt;) and watch the &lt;code&gt;type32.exe&lt;/code&gt; (or &lt;code&gt;itype.exe&lt;/code&gt;, depending on your version) program crash every time you hit a magic key to see what I mean. :p&lt;/blockquote&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Here's a &lt;code&gt;DIFF&lt;/code&gt; of the changes to &lt;code&gt;C:\Program&amp;nbsp;Files\Microsoft&amp;nbsp;IntelliType&amp;nbsp;Pro\commands.xml&lt;/code&gt; that disable most customizations of the &lt;code&gt;C319&lt;/code&gt; and &lt;code&gt;C320&lt;/code&gt; keys, which are &lt;strong&gt;rock up/away&lt;/strong&gt; and &lt;strong&gt;rock down/toward&lt;/strong&gt;, respectively.  I know it works with versions 5.3.606.0 (aka 5.30.606.0) and 5.5.661.0 (aka 5.50.661.0) of the IntelliType software, maybe also others.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- commands.old    2005-03-15 04:46:45.000000000 -0500&lt;br /&gt;+++ commands.xml    2006-09-26 15:45:38.718750000 -0400&lt;br /&gt;@@ -1606,8 +1606,8 @@&lt;br /&gt;             &amp;lt;C101 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;alt rightarrow&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C103 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;escape&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C300 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;enter&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomIn&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomOut&amp;quot; /&amp;gt;            &lt;br /&gt;+            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollUp&amp;quot; /&amp;gt;&lt;br /&gt;+            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollDown&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C1101 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;HorizontalScroll&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C1003 Type=&amp;quot;7&amp;quot; Subtype=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;         &amp;lt;/Application&amp;gt;&lt;br /&gt;@@ -1694,8 +1694,6 @@&lt;br /&gt;         &amp;lt;Application UniqueName=&amp;quot;rctrl_renwnd32&amp;quot; AppName=&amp;quot;Microsoft Outlook&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;C1003 Type=&amp;quot;7&amp;quot; Subtype=&amp;quot;3&amp;quot; wParam=&amp;quot;0x01672&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C401 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;F7&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;OutlookZoomIn&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;OutlookZoomOut&amp;quot; /&amp;gt;            &lt;br /&gt;         &amp;lt;/Application&amp;gt;&lt;br /&gt;         &amp;lt;Application UniqueName=&amp;quot;screenClass&amp;quot; AppName=&amp;quot;Microsoft PowerPoint&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;C100 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;pageup&amp;quot; /&amp;gt;&lt;br /&gt;@@ -2124,8 +2122,6 @@&lt;br /&gt;             &amp;lt;C309 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C204 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C315 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09cc4&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomOut&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomIn&amp;quot; /&amp;gt;            &lt;br /&gt;             &amp;lt;C401 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C900 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09cf0&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C902 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;@@ -2138,8 +2134,6 @@&lt;br /&gt;             &amp;lt;C311 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09d23&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C310 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09cb4&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C315 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09cc7&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomOut&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomIn&amp;quot; /&amp;gt;            &lt;br /&gt;             &amp;lt;C401 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x19d47&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C900 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09cf0&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C902 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x09ddb&amp;quot; /&amp;gt;&lt;br /&gt;@@ -2158,8 +2152,8 @@&lt;br /&gt;             &amp;lt;C101 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x01798&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C103 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C102 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;ctrl add&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;ctrl subtract&amp;quot;/&amp;gt;            &lt;br /&gt;+            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollUp&amp;quot; /&amp;gt;&lt;br /&gt;+            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollDown&amp;quot;/&amp;gt;&lt;br /&gt;         &amp;lt;/Application&amp;gt;&lt;br /&gt;         &amp;lt;Application UniqueName=&amp;quot;MSN6 Window&amp;quot; AppName=&amp;quot;MSN Window&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;C204 Type=&amp;quot;5&amp;quot; KeySeq=&amp;quot;ctrl y&amp;quot; /&amp;gt;&lt;br /&gt;@@ -2188,8 +2182,8 @@&lt;br /&gt;             &amp;lt;C106 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x0a125&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C104 Type=&amp;quot;2&amp;quot; lParam=&amp;quot;0x05&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C105 Type=&amp;quot;2&amp;quot; lParam=&amp;quot;0x06&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomOut&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomIn&amp;quot; /&amp;gt;            &lt;br /&gt;+            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollUp&amp;quot; /&amp;gt;&lt;br /&gt;+            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollDown&amp;quot; /&amp;gt;&lt;br /&gt;         &amp;lt;/Application&amp;gt;&lt;br /&gt;         &amp;lt;Application UniqueName=&amp;quot;Internet Explorer_TridentDlgFrame&amp;quot; AppName=&amp;quot;Internet Explorer Child&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;C103 Type=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;@@ -2230,8 +2224,8 @@&lt;br /&gt;             &amp;lt;C105 Type=&amp;quot;2&amp;quot; lParam=&amp;quot;0x06&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C106 Type=&amp;quot;2&amp;quot; lParam=&amp;quot;0x07&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;C104 Type=&amp;quot;2&amp;quot; lParam=&amp;quot;0x05&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomOut&amp;quot; /&amp;gt;&lt;br /&gt;-            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ZoomIn&amp;quot; /&amp;gt;            &lt;br /&gt;+            &amp;lt;C319 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollUp&amp;quot; /&amp;gt;&lt;br /&gt;+            &amp;lt;C320 Type=&amp;quot;6&amp;quot; Activator=&amp;quot;ScrollDown&amp;quot; /&amp;gt;&lt;br /&gt;         &amp;lt;/Application&amp;gt;&lt;br /&gt;         &amp;lt;Application UniqueName=&amp;quot;HH Child&amp;quot; AppName=&amp;quot;HTML C302&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;C310 Type=&amp;quot;1&amp;quot; wParam=&amp;quot;0x000cf&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Warning:&lt;/strong&gt; The preceding code block came with no warranty whatsoever, so if your dog died, your significant other left you and/or your house burned down as a result of &lt;em&gt;reading&lt;/em&gt; the previous code block, well, sorry, but you should have read this disclaimer first.  Please don't sue me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115930173281846663?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115930173281846663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115930173281846663' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115930173281846663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115930173281846663'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/09/hacking-microsoft-natural-ergonomic.html' title='Hacking the Microsoft Natural Ergonomic Keyboard 4000'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115869625009648191</id><published>2006-09-26T18:55:00.000-04:00</published><updated>2006-09-26T19:01:45.530-04:00</updated><title type='text'>Other cool software you've never heard of</title><content type='html'>&lt;a href="http://oliiscool.blogspot.com/2006/08/these-are-few-of-my-favorite-things.html"&gt;Last time&lt;/a&gt; I promised to write about some less crucial but-still-really-useful pieces of software I often use.  Here's the "priority 2" list:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.grigsoft.com/wincmp3.htm"&gt;Compare It!&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The best diff/merge utility and thus the third best use of $30 I ever spent.  I think it's its keyboard support and light-weight-ness that I enjoy most.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I tried (and even purchased!) DiffDog, but then it crashed too often and would hog the CPU too much for my liking and it looks like Altova couldn't care less about fixing the bugs.  I used to like Araxis Merge also, but why pay $130 (USD) when you get almost everything (except 3-way diff/merge) for $30??&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.hamachi.cc"&gt;Hamachi&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Secure VPN between computers.  Fantastic for playing games with friends from different houses or for remote access between two [otherwise] firewalled hosts on the internet.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.google.com/search?q=k-lite%20mega%20codec%20pack"&gt;K-Lite Mega Codec Pack&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Finally!  No more spyware-infected, 54324-AOL-icons-on-your-desktop and 3420-icons-in-your-system-tray multimedia player distributions!  These guys packaged up &lt;strong&gt;Media Player Classic&lt;/strong&gt; with &lt;strike&gt;a few&lt;/strike&gt; lots of CODECs.  This means that after installing this &lt;em&gt;one&lt;/em&gt; package, you can play any audio or video file you aunt Linda will e-mail you every second rainy Tuesday afternoon.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Did I mention &lt;strong&gt;Media Player Classic&lt;/strong&gt;?? (yes I did)  Well, I need to mention it again, because it means you'll never need to ever see those stupid ads on the side or under the aforementioned funny video Linda sent you.  You'll also never have to wait the extra 25 seconds it takes for those damn things to load, skin, check for updates and pop up some dialogs saying "please send us money to help us continue to make your media playing life hell".  MPC is slick, fast, small and an excellent example of where Microsoft should have stopped working on their Media Player.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://rsspopper.blogspot.com/2004/10/home.html"&gt;RSS Popper&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;RSS/ATOM feed fetcher, delivers to specified Outlook folders.  Works as advertised.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;This means I can read my feeds from anywhere I can access my Outlook mailbox thus I don't end up reading the same articles over and over again between my work computer, home computer, laptop and PDA. (well, &lt;em&gt;almost&lt;/em&gt;, as I haven't quite mastered mail sync for my ancient Palm III on a modern OS)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.ultrapico.com/Expresso.htm"&gt;Expresso&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Regular Expression Development Tool.  Allows you to write and test your regular expressions in a quick, tight loop so that you can fix the mistake before your string contains 5435643789 characters. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;The testing itself is fantastic as it will present all matches in a treeview, allowing you to expand the match groups to see exactly what was matched.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115869625009648191?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115869625009648191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115869625009648191' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115869625009648191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115869625009648191'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/09/other-cool-software-youve-never-heard.html' title='Other cool software you&apos;ve never heard of'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115930254346389247</id><published>2006-09-26T16:27:00.000-04:00</published><updated>2007-04-06T19:57:47.648-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>How to inspire confidence in your build process</title><content type='html'>&lt;a href="http://ankhsvn.tigris.org/servlets/ProjectDocumentView?documentID=33676&amp;showInfo=true"&gt;From the Ankhsvn website&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Same build as above, but works.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;LOL&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update&lt;/strong&gt;: added some labels&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115930254346389247?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115930254346389247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115930254346389247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115930254346389247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115930254346389247'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/09/how-to-inspire-confidence-in-your.html' title='How to inspire confidence in your build process'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115653579344549564</id><published>2006-08-25T15:44:00.000-04:00</published><updated>2006-09-06T00:14:02.383-04:00</updated><title type='text'>These are a few of my favorite things</title><content type='html'>No, I won't be talking about "raindrops on roses" or "brown paper packages", but rather a set of software tools I have found I cannot live without. Well, ok:  I won't die or something, but if I have to &lt;strong&gt;use&lt;/strong&gt; a computer without the following installed, I get &lt;em&gt;very&lt;/em&gt; frustrated:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.altap.cz/salam_en/index.html"&gt;Servant Salamander&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The next step after the good old &lt;strong&gt;Norton Commander&lt;/strong&gt;, this &lt;a href="http://en.wikipedia.org/wiki/Orthodox_file_manager"&gt;Orthodox File Manager&lt;/a&gt; (OFM) allows me to perform file operations faster than Windows Explorer or any command-line I have ever used.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;This is &lt;em&gt;the&lt;/em&gt; software that keeps me on Windows and the best $30 I ever spent.  I have yet to find anything that equals it for other platforms, although &lt;a href="http://krusader.sourceforge.net/"&gt;Krusader&lt;/a&gt; comes close and &lt;a href="http://www.ibiblio.org/mc/"&gt;Midnight Commander&lt;/a&gt; still feels as akward to use as Norton Commander does after trying Servant Salamander.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://scintilla.sourceforge.net/SciTE.html"&gt;SciTE&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SCIntilla-based Text Editor.  Syntax-highlighting, auto-completing and folding compact editor.  I use it to edit every text file when I'm not using Visual Studio.  Look for the occasional patch from yours truly on their mailing list.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.maxthon.com/"&gt;Maxthon&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Internet Explorer with tabs and stuff!  The single best feature is the &lt;strong&gt;download control&lt;/strong&gt;, which allows me to turn off, by default, JavaScript, ActiveX, Java, sounds and videos.  This makes it &lt;em&gt;really&lt;/em&gt; easy to &lt;a href="https://www.microsoft.com/technet/archive/community/columns/security/essays/10imlaws.mspx#EBB"&gt;surf safely&lt;/a&gt; and only turn those features you need when you trust the site, although a persistent "safe list" would be really nice for those sites I visit often.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Some of you may point out that &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; also has tabs &lt;strong&gt;and&lt;/strong&gt; a &lt;a href="https://addons.mozilla.org/firefox/722/"&gt;similar script disabling facility&lt;/a&gt; (which &lt;em&gt;does&lt;/em&gt; support a safe list), so, err..., until I can &lt;em&gt;configure&lt;/em&gt; it to have an experience like I have in Maxthon (which is a similar problem I have with most OFMs), I'll stick with Maxthon a little longer.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.xi-soft.com/default.htm"&gt;Net Transport&lt;/a&gt; (NetXfer)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fantastic software for downloading files.  I use it primarily to queue up and throttle downloads, but it's also super at preparing batches of downloads through its browser integration that scans the current HTML for links and allows you to pick which ones to queue up.  It also supports tricky protocols and scheduled downloads.  It looks like my wish for BitTorrent support has &lt;em&gt;recently&lt;/em&gt; come true, so I'll be trying that new version out very shortly. :)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Next time, I'll post about other cool software you've never heard of, but this time I can sort of tolerate using a computer without.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115653579344549564?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115653579344549564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115653579344549564' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115653579344549564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115653579344549564'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/08/these-are-few-of-my-favorite-things.html' title='These are a few of my favorite things'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115498988518470052</id><published>2006-08-07T18:01:00.000-04:00</published><updated>2006-08-07T18:33:38.060-04:00</updated><title type='text'>Always provide a manual option</title><content type='html'>My wife and I picked up a friend from the Ottawa airport the other day.  On our way out, we had to pay for parking at one of those booths with a mechanical barrier.  Only when we paid, the barrier didn't go up.  The attendant looked at us funny, saying: "Ok, you can go now", and we looked at him with an equally funny look saying: "Sure, just lift the barrier first".&lt;br /&gt;&lt;br /&gt;After a few iterations of this, including the attendant's assurance he had pressed the right button (and hence the gate should be up), he realized maybe we weren't making it up (he's facing the other way) and told us he had to call someone else to get it open.  That someone else eventually showed up with a set of keys &lt;em&gt;and a screwdriver-like tool&lt;/em&gt;, which he proceeded to use to open up the mechanical barrier's box.  This got the barrier to lift, apparently mechanically.&lt;br /&gt;&lt;br /&gt;The RISKS?  Well, you'd hate to have the power go out or have an emergency of some sort, since it can obviously fail.  Those gates should use a &lt;em&gt;mechanical assist&lt;/em&gt; -- thus allowing a human being the option of lifting the barrier themselves -- instead of a completely mechanical drive, just like most garage door openers have that dangling string you can pull on to switch to "manual mode".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since this blog is about software, ummm... the lesson is the same!  Always provide a manual option or an override in software.  It's no coincidence &lt;a href="http://www.google.com/search?q=computers+in+movies+override"&gt;computers in movies always have an "override" option&lt;/a&gt; (although it's admittedly unlikely those people can somehow always get authorization to do so), but the message is clear;  there's always a special circumstance where normal rules/validation conflict or aren't appropriate and thus should be temporarily disabled.&lt;br /&gt;&lt;br /&gt;That is, if you want your software to be used.  After all, business must go on and if the software refuses to accept &lt;em&gt;unusual&lt;/em&gt; input (especially as the business evolves), then people will work around the software and use it less and less.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So think about this issue the next time you need to implement some sort of validation and make it &lt;a href="http://www.google.com/search?q=more+like+guidelines"&gt;more like guidelines&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115498988518470052?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115498988518470052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115498988518470052' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115498988518470052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115498988518470052'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/08/always-provide-manual-option.html' title='Always provide a manual option'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115432223215800200</id><published>2006-07-31T00:17:00.000-04:00</published><updated>2006-07-31T01:14:13.910-04:00</updated><title type='text'>SanDisk is "cruzing" for a bruisin' with their U3 Launchpad</title><content type='html'>Tonight, I was helping my mother with her Mac laptop and new "SanDisk U3 Cruzer Micro" memory stick. She purchased it to be able to "carry pictures around", mostly from her computer to the &lt;a href="http://www.jeancoutu.com/"&gt;Jean Coutu&lt;/a&gt; so they could be printed. Simple enough.&lt;br /&gt;&lt;br /&gt;She tells me she had had some difficulty when she last tried it, so, this being 2006 and plug-and-play no longer needs to be [air] quoted, I ask her to plug it in to see what would happen. She does and some "disk utility" thing seems to pop up. She might have clicked something that was bouncing in her dock or something (my attention was diverted for a second) but there it was. I recognized the window for what it was, and had her exit it since I also noticed a new icon on her desktop that looked like what you should expect from plug-and-play.&lt;br /&gt;&lt;br /&gt;She double-clicks on said icon and, as expected, a window opens up with the contents of the removable device. Except there already files in there. A System folder, a Documents folder and some EXE. At first, I thought it might have been the case she picked up a used memory stick. By digging into the folders, I notice it's software that would most likely be bundled, such as Skype. I simply have her delete everything on the memory stick, except that the EXE in the root folder wasn't getting deleted because it was marked as "protected". "Weird, but not a problem", I tell her; "I'll just erase that when I try it in my laptop".&lt;br /&gt;&lt;br /&gt;So she plays around for a bit, I show her how she can drag pictures from iPhoto into the window representing her memory stick and &lt;a href="http://www.apple.com/getamac/ads/"&gt;all goes well&lt;/a&gt;. I show her how she "ejects" the device before unplugging it (she remembered the scolding she got last time she didn't eject it first) and then I plug it in my laptop to make sure the pictures were indeed copied.&lt;br /&gt;&lt;br /&gt;After plugging it in to one of the USB ports, I notice my computer taking a long time "installing" the new drivers. I thought that was odd as I frequently pop in my digital camera's SD card in the appropriate slot on the side of the computer and it works just as floppy disks did. Then I notice the set of "devices" being detected includes a "CD-ROM" (??) and this animated splash screen follows by saying that the launchpad is loading and it will appear in my system tray when it's done loading. Only it just hung there, most likely because I was running under a low-permission account; I kill the process and fire up my &lt;a href="http://www.altap.cz/salam_en/index.html"&gt;favorite file manager&lt;/a&gt;, only to notice there are TWO new devices showing up and one of them indeed looks like a CD-ROM drive.&lt;br /&gt;&lt;br /&gt;I'm pretty sure I didn't miss a Slashdot announcement on compact disks being reduced to the size of a dime (mini-SD cards excluded) and then I realize what had happened; that EXE on the memory stick had been executed and had installed some "drivers" to be "helpful". Remembering why &lt;a href="http://www.google.com/search?q=sony+rootkit"&gt;Sony sucks&lt;/a&gt;, I start to panic: what if I just got infected with some similar shit? Why weren't my permissions low enough to prevent this?? Why didn't I turn "AutoPlay" off earlier???&lt;br /&gt;&lt;br /&gt;If you are still reading intently at this point, you are probably a fan of &lt;i&gt;hyperlinked&lt;/i&gt; IT drama stories, and that's pretty sad. Just &lt;a href="http://www.useit.com/alertbox/whyscanning.html"&gt;scan like everybody else&lt;/a&gt; and scroll already to the part about removing the damn thing, which has been placed just below this paragraph to ease you into this "scrolling to the interesting stuff" business.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;How to remove the damn thing&lt;/h2&gt;Web searches for "remove driver u3 sandisk" didn't yield anything interesting except that I noticed lots and lots of people are trying to sell or review the damn things. Note to self: remember to repeat the search and click on Google's "Dissatisfied? Help us improve" link. The closest I found was this answer from the &lt;a href="http://www.u3.com/support/#CQ6"&gt;U3 support commonly asked questions&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;h3&gt;6. I want to uninstall the U3 Launchpad from my smart drive&lt;/h3&gt;The U3 Launchpad is only supported on Windows XP and Windows 2000 operating systems and this restriction extends to U3 Launchpad uninstallers. A U3 Launchpad uninstaller is a software module that removes the U3 Launchpad and re-configures the drive to be a single mass storage USB drive. U3 Launchpad uninstallers are only available for and must be run on Windows XP or Windows 2000 machines. The locations for the uninstallers are provided here: &lt;/blockquote&gt;...followed by two links to the product pages that contain no actual uninstallers (surprise, surprise! - but I did find a link called &lt;a href="http://www.sandisk.com/Retail/Default.aspx?CatID=1415"&gt;Launchpad Removal&lt;/a&gt;) and the last one allows you to download a program that pretty much &lt;b&gt;reformats your memory stick&lt;/b&gt; to remove all traces of the launchpad software &lt;i&gt;on the memory stick&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;How to remove the malicious, self-installed drivers&lt;/h2&gt;Errr... I'm not sure. Before I found the uninstall software, I tried uninstalling the drivers from Device Manager, but they would come back after plugging the stick in again, even though I was holding down SHIFT the whole time and had disabled AutoPlay for removable drives. Hmmm... Note to self: investigate how to enforce the "no autoplay whatsoever" group policy and file a bug report with Microsoft if that's not possible... no, if it's not super easy.. not that either; if it's not THE DEFAULT BEHAVIOUR on new installs.&lt;br /&gt;&lt;br /&gt;The best way is probably to reformat the stick with another operating system, or one that's suitably configured to not get itself infected when plugging stuff in.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What's the problem, here?&lt;/h2&gt;You must work for SanDisk or be one of the programmers of U3. I would like to point you to the &lt;a href="http://catless.ncl.ac.uk/risks"&gt;THE RISKS DIGEST&lt;/a&gt;. Read it for a while. Browse through their archives. Find the story from two or more years ago that talked about how easy it would be for malicious programs to automatically run when memory sticks are inserted into PCs and how it could be used for instamatic industrial espionage/sabotage and how this has led to organizations filling in all USB sockets with epoxy (or simply removing them from boxes) to avoid having to deal with the problem altogether.&lt;br /&gt;&lt;br /&gt;Now that you are enlightened in the matters of responsible software engineering, go convince your superiors that you should ship BLANK MEMORY STICKS and an &lt;i&gt;optional&lt;/i&gt; software CD instead, after releasing instructions or software for removing all traces of your drivers in my registry as well as proving to me, in some way or another, that you didn't also install a keylogger or other malicious software on my computer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;In Conclusion&lt;/h2&gt;I'm obviously not paranoid enough about checking my system for the presence of a rootkit infection or disassembling the software to confirm/deny my fears.  Maybe someone else (with more free time than me) will come along and make a more informed determination.  Oh, and I should stick to the point and stop telling long, boring IT drama stories.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115432223215800200?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115432223215800200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115432223215800200' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115432223215800200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115432223215800200'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/07/sandisk-is-cruzing-for-bruisin-with.html' title='SanDisk is &quot;cruzing&quot; for a bruisin&apos; with their U3 Launchpad'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29787727.post-115042347100315708</id><published>2006-06-15T22:02:00.000-04:00</published><updated>2006-06-15T22:05:55.183-04:00</updated><title type='text'>Console.WriteLine ( "Hello world!" );</title><content type='html'>I'm _finally_ blogging!  Now to find something interesting to write about...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29787727-115042347100315708?l=oliiscool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oliiscool.blogspot.com/feeds/115042347100315708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29787727&amp;postID=115042347100315708' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115042347100315708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29787727/posts/default/115042347100315708'/><link rel='alternate' type='text/html' href='http://oliiscool.blogspot.com/2006/06/consolewriteline-hello-world.html' title='Console.WriteLine ( &quot;Hello world!&quot; );'/><author><name>Olivier Dagenais</name><uri>http://www.blogger.com/profile/15266172524939380849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/blogger2/1615/3636/1600/thumbup.jpg'/></author><thr:total>1</thr:total></entry></feed>
