<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>dojo7</title>
  <subtitle>The tech blog of Peter Hollows</subtitle>
  <id>http://dojo7.com/</id>
  <link href="http://dojo7.com/"/>
  <link href="http://dojo7.com/feed.xml" rel="self"/>
  <updated>2012-01-17T00:00:00+11:00</updated>
  <author>
    <name>Peter Hollows</name>
  </author>
  <entry>
    <title>WallMap: Building a huge Google Maps poster</title>
    <link rel="alternate" href="/2012/01/17/how-to-make-a-huge-google-maps-poster.html"/>
    <id>/2012/01/17/how-to-make-a-huge-google-maps-poster.html</id>
    <published>2012-01-17T00:00:00+11:00</published>
    <updated>2012-01-17T00:00:00+11:00</updated>
    <author>
      <name>Article Author</name>
    </author>
    <summary type="html">&lt;p&gt;With a new apartment comes new projects! There&amp;#8217;s a spare wall near the build space that could do with something useful on it. We decided a map would be good. Now to render the map!&lt;/p&gt;

&lt;p&gt;I used the excellent Google &lt;a href='http://bit.ly/zweX5r'&gt;Static Maps API&lt;/a&gt;, the JS API, some CoffeeScript and a static website to create the map.&lt;/p&gt;</summary>
    <content type="html">&lt;p&gt;With a new apartment comes new projects! There&amp;#8217;s a spare wall near the build space that could do with something useful on it. We decided a map would be good. Now to render the map!&lt;/p&gt;

&lt;p&gt;I used the excellent Google &lt;a href='http://bit.ly/zweX5r'&gt;Static Maps API&lt;/a&gt;, the JS API, some CoffeeScript and a static website to create the map.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h2 id='getting_the_tiles'&gt;Getting the tiles&lt;/h2&gt;

&lt;p&gt;Google provide a scale control for their static maps, which means we can get nice large images that are viewable from a distance. Cranking the scale to 2 gives us double the DPI. The API docs mention 4 is available for business customers. This feature was introduced for hi-res handsets and the like.&lt;/p&gt;

&lt;p&gt;Requesting scale=2&amp;#38;size=640x640 (the maximum size for free-use), we get a 1280x1280 image of the target area.&lt;/p&gt;

&lt;p&gt;Click on the image below to see the full sized tile.&lt;/p&gt;
&lt;a href='http://bit.ly/wBNkQ5' target='_blank'&gt;
  &lt;img alt='Google Static Maps API Melbourne' class='picture large' src='http://bit.ly/wBNkQ5' /&gt;
&lt;/a&gt;
&lt;h2 id='pantiling_in_javascript'&gt;Pan-tiling in Javascript&lt;/h2&gt;

&lt;p&gt;There are mathematically nice ways of doing things and easy ways to do things. The fastest route was to use the &lt;a href='http://bit.ly/x6Nnuk'&gt;Google Maps Javascript API&lt;/a&gt; to do the geo-math for us. Specifically, we&amp;#8217;re able to pan by pixel amounts rather than degrees. We also get a nice UI for defining the approximate poster bounds.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the demo :D&lt;/p&gt;
&lt;script src='http://maps.googleapis.com/maps/api/js?sensor=true' type='text/javascript'&gt;
&lt;/script&gt;&lt;script type='text/javascript'&gt;
  (function() { // Load WallMap script
    var s   = document.getElementsByTagName('script')[0];
    var t   = document.createElement('script');
    t.type  = 'text/javascript';
    t.src   = "/js/wallmap.js";
    t.defer = true;
    s.parentNode.insertBefore(t, s);
  })();
  (function() { // Load WallMap CSS
    var l   = document.getElementsByTagName('link')[0];
    var t   = document.createElement('link');
    t.rel   = 'stylesheet';
    t.href  = "/css/wallmap.css";
    l.parentNode.insertBefore(t, l);
  })();
&lt;/script&gt;&lt;div id='wm_controls'&gt;
&lt;/div&gt;&lt;div id='wm_viewer'&gt;
  &lt;div id='wm_map'&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The green overlays drawn are the frames for our tiles. We worked out where the tiles should be by zooming in (to the detail zoom level), panning pixel distances (to the next tile) which now fills the map window, then fetching the map bounds to get our tile image coordinates.&lt;/p&gt;

&lt;p&gt;You can now run this generated convert command (if you have ImageMagick) to fetch and combine the images.&lt;/p&gt;
&lt;div id='wm_result'&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://bit.ly/xt2nKP'&gt;Source for WallMap&lt;/a&gt; is available on GitHub.&lt;/p&gt;

&lt;h2 id='tile_zoom_level'&gt;Tile zoom level&lt;/h2&gt;

&lt;p&gt;The detail zoom level controls the size of features like roads, building boundaries and areas. Scale controls the size of map text, symbols, stroke line widths and other details.&lt;/p&gt;

&lt;p&gt;Figuring out which zoom level is desired requires some experimentation balancing desired coverage area and available wall space. Printed out, the first batch of tiles looked like this.&lt;/p&gt;
&lt;img alt='WallMap Test 1 Printed' class='picture large' src='how-to-make-a-huge-google-maps-poster/IMG_0025.jpg' /&gt;&lt;img alt='WallMap Test 1 Posted' class='picture large' src='how-to-make-a-huge-google-maps-poster/IMG_0082.jpg' /&gt;
&lt;h2 id='printing_it'&gt;Printing it&amp;#8230;&lt;/h2&gt;

&lt;p&gt;Once the PNG is built, the next step is to use software like &lt;a href='http://posterazor.sourceforge.net/'&gt;posterazor&lt;/a&gt; to cut it up and print it out. It&amp;#8217;s a work in progress. More to come.&lt;/p&gt;
&lt;img alt='WallMap' class='picture large' src='how-to-make-a-huge-google-maps-poster/IMG_0083.jpg' /&gt;</content>
  </entry>
  <entry>
    <title>Cracking Station Upgrade</title>
    <link rel="alternate" href="/2012/01/16/cracking-station-upgrade.html"/>
    <id>/2012/01/16/cracking-station-upgrade.html</id>
    <published>2012-01-16T00:00:00+11:00</published>
    <updated>2012-01-16T00:00:00+11:00</updated>
    <author>
      <name>Article Author</name>
    </author>
    <summary type="html">&lt;p&gt;More work on the hashing supercomputer.&lt;/p&gt;</summary>
    <content type="html">&lt;p&gt;More work on the hashing supercomputer.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been transforming my NAS box into a hash-cracking station. I acquired a &lt;a href='http://bit.ly/AmxyM4'&gt;Gigabyte HD 6770 SC&lt;/a&gt;, a high performance, high frequency AMD GPU that&amp;#8217;s &lt;a href='http://bit.ly/x1nW3q'&gt;OpenCL&lt;/a&gt; friendly. This card is cheap (and quiet) for its computational power because it has less RAM than competing graphics cards in the same bracket (graphics RAM &lt;em&gt;speed&lt;/em&gt; matters for this application, but capacity has minimal impact).&lt;/p&gt;

&lt;p&gt;For comparison, here&amp;#8217;s the &lt;a href='http://bit.ly/yMyKwm'&gt;Gigabyte HD GV-R797D5-3GD-B&lt;/a&gt;. One of the most hard-core graphics cards available when this was written.&lt;/p&gt;
&lt;table&gt;
	&lt;caption&gt;
    HD 6770 price/performance 
	&lt;/caption&gt;
	&lt;thead&gt;
		&lt;tr&gt;
      &lt;th scope='col'&gt;Aspect&lt;/th&gt;
			&lt;th class='num' scope='col'&gt;6770&lt;/th&gt;
			&lt;th class='num' scope='col'&gt;GV-R797D5-3GD-B&lt;/th&gt;
      &lt;th class='num' scope='col'&gt;% inc.&lt;/th&gt;
      &lt;th scope='col'&gt;Relevance&lt;/th&gt;
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tfoot&gt;
		&lt;tr&gt;
      &lt;th scope='row'&gt;Price&lt;/th&gt;
			&lt;td class='num'&gt;$139.00&lt;/td&gt;
			&lt;td class='num'&gt;$793.00&lt;/td&gt;
      &lt;td class='num'&gt;+471%&lt;/td&gt;
      &lt;td&gt;6770 is near the sweet spot&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tfoot&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
      &lt;th scope='row'&gt;Core Clock&lt;/th&gt;
			&lt;td class='num'&gt;850 MHz&lt;/td&gt;
			&lt;td class='num'&gt;925 MHz&lt;/td&gt;
      &lt;td class='num'&gt;+9%&lt;/td&gt;
      &lt;td&gt;We care about this&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
      &lt;th scope='row'&gt;Memory Clock&lt;/th&gt;
			&lt;td class='num'&gt;4800 MHz&lt;/td&gt;
			&lt;td class='num'&gt;5500 MHz&lt;/td&gt;
      &lt;td class='num'&gt;+15%&lt;/td&gt;
      &lt;td&gt;This too&lt;/td&gt;
		&lt;/tr&gt;
    &lt;tr&gt;
      &lt;th scope='row'&gt;Memory Size&lt;/th&gt;
      &lt;td class='num'&gt;1024 MB&lt;/td&gt;
      &lt;td class='num'&gt;3072 MB&lt;/td&gt;
      &lt;td class='num'&gt;+200%&lt;/td&gt;
      &lt;td&gt;This can be flexible&lt;/td&gt;
    &lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For basic OpenCL based number crunching, the 6770 has some pretty decent specs for the price.&lt;/p&gt;

&lt;p&gt;Well, today was a hot one in Melbourne and after testing out the card with &lt;a href='http://bit.ly/wj3xEl'&gt;OCLHashCat&lt;/a&gt; the rig nearly melted, reaching a GPU temperature of &lt;em&gt;90&amp;#176;C&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There are reports of these cards running hot. The fanless design may account for that, and they probably had to accept certain trade-offs when designing the thing. The weird thing was, just replacing the factory thermal grease with some &lt;a href='http://bit.ly/zaiyjd'&gt;Arctic Silver 5&lt;/a&gt; dropped the idle temperature from 65&amp;#176;C to 52&amp;#176;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve moved from 2 to 4 silent fans for good measure, taking the full-load temperature (92% GPU utilization for 30 minutes) down to a stable 71&amp;#176;, and idle temperature down to 43&amp;#176;.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the &lt;a href='http://bit.ly/xbGdAt'&gt;Pyrit&lt;/a&gt; benchmark of the continuously achievable WPA2 hash-rate (4,096 iterations of HMAC-SHA1 per WPA2 PMK).&lt;/p&gt;
&lt;script src='https://gist.github.com/1620261.js?file=pyrit-benchmark-output' type='text/javascript'&gt; &lt;/script&gt;
&lt;p&gt;Around &lt;em&gt;one hundred million&lt;/em&gt; HMAC-SHA1s per second (leveraging SSE2 on the 2.4GHz Athlon&amp;#160;II does about 2% of that). Nice.&lt;/p&gt;

&lt;h2 id='bitcoin_mining_test'&gt;BitCoin Mining Test&lt;/h2&gt;

&lt;p&gt;Using &lt;a href='http://bit.ly/wltGta'&gt;poclbm&lt;/a&gt; with the &lt;a href='http://bit.ly/wJXcve'&gt;DeepBit&lt;/a&gt; minding pool. This low-cost experiment rig achieves around 120 MH/s.&lt;/p&gt;

&lt;p&gt;UPDATE 2012/01/17:&lt;/p&gt;

&lt;p&gt;Using &lt;a href='http://bit.ly/zSvqx2'&gt;cgminer&lt;/a&gt; with &lt;a href='http://bit.ly/A79mQn'&gt;OzCoin&lt;/a&gt; increases that to 168.1 MH/s steady.&lt;/p&gt;

&lt;h2 id='hardware_shots'&gt;Hardware shots&lt;/h2&gt;

&lt;p&gt;The HD 6770 SC: &lt;img alt='Gigabyte HD 6770 Silent Cell' class='picture large' src='cracking-station-upgrade/IMG_0079.jpg' /&gt; Heatsink removed: &lt;img alt='Gigabyte HD 6770 Silent Cell' class='picture large' src='cracking-station-upgrade/IMG_0076.jpg' /&gt; The card that hides underneath: &lt;img alt='Gigabyte HD 6770 Silent Cell' class='picture large' src='cracking-station-upgrade/IMG_0077.jpg' /&gt; Re-installed with two extra fans (airflow from bottom to top): &lt;img alt='Gigabyte HD 6770 Silent Cell' class='picture large' src='cracking-station-upgrade/IMG_0080.jpg' /&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Site relaunched. The power of MM!</title>
    <link rel="alternate" href="/2012/01/15/site-relaunched.html"/>
    <id>/2012/01/15/site-relaunched.html</id>
    <published>2012-01-15T00:00:00+11:00</published>
    <updated>2012-01-15T00:00:00+11:00</updated>
    <author>
      <name>Article Author</name>
    </author>
    <summary type="html">&lt;p&gt;This site was re-built over a weekend. Static site generators are the new black amongst Ruby developers at present, and from my experience with &lt;a href='http://middlemanapp.com/'&gt;Middleman&lt;/a&gt; it&amp;#8217;s easy to see why. In this article I&amp;#8217;ll briefly discuss this site&amp;#8217;s rebuild and the gains made from taking the static approach.&lt;/p&gt;</summary>
    <content type="html">&lt;p&gt;This site was re-built over a weekend. Static site generators are the new black amongst Ruby developers at present, and from my experience with &lt;a href='http://middlemanapp.com/'&gt;Middleman&lt;/a&gt; it&amp;#8217;s easy to see why. In this article I&amp;#8217;ll briefly discuss this site&amp;#8217;s rebuild and the gains made from taking the static approach.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h2 id='the_basics'&gt;The basics&lt;/h2&gt;

&lt;p&gt;A &lt;a href='http://en.wikipedia.org/wiki/Static_web_page'&gt;static site&lt;/a&gt; is &amp;#8220;is a web page that is delivered to the user exactly as stored, in contrast to dynamic web pages which are generated by a web application&amp;#8221;.&lt;/p&gt;

&lt;h2 id='the_benefits'&gt;The benefits&lt;/h2&gt;

&lt;p&gt;The idea has been around a while. In the Ruby community alone there are &lt;a href='https://www.ruby-toolbox.com/categories/static_website_generation'&gt;several good static site generator solutions&lt;/a&gt;. I went for &lt;a href='http://middlemanapp.com/'&gt;Middleman&lt;/a&gt; for a number of reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It was created to work for the general-case&lt;/li&gt;

&lt;li&gt;There are a number of extensions, but most of the useful stuff is built-in&lt;/li&gt;

&lt;li&gt;Support for Asset Pipeline style script management (Sass, CoffeeScript)&lt;/li&gt;

&lt;li&gt;It&amp;#8217;s just damn good design&lt;/li&gt;

&lt;li&gt;Rack support if you really really need it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;What you&amp;#8217;ll gain&lt;/em&gt; with using an SSG are mostly performance boosts. Given the site only needs to be generated once per deploy, as opposed to every pageview, you&amp;#8217;re able to deploy on much lighter-weight platforms and enjoy the reduced cost.&lt;/p&gt;

&lt;h2 id='the_tradeoff'&gt;The tradeoff&lt;/h2&gt;

&lt;p&gt;Of course, the flipside of this scenario is there&amp;#8217;s no longer an app-server sitting there ready to generate responses based on the context of the request. Though it&amp;#8217;s becoming a trend to move more toward client-based apps that link to remote data-sources, rather than essentially running the app for everyone on a central server.&lt;/p&gt;

&lt;p&gt;Most of the client-side technology required to making this de-centralized transition is supported by Middleman. Tools like &lt;a href='http://coffeescript.org/'&gt;CoffeeScript&lt;/a&gt;, &lt;a href='http://compass-style.org/'&gt;Sass&lt;/a&gt; and &lt;a href='http://documentcloud.github.com/backbone/'&gt;Backbone.js&lt;/a&gt; are doing for client-side development what Ruby on Rails did for server-side development. The gap is closing and I wouldn&amp;#8217;t be surprised if 2012 marks the year where we change our architectural preferences en masse toward client-based approaches. There are so many advantages.&lt;/p&gt;

&lt;h2 id='this_site'&gt;This site&lt;/h2&gt;

&lt;p&gt;I really enjoyed re-writing this site in Middleman, familiarizing myself with the different available solutions and finding a git-based deployment strategy that worked for me.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve published the &lt;a href='https://github.com/captainpete/dojo7-site'&gt;source-code for the dojo7 website on Github&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Formatting currency in JavaScript</title>
    <link rel="alternate" href="/2012/01/15/formatting-currency-in-javascript.html"/>
    <id>/2012/01/15/formatting-currency-in-javascript.html</id>
    <published>2012-01-15T00:00:00+11:00</published>
    <updated>2012-01-15T00:00:00+11:00</updated>
    <author>
      <name>Article Author</name>
    </author>
    <summary type="html">&lt;p&gt;I&amp;#8217;ve been hunting for something like Rails&amp;#8217; number_to_currency for Javascript that&amp;#8217;d give me a delimited output with precision in cents.&lt;/p&gt;</summary>
    <content type="html">&lt;p&gt;I&amp;#8217;ve been hunting for something like Rails&amp;#8217; number_to_currency for Javascript that&amp;#8217;d give me a delimited output with precision in cents. &lt;/p&gt;

&lt;p&gt;Most of what I found didn&amp;#8217;t work well so I rolled my own. The code is fairly simple compared to other alternatives and can be easily modified to work with other currencies or dollar amounts.&lt;/p&gt;

&lt;h2 id='usage'&gt;Usage&lt;/h2&gt;
&lt;script src='https://gist.github.com/1613071.js?file=usage.js' type='text/javascript'&gt;
&lt;/script&gt;
&lt;h2 id='coffeescript_implementation'&gt;CoffeeScript Implementation&lt;/h2&gt;
&lt;script src='https://gist.github.com/1613071.js?file=currency-formatter.js' type='text/javascript'&gt;
&lt;/script&gt;
&lt;h2 id='javascript_implementation'&gt;Javascript Implementation&lt;/h2&gt;
&lt;script src='https://gist.github.com/1613071.js?file=currency-formatter.coffee' type='text/javascript'&gt;
&lt;/script&gt;</content>
  </entry>
</feed>

