<?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-7919361321436933137</id><updated>2012-01-24T12:14:28.162-08:00</updated><category term='facebook'/><category term='Dojo'/><category term='i18n'/><category term='javascript'/><category term='cloud computing'/><category term='authentication'/><category term='erlang'/><category term='php'/><category term='web'/><category term='patterns'/><category term='ajax'/><category term='gadgets'/><category term='development'/><category term='programming'/><category term='tutorial'/><category term='front-end'/><category term='IO2008'/><category term='game'/><category term='mashups'/><category term='opensocial'/><category term='open social'/><category term='javascript widgets'/><category term='frameworks'/><category term='gfc gogle friend connect'/><category term='amazon'/><category term='web 2.0'/><category term='programming web'/><category term='gfc'/><category term='oauth'/><category term='ria'/><category term='architecture'/><category term='dojo tutorial ajax'/><category term='fbjs'/><category term='database'/><title type='text'>Script Uncle</title><subtitle type='html'>Mostly JavaScript Ramblings</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default?start-index=101&amp;max-results=100'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>143</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-3060372955892872632</id><published>2012-01-02T08:56:00.000-08:00</published><updated>2012-01-02T09:00:02.347-08:00</updated><title type='text'>Simple Scaffolding for a Dojo Ajax Toolkit application</title><content type='html'>I've been writing some simple exercises for workshop-style (or solo) training for Dojo Ajax Toolkit, focusing on the strength of Dojo - writing OO-JavaScript applications.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-A00bOFl3RxE/TwHhqHULuGI/AAAAAAAAEqg/VI0_kY97XmE/s1600/99b4665b-1b1e-49c8-86f3-b5b5c81789b0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://3.bp.blogspot.com/-A00bOFl3RxE/TwHhqHULuGI/AAAAAAAAEqg/VI0_kY97XmE/s320/99b4665b-1b1e-49c8-86f3-b5b5c81789b0.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The first exercises is about using Dojo's (classical) require and simple namespacing to create simple widgets, but I've gotten repeated requests for a complete application skeleton - something I understand the need for and which would have helped me quite a bit some years ago as well.&lt;br /&gt;&lt;br /&gt;Luckily now there are some. &amp;nbsp;The guys at Sitepen have written some excellent articles (with much better layout :) &lt;a href="http://dojotoolkit.org/documentation/tutorials/1.6/recipes/app_controller/" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://dojotoolkit.org/documentation/tutorials/1.6/templated/" target="_blank"&gt;here&lt;/a&gt;&amp;nbsp;which you should definitely check out as well.&lt;br /&gt;&lt;br /&gt;My aim here, though is to give you a scaffolding which contains all the structure you need to get started. I've included Dojo 1.7.1 &amp;nbsp;in the latest exercise, which might seems staggeringly stupid, but the reason is that this part of the exercises will go into building and testing, where you actually have to have a downloaded copy.&lt;br /&gt;&lt;br /&gt;The exercises (definitely a work in progress) can be found here;&amp;nbsp;&lt;a href="https://github.com/psvensson/Dojo-Ajax-Toolkit-Free-Training"&gt;https://github.com/psvensson/Dojo-Ajax-Toolkit-Free-Training&lt;/a&gt;&amp;nbsp;and here is the Description file of today's app scaffolding sample.&lt;br /&gt;&lt;br /&gt;-----&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This exercise show how to make a simple scaffolding of an application in Dojo.&lt;br /&gt;It is not an exercise per se, but shows both a simple CSS layout and how to split up separate parts of the app into subclasses.&lt;br /&gt;&lt;br /&gt;This time we are referencing a local copy of Dojo 1.7.1, since subsequent exercises will use both the DOH testing system and the build system, both which are used from the Dojo 'util' folder&lt;br /&gt;and relies on parts of Dojo to run.&lt;br /&gt;&lt;br /&gt;I'm still using the old (pre-AMD) style of declaring classes, so Dojo will warn about some things.&lt;br /&gt;&lt;br /&gt;The goal is to show in a series of exercises how to create a simple single-page app with Dojo which is:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;1. Object-oriented - splitting functionality across a small class-hierarchy and through a logical namespace&lt;br /&gt;&amp;nbsp;2. Using a sensible box model CSS layout&lt;br /&gt;&amp;nbsp;3. Turn-key, so you can just copy the structure and get going modifying stuff as you please.&lt;br /&gt;&lt;br /&gt;The page sample.html require's just one class, which is the widget mycustom.MainApp&lt;br /&gt;&lt;br /&gt;In the MainApp class, a template is declared which defines the uppermost layout of the application;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;div class="mycustom_box"&gt;&lt;br /&gt;&amp;lt;div class="mycustom_box"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;div class="mycustom_top"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;div class="mycustom_left" &amp;nbsp;dojoType="mycustom.navigator.ui.MenuBar"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;div class="mycustom_right" dojoType="mycustom.common.ui.LoginWidget"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;div class="mycustom_center"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;div dojoType="mycustom.navigator.ui.ViewPort"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;div class="mycustom_bottom"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;Bottom area&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;The application has three visual parts; A top part which contain a menu widget and a login/out widget, a central part which contains a viewport which can switch between different views, and a bottom part which contain information and links.&lt;br /&gt;&lt;br /&gt;Since these different parts are defined in their separate classes, with their separate template files, you get an automatic modularization that makes it less likely that different programmers&lt;br /&gt;step on each others toes when working together (or just one making a 10K lines long file...)&lt;br /&gt;&lt;br /&gt;This is a very, very simple scaffolding example which does nothing at all, but is a minimalistic proof of concept of how to start your own non-trivial Dojo application.&lt;br /&gt;&lt;br /&gt;The namespace is divided into the main parts 'common' - for classes that can be reused and are hopefully generic, and 'navigator' - for classes that are specifically implementing the logic of this application.&lt;br /&gt;&lt;br /&gt;I have called it 'navigator' because Internets. I have meant it to be a small app that let you navigate some space of stuff.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-3060372955892872632?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/3060372955892872632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=3060372955892872632' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3060372955892872632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3060372955892872632'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2012/01/simple-scaffolding-for-dojo-ajax.html' title='Simple Scaffolding for a Dojo Ajax Toolkit application'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-A00bOFl3RxE/TwHhqHULuGI/AAAAAAAAEqg/VI0_kY97XmE/s72-c/99b4665b-1b1e-49c8-86f3-b5b5c81789b0.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-7750022489186298642</id><published>2011-09-24T06:47:00.000-07:00</published><updated>2011-09-24T06:57:59.565-07:00</updated><title type='text'>How to build Large Web Applications, part I</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-vNHlO5XuwTQ/Tn3NASKAW0I/AAAAAAAADFw/TTvrgA001JI/s1600/playing-tennis-on-wings-of-plane-vintage-daredevils-black-and-white.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="234" src="http://1.bp.blogspot.com/-vNHlO5XuwTQ/Tn3NASKAW0I/AAAAAAAADFw/TTvrgA001JI/s320/playing-tennis-on-wings-of-plane-vintage-daredevils-black-and-white.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;I've&lt;/b&gt; been busy the last two years building fairly intricate web apps for my customers and while it's a fun job it's also by necessity not public in the same way an open-source project is. The only comments I get and discussion I'm involved in are generally from my customers, so it's a bit of a closed loop.&lt;br /&gt;&lt;br /&gt;When I met Paul Irish in May this year in San&amp;nbsp;Francisco&amp;nbsp;he asked me,' But what do you actually do?', which was a fair question but took me by surprise. I'm mostly known for .. being that Swedish guy. With some luck people know I prefer Dojo as well, but I guess that's about it.&lt;br /&gt;&lt;br /&gt;So what do I do? I build web apps as an&amp;nbsp;independent&amp;nbsp;consultant. Sure, I arrange conferences and user group meetings too, but that's where my beer comes from, so to speak.&lt;br /&gt;&lt;br /&gt;This series of posts is both written to share and discuss what I feel are best practices around building large web apps, from a developer&amp;nbsp;perspective, but also to let people know what I do. Possibly with the secretly evil intent of getting new customers if anything I write seems to be useful :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-3aZYSgtQgW8/Tn3Liw_ZecI/AAAAAAAADFs/TVB2egf9U3U/s1600/3lsRs.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="104" src="http://3.bp.blogspot.com/-3aZYSgtQgW8/Tn3Liw_ZecI/AAAAAAAADFs/TVB2egf9U3U/s320/3lsRs.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Let's&lt;/b&gt; begin with defining what a large web app is.&lt;br /&gt;&lt;br /&gt;A large web app (according to me, but please challenge and/or add to the list of items);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Have composite views (showing both a static status area and a changing subview of items and lists, for example)&lt;/li&gt;&lt;li&gt;Have widgets that are variants of each other.&lt;/li&gt;&lt;li&gt;Have widgets that need to show up in dynamic configurations (e.g. a list of n, or each a always have a b except on&amp;nbsp;Saturdays, ..)&lt;/li&gt;&lt;li&gt;Initializes&amp;nbsp;communication&amp;nbsp;with the server or service and caches some or all information.&lt;/li&gt;&lt;li&gt;Have widgets that need to change states, remember states and react to state changes in other widgets.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;This list could go on and on, probably, but these are the most important things off the top of my head.&lt;br /&gt;One of my customers had an existing, successful product that was built in .Net C#. It was a client-server system where the client had the following features;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Personal view of things going on, of various sorts.&lt;/li&gt;&lt;li&gt;List of personal things, arranged per time period in a tree structure, which showed a grid with the selected things.&lt;/li&gt;&lt;li&gt;Library of things of other people, arranged in a tree by both time period, user names and project names.&lt;/li&gt;&lt;li&gt;*very* complex search view where list of search queries could be build up dynamically and combined like date, project names but also other domain-specific (and visual) properties.&lt;/li&gt;&lt;li&gt;A thing editor which let the user compose a thing that was composed of various parts which could be dragged from a tab to the left and then changed according to their type and rearranged. There were parts like annotatable image, rich text, project reference, and so on.&lt;/li&gt;&lt;li&gt;Some of the parts needed access to the system clipboard for reading and writing, and some parts needed to start with and communicate with Excel. Several parts needed file access.&lt;/li&gt;&lt;li&gt;Lots of other, minor stuff.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;And now, two years later, the Dojo/HTML5 version of the client have about 80% of the functionality of the old client (and some that it didn't) being sold to clients and everything. It's been quite a ride!&lt;br /&gt;&lt;br /&gt;I realize that I both want to cover the story of the programs creation and 'how to make large web apps' at the same time. It probably is a bad idea, but let's anyway.&lt;br /&gt;&lt;br /&gt;First of all, before digging into specific implementation I would like to talk about bare necessities. Stuff you just can't do without, stuff that if you are indeed left without it you will have to reinvent, poorly, and too late and botch things up completely. Yes, I have, and probably you too. But I didn't on this project(s) :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-6pqyXo1Oz_A/Tn3PLs-wFQI/AAAAAAAADF0/OC35XCUeZdo/s1600/image012_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="241" src="http://3.bp.blogspot.com/-6pqyXo1Oz_A/Tn3PLs-wFQI/AAAAAAAADF0/OC35XCUeZdo/s320/image012_1.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Anyhoo,&lt;/b&gt; If we take the first list of things that define a large web app, the items leads to certain demands on your tooling and libraries of choice. First of all you need to have a clean widget abstraction to work with, one that clearly modularize your code and your markup. It also help tremendously if you have a widget lifecycle metaphor, which is handled for you and that you can plug in to when and if you need to.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Widget Abstraction&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The widget abstraction should, at minimum do the following (lots of lists, sorry);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Separate code and markup, so you have a separate file or string for the markup of the widget&lt;/li&gt;&lt;li&gt;Make it possible to create widgets in classes that derive from each other, so you can have one grid baseclass, then a librarygrid that inherits from the basegrid, et.c.&lt;/li&gt;&lt;li&gt;Completely hide id allocation to elements and sub-widgets. By this I mean that the abstraction need to let you use symbolic names inside the markup (&lt;div secretsauceproperty="foo"&gt;&lt;/div&gt;) that are then used inside the widget class in lieu of id lookups.&lt;/li&gt;&lt;li&gt;Use markup replacement, so that parts of the markup is replaced with data in the widget class (&lt;div&gt;${foo}&lt;/div&gt;will be replaced with this.foo in the widget before the widget is placed in the DOM)&lt;/li&gt;&lt;li&gt;Have a lifecycle so that when you create a widget, the widget "subsystem" / superclasses will call a number of functions on it that corresponds to the different event like a) init, b) before markup creation, c) after markup creation, d) before widget inserted into the DOM, et.c.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Dojo does all of this (as does several if it's peers (JavascriptMVC, Sproutcore, ExtJS, et.c.), but since the 'everything in a &amp;nbsp;box' approach is a conceptual hard-sell, people generally want to use smaller and separate libraries that does just one thing, but well.&lt;br /&gt;&lt;br /&gt;A good, but a little bit dated list of a couple of markup libraries can be found &lt;a href="http://www.viget.com/extend/benchmarking-javascript-templating-libraries/"&gt;here.&lt;/a&gt;&amp;nbsp;But markup libraries (like Mustache.js) only solves one of the problems.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Dojo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm going to cover a bit how Dojo works here, but please let me know in the comments if you know about stand-alone libraries for these functions. i would think that some are probably part of a larger library's class-system, but still.&lt;br /&gt;&lt;br /&gt;When I create a widget using Dojo, I create two files. One is the JavaScript class (obv) whic inherits from another custom widget or directly from dijit._Widget (widget subsystem) and dijit._Templated (markup replacement and symbolic element/subwidget naming). It could look like this;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;In the directory "my/custom" the file "widget.js";&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;dojo.provide("my.custom.widget");&lt;br /&gt;dojo.require("dijit._Widget");&lt;br /&gt;dojo.require("dijit._Templated");&lt;br /&gt;dojo.declare(""my.custom.widget", [dijit._Widget,&amp;nbsp;dijit._Templated],&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; templatePa&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;th: dojo.cache("my.custom", "widget.html"),&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="Apple-style-span" style="color: blue;"&gt;username&lt;/span&gt;: "nisse",&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; postCreate: function()&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; dojo.connect(this.&lt;span class="Apple-style-span" style="color: #38761d;"&gt;mybutton&lt;/span&gt;, this, function(e)&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;{&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;console.log("Someone pressed me button, eh?");&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;The file "widget.html";&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt; div&amp;gt;&lt;br /&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt; button dojoAttachPoint="mybutton" &amp;gt;${username}&amp;lt; button &amp;gt;&lt;br /&gt;&lt;div&gt;&amp;lt;div / &amp;gt;&lt;br /&gt;&lt;br /&gt;The 'postCreate' function on a widget is called (if present) just before the widget is placed in the DOM, but after all markup replacement have been done. We now have markup that contains a div with a button in it, and the content of the button reads 'nisse', since that was what the class variable 'username' contained.&lt;br /&gt;&lt;br /&gt;To use the widget you just have the following things in you code;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;dojo.require("my.custom.widget");&lt;br /&gt;...&lt;br /&gt;var foo = new my.custom.widget();&lt;br /&gt;// Not mentioning argument passing or automatic placement in page stuff. it's just a widget in the wind right now&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;There a re lots of other things you can do, like automatic event wiring, but I hope this small example is just enough to make you think 'Hmm.. that could actually be kind of useful'.&lt;br /&gt;&lt;br /&gt;I am not really touching on the namespacing either, which is a simple things that have had ridiculous positive effects on the development speed and stability. We'll get to that later.&lt;br /&gt;&lt;br /&gt;What the widget will look like in the actual page is something like this;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div&gt;&amp;lt; div&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;button id="mycustomwidget_0_mybutton"&amp;gt;nisse&amp;lt;/ button &amp;gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div&gt;&amp;lt;div/ &amp;gt;&amp;nbsp;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div&gt;What's actually in the id is not important, the important thing is that the id is never visible to you (unless you really want to, but you don't. Why would you? The only thing you need is to get a reference to the node in question (in this case, to attach an event handler to it).&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Also, what may be less apparent, is that when you customer want another widget just like it beside the first, you don't have to worry about widget id lookup code, you know that you abstraction will handle those details and just create a new one and smack it up - no problem.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;There are tons of more things I'd like to fit in here, but I have to clean the house while parts of the family is playing Deus Ex (the original) and others are off galivanting with horses. &amp;nbsp;Oh well..&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Oh, right. I'll be doing a series of free, half-day Dojo-training events at Valtech in Sweden beginning the 13/10 2011. I'll post here (and on twitter etc) if you live nearby and want to learn the basics of creating custom Dojo widgets.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;See you soon!&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&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/7919361321436933137-7750022489186298642?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/7750022489186298642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=7750022489186298642' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7750022489186298642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7750022489186298642'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2011/09/how-to-build-large-web-applications.html' title='How to build Large Web Applications, part I'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-vNHlO5XuwTQ/Tn3NASKAW0I/AAAAAAAADFw/TTvrgA001JI/s72-c/playing-tennis-on-wings-of-plane-vintage-daredevils-black-and-white.jpg' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-5822972097777577173</id><published>2011-04-09T08:05:00.000-07:00</published><updated>2011-04-10T01:57:19.070-07:00</updated><title type='text'>Bad, hairy, dangerous and irresponsible node+now+couch example</title><content type='html'>What I feel is lacking many times when I want to learn a new piece of technology is smallest possible complete examples. I find many time how to interact with a new fancy database, or maybe how to communicate between client and server in a simpler, cooler way.&lt;br /&gt;&lt;br /&gt;Very seldom do I find examples that do everything I need. What I want, ideally, when toying with a new piece of tech is the following;&lt;br /&gt;&lt;br /&gt;1. Full instructions on how to set up any requirements, or at least pointers to good sources.&lt;br /&gt;2. Example of client code, or at least how to get a basic web page up through or in parallel to this new something.&lt;br /&gt;3. Example of how to call the service from whatever client should be used.&lt;br /&gt;4. Example of how to take care of the client requests send on the server-side&lt;br /&gt;5. Example on how to persist information and get it back again, even if that is not really part of the new tech.&lt;br /&gt;&lt;br /&gt;What I like to convey, I think, &amp;nbsp;is that there is need for examples that give a newbie a fully working service for all examples, since even a very simple assumption can be to hard to grok if you are new to a certain scene.&lt;br /&gt;&lt;br /&gt;In general I'd think it is better to have working, fully stand-alone examples that one does not understand one bit, than to have an example that is a partial service that is easy to understand. The newbie is a coder after all, and as long he or she have a working example that can be thrown rocks at, eventually he or she will figure the stuff out.&lt;br /&gt;&lt;br /&gt;As it happens I've just manages to create (what I hope is) such a thing. What I wanted was to use the new &lt;a href="http://nowjs.com/"&gt;now.js&lt;/a&gt;&amp;nbsp; socket.io client-&amp;gt;server and server-&amp;gt;client communications proxy. &amp;nbsp;It's really sweet since it makes JSON-RPC calls really simple. it's like this;&lt;br /&gt;&lt;br /&gt;1. Your web page loads the now.js script from your now-powered node.js serverside JavaScript server.&lt;br /&gt;2. The server-script on the node side adds any property to the global 'everyone.now. object.&lt;br /&gt;3. JavaScript in your page gets any property changes propagated to a proxy object called just 'now' on the client.&lt;br /&gt;4. If the properties are functions, the client can call them, and the function call will be executed on th server. No setup code, no nothing. Just call the bloody function, thanks.&lt;br /&gt;5. If the client (your webpage JS code) adds a function of its own the server can call that.&lt;br /&gt;6. This is what you really, really want.&lt;br /&gt;&lt;br /&gt;If the browser doesn't support socket.io, a flash wrapper will be used, but all else remain equal.&lt;br /&gt;&lt;br /&gt;But then again, you really would want to have some database running wouldn't you? On the server-side, I mean. Couchdb, for example.&lt;br /&gt;&lt;br /&gt;What I just did was create a very small, not very clean example that uses now.js, couchdb and cradle on node and a small index.html file which load the now.js script and shows how to call functions exposed back and forth.&lt;br /&gt;&lt;br /&gt;The code looks like this;&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; var url = require("url");  &lt;br /&gt; var sys = require("sys");  &lt;br /&gt; var path = require("path");  &lt;br /&gt; var fs = require("fs");  &lt;br /&gt; var inspect = require('eyes').inspector({styles: {all: 'magenta'}});  &lt;br /&gt; var cradle = require("cradle");  &lt;br /&gt; cradle.setup({host: "127.0.0.1", port: 5984});  &lt;br /&gt; var conn = new(cradle.Connection)();  &lt;br /&gt; var db = conn.database("abc");  &lt;br /&gt; db.create();  &lt;br /&gt; var yourHttpServer = require('http').createServer(function(req, response)  &lt;br /&gt; {  &lt;br /&gt;  /* Serve your static files */  &lt;br /&gt;  var uri = url.parse(req.url).pathname;  &lt;br /&gt;   var filename = path.join(process.cwd(), uri);  &lt;br /&gt;   path.exists(filename, function(exists) {  &lt;br /&gt;     if(!exists) {  &lt;br /&gt;       response.writeHead(404, {"Content-Type": "text/plain"});  &lt;br /&gt;       response.write("404 Not Found\n");  &lt;br /&gt;       response.end();  &lt;br /&gt;       return;  &lt;br /&gt;     }  &lt;br /&gt;     fs.readFile(filename, "binary", function(err, file) {  &lt;br /&gt;       if(err) {  &lt;br /&gt;         response.writeHead(500, {"Content-Type": "text/plain"});  &lt;br /&gt;         response.write(err + "\n");  &lt;br /&gt;         response.end();  &lt;br /&gt;         return;  &lt;br /&gt;       }  &lt;br /&gt;       response.statusCode =200;  &lt;br /&gt;       response.write(file, "binary");  &lt;br /&gt;       response.end();  &lt;br /&gt;     });  &lt;br /&gt;     });  &lt;br /&gt; });  &lt;br /&gt; yourHttpServer.listen(8080);  &lt;br /&gt; var everyone = require("now").initialize(yourHttpServer);  &lt;br /&gt; everyone.now.msg = "Welcome to TEH wicked nowjs JSON-RPC";  &lt;br /&gt; everyone.now.foo = function(arg,cb)  &lt;br /&gt; {  &lt;br /&gt;     sys.puts("Foo called.. arg and everyone.now is...\n");  &lt;br /&gt;     inspect(arg);  &lt;br /&gt;     inspect(everyone.now);  &lt;br /&gt;     db.get('clientlog', function(err, doc)  &lt;br /&gt;     {  &lt;br /&gt;         inspect(doc);  &lt;br /&gt;         if(!doc)  &lt;br /&gt;         {  &lt;br /&gt;             db.save('clientlog', {log: []});  &lt;br /&gt;         }  &lt;br /&gt;         else  &lt;br /&gt;         {  &lt;br /&gt;             var arr = doc.log || [];  &lt;br /&gt;             inspect(arr);  &lt;br /&gt;             arr.push({date: new Date(), message: arg});  &lt;br /&gt;             doc.log = arr;  &lt;br /&gt;             db.save('clientlog', doc,  &lt;br /&gt;             function(err, res)  &lt;br /&gt;             {  &lt;br /&gt;             // Handle success  &lt;br /&gt;                 sys.puts("Error after save was : "+err);  &lt;br /&gt;             })  &lt;br /&gt;         }  &lt;br /&gt;     });  &lt;br /&gt;     cb( "server callback yo!");  &lt;br /&gt; }  &lt;br /&gt; everyone.now.bar = function(arg)  &lt;br /&gt; {  &lt;br /&gt;     sys.puts("now.js function 'bar' called from client. args are..");  &lt;br /&gt;     inspect(arg);  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What you need to do to get this&amp;nbsp;working&amp;nbsp;is;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: 'Droid Sans', arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="color: #202020;"&gt;0. Don't have a lossy operating system.&lt;br /&gt;1. Install &lt;a href="http://couchdb.apache.org/index.html"&gt;couchdb&lt;/a&gt; and create a database named 'abc'&lt;/div&gt;&lt;div style="color: #202020;"&gt;2. git clone &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; + &lt;a href="https://github.com/isaacs/npm"&gt;npm&lt;/a&gt;;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: monaco, consolas, monospace; font-size: 12px; line-height: 16px; white-space: pre-wrap;"&gt;&lt;span style="color: black;"&gt;git clone https&lt;/span&gt;&lt;span style="color: #666600;"&gt;:&lt;/span&gt;&lt;span style="color: #880000;"&gt;//&lt;a href="http://github.com/ry/node.git" style="color: #67753a;" target="_blank"&gt;github.com/ry/node.git&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: monaco, consolas, monospace;"&gt;&lt;span style="font-size: 12px; line-height: 16px; white-space: pre-wrap;"&gt;git clone&lt;span class="Apple-style-span" style="color: #202020;"&gt; &lt;/span&gt;&lt;a href="https://github.com/isaacs/npm.git" style="color: #67753a;" target="_blank"&gt;https://github.com/isaacs/npm.&lt;wbr&gt;&lt;/wbr&gt;git&lt;/a&gt;&lt;span class="Apple-style-span" style="color: #202020;"&gt;&lt;br clear="all" /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;./configure and make install first node, then npm&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;3. npm install cradle (couchdb helper library)&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;4. npm install now (that thing I just talked about, sheesh)&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;5. npm install eyes (logging/inspect library)&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;6. Unzip the &lt;a href="http://genericwitticism.com/nodestuff.zip"&gt;nowtest example zipfile &lt;/a&gt;somwhere and do 'node nowtest.js'&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;span style="font-family: tahoma, sans-serif;"&gt;7. Go to&amp;nbsp;&lt;a href="http://localhost:8080/index.html" style="color: #67753a;" target="_blank"&gt;http://localhost:8080/index.&lt;wbr&gt;&lt;/wbr&gt;html&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #202020;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Ta-daa! :)&lt;br /&gt;&lt;br /&gt;Or possibly not, since I just slammed this together. It's bound to have ugly, warty, beer-guzzling bugs. Please tell me about them so I can update the code and links. Thx!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-5822972097777577173?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/5822972097777577173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=5822972097777577173' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5822972097777577173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5822972097777577173'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2011/04/bad-hairy-dangerous-and-irresponsible.html' title='Bad, hairy, dangerous and irresponsible node+now+couch example'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-683239882488697041</id><published>2010-11-02T08:23:00.000-07:00</published><updated>2010-11-02T08:23:11.878-07:00</updated><title type='text'>Ethics and Employment - part 1</title><content type='html'>I've been thinking about employment for quite some time. It's a large topic and way too easily sway into the marshlands of politics. The first time I thought hard on employment was a year and a half ago.&lt;br /&gt;&lt;br /&gt;I realized that the company I worked for at the time didn't have the right connections to land the really cool JavaScript jobs which I was yearning for. I wanted to create true JavaScript apps and time and again I was shucked half on the side into a 'Web Project' where you had to massage the dark mystery horror server-side templates as per usual.&lt;br /&gt;&lt;br /&gt;This was not very fun. I liked the people I was working with but not what I was doing.&lt;br /&gt;&lt;br /&gt;The reason was the fact that I was sitting as a lame duck, wholly dependent on 'consultant routing' companies or my employer to give me something to do. Since they were basically blind to what a JavaScript client-side application was and I had few connections outside the people I happened to know, I was stuck in a loop.&lt;br /&gt;&lt;br /&gt;After arranging my first conference (SWDC 2009), and subsequently starting the Google Technology user Group of Stockholm I met with a lot of new people, one of who became my first customer, since they &lt;i&gt;did&lt;/i&gt; want to make a JavaScript application. Quite a large one as well - a port of an existing .Net client-server app, but where the client should be remade in JavaScript and 'HTML5' with IE8 as a lowest boundary browser.&lt;br /&gt;&lt;br /&gt;I started my own company, took on the new customer and their project and I'm still working with them one year and four work packages later (albeit only two days a week, which was the idea at this point in the project). I had other customers as well, arranged another conference (Android Only) and generally made good money having a fair bit of fun :)&lt;br /&gt;&lt;br /&gt;The reason I do is because two things happened (painfully evident, but still);&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;1) I finally managed to generate luck by meeting enough interesting people&lt;/blockquote&gt;&lt;blockquote&gt;2) I dared to bite.&lt;/blockquote&gt;&lt;br /&gt;And only recently have I realized what a sorry wretch I was before, not having any control over my working life and I felt that most possibly other people feel the same way. Generally, I've found out it's like this;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;1) You don't need to be employed at a company to get to work at great project and make good money, you only need to know enough people.&lt;/blockquote&gt;&lt;br /&gt;And if you don't know enough people, that's fixable. I feel that everyone should have their own company and interact with other companies as equals. To be an employee at a company is really not neccessary. Other than you own, that is.&lt;br /&gt;&lt;br /&gt;Another objection I have to being employed is that you get always get this half-decent salary that is capped, with your employer making as much money as possible on top of the cap, so to speak. I feel that employees should get a bigger share out of the profit they make.&lt;br /&gt;&lt;br /&gt;I've been part of profit-sharing schemes on different companies I've worked for, but none have really made any lasting impressions. I feel that as a subject area expert (and consultant) you should get at least 50% of the profit you generate. If you're become better, this will (or should) reflect on a higher hourly rate and an automatically higher salary.&lt;br /&gt;&lt;br /&gt;Having your own company gives you 100% of the profits of course, but not always as salary.&lt;br /&gt;OK, so what are the downsides? Lots, of course, but nothing that actually counts if you compare it to slowly becoming an old irritable grouch who is forced to do things he hate most of his working time. For example;&lt;br /&gt;&lt;br /&gt;1) Most of the time you only know about the next three months of revenue&lt;br /&gt;2) You are completely dependent on your customers&lt;br /&gt;3) You are completely epenedent on your customers paying you sort of on time&lt;br /&gt;4) You have no money when you don't work (i.e. 'vacation')&lt;br /&gt;&lt;br /&gt;So, in a nutshell, working on your own, you don't have any security whatsoever.&lt;br /&gt;&lt;br /&gt;Let me tell you a secret: Neither have you when you're employed, rounded down. &lt;br /&gt;&lt;br /&gt;The company can become bankrupt or on hard times, having to downsize as easy as your personal company would. The only difference between being an employee and owning your own company is that you actually have some control over the ship in the latter case.&lt;br /&gt;&lt;br /&gt;Even though this I do believe that you shouldn't be employed I have had two moral dilemmas; First of all Google. I have been a bit of a Google fanboy and despite having had my own company, I've applied for some positions there. This is clearly scizophrenic so I really hope I've stopped with that sort of stuff now :)&lt;br /&gt;&lt;br /&gt;The second moral dilemma has to do with employing people myself. Since I have quite a large network nowadays I get a lot of interesting offers that I rarely can do something about, being tied up in prior agreements.&lt;br /&gt;&lt;br /&gt;So, the natural solution would be to hand over those projects to other one-man shows for a small commission. Now for the suprising part; I can't seem to find these other one-man shows. OK, yes, I know of one, two at the most. I've been talking to great employed people I know, urging them to start their own company and start receiving project from me, but inevitably they shirk away from that and continue doing sort-of boring stuf&amp;nbsp;(IMO) in exchange for apparent safety.&lt;br /&gt;&lt;br /&gt;This has led me to the very strange conclusion that if I want to give people projects, I have to employ them. OK, I *could* give the projects to the companies they work for now, but in most cases those companies are large, very &lt;cough&gt; executive and so on and so forth. I have a feeling I would not look good in the end, the projects having come to me sort of on a personal level. I would want to have some sort of responsibility.&lt;/cough&gt;&lt;br /&gt;&lt;br /&gt;So how do you employ people when you're against employment? :)&lt;br /&gt;&lt;br /&gt;Stay tuned for next chapter.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-683239882488697041?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/683239882488697041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=683239882488697041' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/683239882488697041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/683239882488697041'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2010/11/ethics-and-employment-part-1.html' title='Ethics and Employment - part 1'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1296233532163668033</id><published>2010-09-11T07:15:00.000-07:00</published><updated>2010-09-11T07:15:27.756-07:00</updated><title type='text'>The problem-solving process in dynamic vs. static languages</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_EVNJz2KzLVU/TFZEiwCkvTI/AAAAAAAARBo/QETs9Jk3XNk/s1600/MADb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_EVNJz2KzLVU/TFZEiwCkvTI/AAAAAAAARBo/QETs9Jk3XNk/s320/MADb.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This post is about why not to used static languages. It will outline the creative process used when starting to attack a problem and implementing its solution in code, and why that very process is hindered greatly by static languages.&lt;br /&gt;&lt;br /&gt;You know what I mean, when I say static languages (Java, Scala, C++, et.c.).&lt;br /&gt;&lt;br /&gt;I know that I've read about similar ponderings to these on the web earlier but a) I can't find them right now and b) It struck me anew on a personal level when I tried to understand why I work so much quicker when developing code in a dynamic language (especially JavaScript).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;The dynamic development process&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I start to formulate a solution to a problem in JavaScript, I focus on the algorithm, on the classes that operate on the data and their methods - on the flow of function calls between different parts of the system I build.&lt;br /&gt;&lt;br /&gt;Most often I forget some details about the data being passed or of what kind of state I need to include in the arguments in calls between different classes. This is no big deal as I just create new objects on the fly as arguments or return values, sometimes currying them up as part of a filtering process.&lt;br /&gt;&lt;br /&gt;This lets me stay 'in the zone' and focus on the problem I'm trying to solve. The data structures are pliable and can be changed in the same place as the code. I never need to bothered with what kind of data I'm juggling. I might do something like this;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;foo.barMethod({size: x, noses: 17, frotz: {a:'b', c:'d'}}, this.somethingImportantAtTheMoment);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The first barMethod argument is an object. Just an object, could be anything. When I need to put more stuff in there, I do so. The object is so lightweight that it doesn't warrant its own class, it is really just a simple wrapper around some data I'm passing, pliable as my code for using it are right now in my problem-solving process.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;The static development process&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This might differ significantly in Scala which I must confess I haven't studied enough. Please let me know in the comments if so. But when working with Java, I very quickly run into the creation of (often hierarchical) the definition of data classes and interfaces.&lt;br /&gt;&lt;br /&gt;Their properties are often complex, themselves objects, a couple of layers deep. Even though each data class is trivial, creating them takes me out of my creative zone, forcing me to make decisions around data that I'm not ready for yet. So naturally I put in the bare minimum of information.&lt;br /&gt;&lt;br /&gt;Then when using and passing around these objects, I often find myself constricted by the fairly arbitrary member/property types I've chosen, whose management tend to bleed out into the code, in the form of casts, et.c (This should be an area where Scala does help, though).&lt;br /&gt;&lt;br /&gt;When I change my strategies for my problem-solving logic, it impacts heavily on the contents and types of the data classes, even if the data and logic classes are the same. I need continually to pop out of problem-solving mode into yak-shaving mode to arrange the data to fit my new logic.&lt;br /&gt;&lt;br /&gt;I have now realized why static people so often tout the importance of having refactoring zombie-dust-powers in their extensive IDEs. From my vantage point it seems like fixing a language deficiency.&lt;br /&gt;&lt;br /&gt;But wait! &amp;nbsp;What about all that evil terror that happens if you just create anonymous objects and functions mid-stride without any type enforcement? &amp;nbsp;Well, for one thing - testing is key, and another thing - it has actually happened once or twice that I've had to hunt about in somebody else's code for what on earth they have put in an argument object.&lt;br /&gt;&lt;br /&gt;Compared to the extreme pain of always having a static retriever biting my private parts, the problem of finding the dynamic bottle of beer in the living rooms has in my experience been an extremely fair trade-off.&lt;br /&gt;&lt;br /&gt;YMMV, of course.&lt;br /&gt;&lt;br /&gt;Comments?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1296233532163668033?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1296233532163668033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1296233532163668033' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1296233532163668033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1296233532163668033'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2010/09/problem-solving-process-in-dynamic-vs.html' title='The problem-solving process in dynamic vs. static languages'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_EVNJz2KzLVU/TFZEiwCkvTI/AAAAAAAARBo/QETs9Jk3XNk/s72-c/MADb.jpg' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4514286378881112066</id><published>2010-05-01T09:22:00.000-07:00</published><updated>2010-05-01T09:22:44.339-07:00</updated><title type='text'>A solid dyson sphere of Awesome; The JSConf experience</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://posterous.com/getfile/files.posterous.com/mahemoff/j6vhAIqlsAzrIiJ3OWY5VVVcfYHWbOLBeLy7nF1BqadkCICNSXSTP1KiGGrV/photo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://posterous.com/getfile/files.posterous.com/mahemoff/j6vhAIqlsAzrIiJ3OWY5VVVcfYHWbOLBeLy7nF1BqadkCICNSXSTP1KiGGrV/photo.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;A couple of weeks ago I attended the second US JSConf in Washington. It turned out to be a very good move indeed.&lt;br /&gt;&lt;br /&gt;I can easily say that this was one of the best conferences I've been to, maybe the best one. The reasons are, I suggest, threefold;&lt;br /&gt;&lt;br /&gt;1) I have a personal, burning and possibly unhealthy interest in JavaScript.&lt;br /&gt;2) The speakers were generally critical-mass awesome.&lt;br /&gt;3) Track C - "The first rule of Track C is that you don't talk about Track C" - as Peter Higgins, president of the Dojo Ajax Toolkit has been known to tweet.&lt;br /&gt;&lt;br /&gt;Track C meant hanging around the corridors of Hotel Palomar, pilfering beer from pirate chests and having interstellar discussions about programming. And joking. And talking about SF books. Epic.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xBSA8ejAI/AAAAAAAAAoE/jG0N5GcUrME/s1600/2010-04-17+13.20.29.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xBSA8ejAI/AAAAAAAAAoE/jG0N5GcUrME/s320/2010-04-17+13.20.29.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;The&amp;nbsp;playfulness and allowing atmosphere was really great and everywhere you turned you met guys and gals that also arrange their own conferences, write their own frameworks, turns the web inside out (or upside down), and so on.&lt;br /&gt;&lt;br /&gt;But last things first; After two days of extremely technical talks, games and panels, comes the final payoff - the keynote. What might the keynote bring, after node.js future directions, Sproutcore WYSIWYG editors, custom DSLs and JavaScript interpreters for Flash?&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/S9xENByl5TI/AAAAAAAAAoM/CD6xfUpAMgw/s1600/2010-04-17+08.22.58.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/S9xENByl5TI/AAAAAAAAAoM/CD6xfUpAMgw/s320/2010-04-17+08.22.58.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;In a word: 'Bacon'. Aaron Quint gave a Bacon keynote. No, it's not a framework or scrum-derivate-du-jour, actual cured pigs belly, that's what.&lt;br /&gt;&lt;br /&gt;Aaron is a foodie. He's a great Ruby and JS guy as well, but he is a very passionate foodie, and the level of passion and knowledge in his talk about making your own bacon, history of and how to barter it for microbrew was both entertaining and cheeky.&lt;br /&gt;&lt;br /&gt;Actually, the cheek belongs to Chris Williams, Pirate Captain of JSConf who, as always, risks all by choosing a *non-programming* keynote for a programming conference. That in it self was almost as fun as seeing it. &amp;nbsp;Naturally Passion is key, and Aaron did weave in some pseudo-code to refer to the different experience of making food and making code. But the core of the talk was, IMO, about what makes us tick, as foodies, as developers and as human beings.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xFZuHsqyI/AAAAAAAAAoU/LKaB2-mWyZY/s1600/2010-04-17+08.48.58.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xFZuHsqyI/AAAAAAAAAoU/LKaB2-mWyZY/s320/2010-04-17+08.48.58.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Also, Chris actually planned JSConf together with his wife (who had a T-shirt with the text 'Pirate Pending' on), which was really nice and the very antithesis of Corporate.&lt;br /&gt;&lt;br /&gt;Another cool thing about the conference was that over 100 people who sent in their abstracts didn't get chosen. Actually, that is just the way it is and neither here, nor there, but since many people *really* wanted to get a place speaking at JSConf and vented some steam on twitter, Kyle Simpson (@getify) proposed having a pre-conference conference, the so-called Scurvyconf, which was open for anyone who couldn't speak at the actual JSConf.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/S9xOx4W2J6I/AAAAAAAAAoc/XIvcClYZE0A/s1600/2010-04-17+11.45.35.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/S9xOx4W2J6I/AAAAAAAAAoc/XIvcClYZE0A/s320/2010-04-17+11.45.35.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;The sound at the pub where ScurvyConf was held was deafening, with drunk geeks shouting over each other and having a generally good time. So the speakers had a hard time getting heard. This was taken in stride however and even though the audience participation was varied, it was very empathic where it occurred.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/S9xSHqJGP4I/AAAAAAAAAok/4oxdRbjN7c0/s1600/2010-04-18+14.18.22.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/S9xSHqJGP4I/AAAAAAAAAok/4oxdRbjN7c0/s320/2010-04-18+14.18.22.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;At the end of the first day we were treated to a cruise on the Photomac sponsored by Yahoo! with wonderful food and long discussions with people from Disney, Microsoft (Really!) and SinnerSchraeder (Hi Holger!) ranging from how XSS really works to defensive synthetic biology and the open wetware foundation. A total blast.&lt;br /&gt;&lt;br /&gt;I finally got to meet in person Justin Meyer, the creator of JavaScriptMVC who gave a great talk on its many strong points. My favorite is still the railsish generative scripts which creates client-side files for certain tasks (like consuming and displaying services). &amp;nbsp;Justin was also the man who opened the bar in the wee hours of the morning on our way home from the final Google dinner night. Kudos for that (and spontaneous dancing to boot).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xTJ-jP6RI/AAAAAAAAAos/D6TDE3Rr3PU/s1600/2010-04-19+02.02.13.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xTJ-jP6RI/AAAAAAAAAos/D6TDE3Rr3PU/s320/2010-04-19+02.02.13.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;When we finally got home, the final night, the idea was to go to sleep immediately. The ever-present pirate party had other ideas, however.&lt;br /&gt;&lt;br /&gt;There was vodkas and Guitar Hero and lots of falling into each other arms and crying, figuratively speaking, naturally.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xUQFNWubI/AAAAAAAAAo0/DpvJiYJkgGo/s1600/2010-04-20+01.43.54.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xUQFNWubI/AAAAAAAAAo0/DpvJiYJkgGo/s320/2010-04-20+01.43.54.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;We just had a great time. In fact, when I ran through airports the following morning, hungover like what have you, I was told that I had something hanging on my back. So I did. I let it hang all the way back to Sweden, and&amp;nbsp;referred&amp;nbsp;at least one person to Facebook who asked about it.&lt;br /&gt;&lt;br /&gt;It turned out, when I looked at my pictures, that I was not the only one so inflicted.&lt;br /&gt;&lt;br /&gt;I'll wrap this up now, and leave you with some more random pictures and a huge thanks to Chris and his pirate family for creating a completely stellar experience.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/S9xU46TZ7kI/AAAAAAAAAo8/34ai6FxUjUs/s1600/2010-04-19+03.08.00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/S9xU46TZ7kI/AAAAAAAAAo8/34ai6FxUjUs/s320/2010-04-19+03.08.00.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/S9xVC7cVYFI/AAAAAAAAApE/0gYsibXuDyY/s1600/2010-04-19+03.05.15.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/S9xVC7cVYFI/AAAAAAAAApE/0gYsibXuDyY/s320/2010-04-19+03.05.15.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/S9xVMT3syRI/AAAAAAAAApM/XoHJ7dtDnl4/s1600/2010-04-17+15.14.02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/S9xVMT3syRI/AAAAAAAAApM/XoHJ7dtDnl4/s320/2010-04-17+15.14.02.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/S9xVTacumMI/AAAAAAAAApU/6K8Zw1sc7JE/s1600/2010-04-19+02.41.08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/S9xVTacumMI/AAAAAAAAApU/6K8Zw1sc7JE/s320/2010-04-19+02.41.08.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4514286378881112066?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4514286378881112066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4514286378881112066' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4514286378881112066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4514286378881112066'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2010/05/solid-dyson-sphere-of-awesome-jsconf.html' title='A solid dyson sphere of Awesome; The JSConf experience'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rRWdAFxWBEM/S9xBSA8ejAI/AAAAAAAAAoE/jG0N5GcUrME/s72-c/2010-04-17+13.20.29.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-8942647980795909816</id><published>2010-02-28T07:42:00.000-08:00</published><updated>2010-03-01T10:06:52.192-08:00</updated><title type='text'>Super-simple authentication using Google Friend Connect</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://code.google.com/apis/friendconnect/images/friendconnect_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="313" src="http://code.google.com/apis/friendconnect/images/friendconnect_logo.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I've been following Google friend Connect since it came out, since it's a very interesting API.&lt;br /&gt;&lt;br /&gt;For me, what's interesting about it has always been that it takes care of the authentication for a site owner. This is not the basic use-case, mind you. The basic use cases seems to be the simple addition of site-separate, rich, social widgets.&lt;br /&gt;&lt;br /&gt;This is by no mean bad, but the first thing I wanted to do with GFC was to just put up the first, simple 'join this site' widget, and then use the magic to let anyone who had a Google. Yahoo, AIM, OpenID, et.c. account just log in to my site, using a unique user id &amp;nbsp;provided by Google.&lt;br /&gt;&lt;br /&gt;This proved quite hard in the beginning, especially since you basically had to learn a lot of OpenSocial APIs just to do something non-trivial. Since a couple of months back, the GFC APIs has become richer and also simpler. &amp;nbsp;The meaning of this blog post is to show you in a simple way how to leverage GFC for your own authentication, without breaking a sweat.&lt;br /&gt;&lt;br /&gt;What you need to do is the following;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Register your site with&lt;a href="http://www.google.com/friendconnect"&gt; GFC&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Copy-paste in the HTML/Script code for the member gadget into your index.html page (This is done by selecting that gadget and choose to let the GFC page render the code including your site id in a copy-paste box. not terribly hard either).&lt;/li&gt;&lt;li&gt;Do nothing in particular, since the cookie will be send as part of each request to your server (even Ajax ones).&lt;/li&gt;&lt;li&gt;In your server, receive the cookie (looking like this: 'fcauth19038466278488110'), and call GFC from the server, suing the cookie, to get some info about the user.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Using the following code, I make sure that the opensocial API is loaded and that I get a callback when it feels ready. It's not really necessary, but might be of use if you need to access viewer or owner info in your page before or without talking to the server.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;   google.load('friendconnect', '0.8');&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;google.friendconnect.container.loadOpenSocialApi(&lt;br /&gt;{ &lt;br /&gt;      site: 'xxxxxxxxxxxxxxxxxxxx',&lt;br /&gt;      onload: function() &lt;br /&gt;     { &lt;br /&gt;    var fcauth = dojo.cookie("fcauthxxxxxxxxxxxxxxxxxxxx");&lt;br /&gt;    console.log("gfc onload fcauth cookie was '"+fcauth+"'");&lt;br /&gt;    if(fcauth &amp;amp;&amp;amp; fcauth != "undefined")&lt;br /&gt;    {                    &lt;br /&gt;        try&lt;br /&gt;        {                  &lt;br /&gt;            dojo.publish("ab_cookie", [fcauth]);          &lt;br /&gt;        }&lt;br /&gt;        catch(e)&lt;br /&gt;        {&lt;br /&gt;            console.log("ERROR in opensocial access.."+e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Naturally, you can use an Ajax call inside the callback function directly. I've put all of my logic inside a custom Dojo widget, and if you're not using Dojo, you can do whatever you want.&lt;br /&gt;&lt;br /&gt;On the server, which I've coded using &lt;a href="http://node.js/"&gt;node.js&lt;/a&gt; and &lt;a href="http://wiki.github.com/ry/node/modules"&gt;fab&lt;/a&gt;, my handler function look like this;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;Game.prototype.getUserInfo = function(fcauth, id, cb)&lt;br /&gt;{&lt;br /&gt;    // http://www.google.com/friendconnect/api/people/@owner/@self?fcauth=&amp;lt;your fcauth&amp;gt;&lt;br /&gt;    log.info(&amp;quot;getUserInfo called with fcauth='&amp;quot;+fcauth+&amp;quot;' and id='&amp;quot;+id+&amp;quot;'&amp;quot;);&lt;br /&gt;    if(!fcauth &amp;#124;&amp;#124; fcauth == &amp;quot;undefined&amp;quot;)&lt;br /&gt;    {&lt;br /&gt;        log.debug(&amp;quot;Skipping null/unathorized request&amp;quot;);    &lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;    &lt;br /&gt;    var google = http.createClient(80, &amp;quot;www.google.com&amp;quot;);&lt;br /&gt;    var request = google.request(&amp;quot;GET&amp;quot;, &amp;quot;/friendconnect/api/people/@me/@self?fcauth=&amp;quot;+fcauth, {&amp;quot;host&amp;quot;: &amp;quot;www.google.com&amp;quot;});&lt;br /&gt;    request.finish(function (response) &lt;br /&gt;    {        &lt;br /&gt;        response.setBodyEncoding(&amp;quot;utf8&amp;quot;);&lt;br /&gt;        response.addListener(&amp;quot;body&amp;quot;, function (chunk) &lt;br /&gt;        {&lt;br /&gt;            sys.puts(&amp;quot;BODY: &amp;quot; + chunk);&lt;br /&gt;            var echunk = eval(&amp;quot;(&amp;quot;+chunk+&amp;quot;)&amp;quot;);&lt;br /&gt;            if(cb) cb(echunk);&lt;br /&gt;        });&lt;br /&gt;    })&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;You might choose Python or PHP on the server-side, but I hope that the code is fairly simple to understand. I have the specific code that extract the variables somewhere else, but the function is called with a couple of parameters, where one is 'cfauth'. This is the contents of the cookie set by GFC in the page before.&lt;/div&gt;&lt;div&gt;What the function does is call the GFC server with the cookie, using a special URL which gives back user information about the person just signed in using the cookie. We get back stuff that look like this;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;{"entry":{"isViewer":true,"id":"16646299100122442145","thumbnailUrl":"http://www.google.com/friendconnect/profile/picture/9aOJATlcddBMuphbZq6wdLLqvyJr39BwuR60j67nPGv6LO8O_V3xho7gIoeH2juRoEm7jAOdl6_4RK4QAv5aFqD0zzg3TUxVAAZehjEoaEVTjeML9zwRyDFklaql_MxAznquk-Yhm63-ihZtryfA_T3tAwhWv4Szl12A1tZ3xfAa1jAdrE3it5Tx-fAbBW_qPZ3EE4DfALqLKmWC9hqXoXy9wI3rqzoS67CkgsTcU3CJM70ua9Z6OkIpFx7zi3dIXfIFawbodmOhKQ5A7_LeGA","photos":[{"value":"http://www.google.com/friendconnect/profile/picture/9aOJATlcddBMuphbZq6wdLLqvyJr39BwuR60j67nPGv6LNGCV3xho7gIoeH2juRoEm7jAOdl6_4RK11H5aFqDmikrg3TUxVAAZehjEoaEVTjeML9zwRyDFklaql_MxAznquk-Yhm63-ihZtryfA_T3tAwhWv4Szl12A1tZ3xfAa1jAdrE3it5Tx-fAbBW_qPZ3EE4DfALqLKmWC9hqcx0XswI3rqzoS67CkgsTcU3CJM70ua9Z6OkIpFuyzi3dIXfIFawbodmOhKQ5A7_LeGA","type":"thumbnail"}],"displayName":"psvensson"}}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I hope this helps someone, and apologies for not giving out all of my code, which is in a bit of flux.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-8942647980795909816?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/8942647980795909816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=8942647980795909816' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8942647980795909816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8942647980795909816'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2010/02/super-simple-authentication-using.html' title='Super-simple authentication using Google Friend Connect'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-7607514927487360041</id><published>2010-02-11T03:12:00.000-08:00</published><updated>2010-02-11T03:15:47.372-08:00</updated><title type='text'>[Swedish] rabatt till GTUG Stockholm medlemmar till Scandinavian Web Developer Conference 2010</title><content type='html'>&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;img alt="?ui=2&amp;amp;view=att&amp;amp;th=12660e94d18e470d&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_12660e94d18e470d&amp;amp;zw" height="124" src="https://mail.google.com/mail/?ui=2&amp;amp;ik=213d69ae9c&amp;amp;view=att&amp;amp;th=126bcb821b8afa0c&amp;amp;attid=0.3&amp;amp;disp=emb&amp;amp;realattid=ii_12660e94d18e470d&amp;amp;zw" title="?ui=2&amp;amp;view=att&amp;amp;th=12660e94d18e470d&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_12660e94d18e470d&amp;amp;zw" width="320" /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;div class="gmail_quote"&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Den&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;2 och 3 Juni&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;går&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.swdc-central.com/" style="color: #2a5db0;" target="_blank"&gt;&lt;span style="font-size: large;"&gt;SWDC2010&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: large;"&gt;&amp;nbsp;av stapeln på Skandia-teatern på Drottninggatan i Stockholm.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Konferensen för dig som vill lära dig det absolut senaste inom webb och mobilutveckling.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;[Detta information har tidigare gåt ut till GTUG medlemmar, men är nu uppdaterat med mer rabatt och enklare biljettprocess]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;De främsta internationella&amp;nbsp;experterna&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;inom Front-end utveckling, Mobil utveckling och JavaScript delar med sig av sina kunskaper.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;div&gt;&lt;b&gt;DAG 1:&lt;/b&gt;&amp;nbsp;Fokuserar på front-end utveckling och JavaScript&lt;/div&gt;&lt;div&gt;&lt;b&gt;DAG 2&lt;/b&gt;: Fokuserar på&amp;nbsp;programmering och utveckling av mobiltelefonapplikationer till framör allt iPhone och Android.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Du som har kommit på minst ett&lt;b&gt;&amp;nbsp;GTUG Stockholm&lt;/b&gt;&amp;nbsp;möte får 875:- (25%) i rabatt på konferenspriset på&amp;nbsp;&lt;b&gt;3500:-&lt;/b&gt;&amp;nbsp;(ex.moms), alltså bara&amp;nbsp;&lt;b&gt;&lt;u&gt;2625&lt;/u&gt;&lt;/b&gt;&lt;u&gt;:-&lt;/u&gt;&amp;nbsp;för båda dagarna!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Erbjudandet gäller fram till den&amp;nbsp;&lt;b&gt;15 Mars&lt;/b&gt;. För att använda dig av erbjudandet behöver du skicka ett mail från den epost-adress som är registrerad hos GTUG Stockholm till&amp;nbsp;&lt;a href="mailto:register@swdc-central.com" style="color: #2a5db0;" target="_blank"&gt;register@swdc-central.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Som svar kommer du att få en engångskod som du använder under fältet "Coupons" på betalningstjänsten Stage HQ, som vi har länkat till från vår hemsida.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Mer information om konferensen finns att hämta på&amp;nbsp;&lt;a href="http://www.swdc-central.com/" style="color: #2a5db0;" target="_blank"&gt;http://www.swdc-central.com&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Bland våra 15 talare:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img alt="?ui=2&amp;amp;view=att&amp;amp;th=12660c45c7a9ce97&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_12660c45c7a9ce97&amp;amp;zw" height="96" src="https://mail.google.com/mail/?ui=2&amp;amp;ik=213d69ae9c&amp;amp;view=att&amp;amp;th=126bcb821b8afa0c&amp;amp;attid=0.1&amp;amp;disp=emb&amp;amp;realattid=ii_12660c45c7a9ce97&amp;amp;zw" title="?ui=2&amp;amp;view=att&amp;amp;th=12660c45c7a9ce97&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_12660c45c7a9ce97&amp;amp;zw" width="92" /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Tom Hughes-Croucher&amp;nbsp;&lt;/b&gt;- Technical Evangelist/Innovation Lead på&amp;nbsp;&lt;b&gt;Yahoo!&lt;/b&gt;&amp;nbsp;och expert på Accesibilitet och Web standarder.&lt;/div&gt;&lt;div&gt;Talar om :&amp;nbsp;&lt;span style="color: #222222; font-family: Myriad, Helvetica, Tahoma, Arial, clean, sans-serif; font-size: 12px; font-weight: bold;"&gt;Mobile Data: How to avoid the latency trap when using web services.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #222222; font-family: Myriad, Helvetica, Tahoma, Arial, clean, sans-serif; font-size: 12px; font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img alt="?ui=2&amp;amp;view=att&amp;amp;th=12660c5ca6b2152e&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_12660c5ca6b2152e&amp;amp;zw" height="96" src="https://mail.google.com/mail/?ui=2&amp;amp;ik=213d69ae9c&amp;amp;view=att&amp;amp;th=126bcb821b8afa0c&amp;amp;attid=0.2&amp;amp;disp=emb&amp;amp;realattid=ii_12660c5ca6b2152e&amp;amp;zw" title="?ui=2&amp;amp;view=att&amp;amp;th=12660c5ca6b2152e&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_12660c5ca6b2152e&amp;amp;zw" width="96" /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Tom Blackmore&lt;/b&gt;&amp;nbsp;har arbetat med geospatiell data hos&amp;nbsp;&lt;a href="http://hitta.se/" style="color: #2a5db0;" target="_blank"&gt;hitta.se&lt;/a&gt;, varit projektledare för&amp;nbsp;&lt;a href="http://hitta.se/" style="color: #2a5db0;" target="_blank"&gt;hitta.se&lt;/a&gt;'s 3D-kartor, och håller en kurs i GIS på Mälardalens Unviersitet.&lt;/div&gt;&lt;div&gt;Talar om:&amp;nbsp;&lt;span style="color: #222222; font-family: Myriad, Helvetica, Tahoma, Arial, clean, sans-serif; font-size: 12px; font-weight: bold;"&gt;&amp;nbsp;Handling spatial data on the web.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;img alt="?ui=2&amp;amp;view=att&amp;amp;th=1266a6542dfcda0e&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_1266a6542dfcda0e&amp;amp;zw" src="https://mail.google.com/mail/?ui=2&amp;amp;ik=213d69ae9c&amp;amp;view=att&amp;amp;th=126bcb821b8afa0c&amp;amp;attid=0.4&amp;amp;disp=emb&amp;amp;realattid=ii_1266a6542dfcda0e&amp;amp;zw" title="?ui=2&amp;amp;view=att&amp;amp;th=1266a6542dfcda0e&amp;amp;attid=0.1&amp;amp;disp=attd&amp;amp;realattid=ii_1266a6542dfcda0e&amp;amp;zw" /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Stefan Pettersson&lt;/b&gt;&amp;nbsp;är konsult på Netlight AB som JavaScript/Front-End expert och har arbetat på några av Sveriges största sajter, bl.a. Aftonbladet.se.&lt;/div&gt;&lt;div&gt;Talar om:&amp;nbsp;&lt;span style="color: #222222; font-family: Myriad, Helvetica, Tahoma, Arial, clean, sans-serif; font-size: 12px; font-weight: bold;"&gt;Developing Large-Scale JavaScript Websites.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #222222; font-family: Myriad, Helvetica, Tahoma, Arial, clean, sans-serif; font-size: 12px; font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Se&amp;nbsp;&lt;a href="http://www.swdc-central.com/" style="color: #2a5db0;" target="_blank"&gt;http://www.swdc-central.com&lt;/a&gt;&amp;nbsp;för en komplett lista över talare!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&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/7919361321436933137-7607514927487360041?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/7607514927487360041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=7607514927487360041' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7607514927487360041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7607514927487360041'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2010/02/swedish-rabbat-till-gtug-stockholm.html' title='[Swedish] rabatt till GTUG Stockholm medlemmar till Scandinavian Web Developer Conference 2010'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6932538825441599206</id><published>2010-02-01T10:55:00.000-08:00</published><updated>2010-02-01T10:55:44.661-08:00</updated><title type='text'>GTUG Meeting January 2010</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/S2ce_jBV2DI/AAAAAAAAAkw/zrVjBjbJYb8/s1600-h/IMAG0205.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/S2ce_jBV2DI/AAAAAAAAAkw/zrVjBjbJYb8/s320/IMAG0205.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The January meeting got out of hand early on, as I got a semingly inocuous email message from a GTUG member asking if anyone from Google would be there to show the recently unveiled Nexus One phones.&lt;br /&gt;&lt;br /&gt;I asnwered that I thought it unlikely, but that I would give it a shot, and then forward the request to Tommy at Google Sweden.&lt;br /&gt;&lt;br /&gt;Not many minutes passed before I got a reply where he positively guaranteed that he or someone else would be present at the meeting, just the next week.&lt;br /&gt;&lt;br /&gt;When people got to know about this, we had a deluge of registrations, and for the nth time I became really tired with LinkedIn's feature-lack of limits for the otherwise hadny events that I used to use for GTUGs. In all, 93 people registered on the double machine check-in me and Ottoboni provided for the evening.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/S2cgEInagLI/AAAAAAAAAk4/50MPYsOLrgo/s1600-h/IMAG0219.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/S2cgEInagLI/AAAAAAAAAk4/50MPYsOLrgo/s320/IMAG0219.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;First out was Ingemar Resare who talked about Google Apps integration, then came Tommy and Serge from the Google Office and totally winged an imprompty Nexus One presentation using their personal ones and answered hudnerds of questions.&lt;br /&gt;&lt;br /&gt;I had to break somewhere in the possible middle of the question train since people started getting restless, eyehing the sandwhich trays (OK, so I was hungry, sue me :)&lt;br /&gt;&lt;br /&gt;The food break was on the other hand a natural time for people to get to thold and try out the Nexus One themselves, with a Sandwhich or beer in the other, possibly both.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/S2cg3bRyehI/AAAAAAAAAlA/HvsbclnRTRo/s1600-h/IMAG0234.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/S2cg3bRyehI/AAAAAAAAAlA/HvsbclnRTRo/s320/IMAG0234.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;To the left here is Tommy describing the Nexus one's features.&lt;br /&gt;&lt;br /&gt;For our last number, we got Peter Sönnergren who did an outstanding App Engine + Java talk which led to a lot of questions and I think perhaps the first real walkthrough for many present.&lt;br /&gt;&lt;br /&gt;He was promptly talked to by the arranger of JFokus (which was due the very next week) and it turned out that he not only appeared on stage (together with Patrick Chanezon, I think) and also took over a Groove on App Engine session, sicne the Groovy guy had falled unexpectedly sick at the day of the talk. Talk about pivoting!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/S2cigm7U_YI/AAAAAAAAAlI/JjwfB2F1sPY/s1600-h/IMAG0241.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/S2cigm7U_YI/AAAAAAAAAlI/JjwfB2F1sPY/s320/IMAG0241.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Gotta keep this short, but now you know what was going on. &amp;nbsp;And actually, the next GTUG meeting is this Thursday - completely packed as well, since we will both host Spotify's Anders Bond who will talk about their Android development process, and as a little extra number.. &lt;br /&gt;&lt;br /&gt;An Actual Android Developer Codelab with breakout coding sessions and everything led by Reto and Billy from the Google Developer Advocate Android team. Check out their schedule &lt;a href="http://sites.google.com/site/androiddevlabs/home"&gt;here&lt;/a&gt;. Sweden is just part of the big show that's going down right now.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/S2cjDwc_kLI/AAAAAAAAAlQ/ox9jgsiRLXA/s1600-h/IMAG0245.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/S2cjDwc_kLI/AAAAAAAAAlQ/ox9jgsiRLXA/s320/IMAG0245.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;But we'll have a meeting in March as well - at the Google Sweden Office (allegedly).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-6932538825441599206?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6932538825441599206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6932538825441599206' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6932538825441599206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6932538825441599206'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2010/02/gtug-meeting-january-2010.html' title='GTUG Meeting January 2010'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rRWdAFxWBEM/S2ce_jBV2DI/AAAAAAAAAkw/zrVjBjbJYb8/s72-c/IMAG0205.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-3275787464513210435</id><published>2009-12-29T04:49:00.001-08:00</published><updated>2009-12-29T04:49:38.678-08:00</updated><title type='text'>A new term for what we do</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.shawnmcnulty.com/art/L/perseverance_red_abstract_painting.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://www.shawnmcnulty.com/art/L/perseverance_red_abstract_painting.jpg" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I started a new part-time project a while ago where I was allowed to use the full power of thin server architecture and Dojo, where the back-end was written in PHP.&lt;br /&gt;&lt;br /&gt;While talking about the architecture with the back-end developer (which was really impressed about the cleanness of using a &lt;a href="http://groups.google.com/group/json-schema/web/service-mapping-description-proposal"&gt;SMD&lt;/a&gt; file to define the protocol contract between client and server) we compared experiences and realized that we were both programmers first and visual designers last, if at all.&lt;br /&gt;&lt;br /&gt;Many times the customer or project owner have a very dim understanding of client-side development, which leads to bizarre ideas about the simplicity of implementing ideas in the browser. Most common is that JavaScript is seen as something to use as a last resort and that the entire user experience is seen as a series of 90s cardboard static HTML pages, mainly because it's simpler to conceptualize, I guess.&lt;br /&gt;&lt;br /&gt;Working the majority of my time with web pages but never with visual design means that I need to find very advanced customers and project members who understand that there is a layer below the design, but not on the server.&lt;br /&gt;&lt;br /&gt;And that's when the expert PHP developer I was working with (Henrik Hussfelt, no less) coined the term &lt;b&gt;middle-end developer&lt;/b&gt;. I have never heard that before, and IMO it resonates with where I put myself in the value stack.&lt;br /&gt;&lt;br /&gt;Could a new definition like middle-end be a tool to more precisely define the JavaScript programmers role; Not as someone who adds an event handler to a button, but someone who creates the actual client application, but not the markup template for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-3275787464513210435?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/3275787464513210435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=3275787464513210435' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3275787464513210435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3275787464513210435'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/12/new-term-for-what-we-do.html' title='A new term for what we do'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-8171501708471426894</id><published>2009-12-14T05:02:00.000-08:00</published><updated>2009-12-14T05:02:21.088-08:00</updated><title type='text'>GTUG Stockholm meeting December 2009</title><content type='html'>Like the happy crazy people we are, we had a GTUG meeting only days after the Android Hackathon. The upside of that was that we could have a recap for those unfortunates who didn't have the time or ability to attend.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SySvEruGHVI/AAAAAAAAAiY/l2JJYYqwH7Y/s1600-h/IMAG0175.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SySvEruGHVI/AAAAAAAAAiY/l2JJYYqwH7Y/s320/IMAG0175.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;About 30 people came, which is OK, but made me think maybe we should do the meetings bi-monthly instead of every month. Not sure either way, but I'll decide after next meeting.&lt;br /&gt;&lt;br /&gt;The people who came were as always from a lot of different companies; Spotify, formerly of Spotify, Voddler, Qbranch and many others.&lt;br /&gt;&lt;br /&gt;After my short introduction and talk on some new Google technologies (Mostly Closure) Tommy Widenflycht from Google Sweden did a talk on Google recruitment and then answered questions for a long time, handing out frisbees and hats to the best ones.&lt;br /&gt;&lt;br /&gt;Apparently, there's a need for really talented Server-Side coders (C++/Java) and A/V Codec programmers in the Stockholm office (and elsewhere). If you feel that you fit the bill, contact me by direct email (psvensson@gmail.com) or comment this post and I'll make sure you get to talk to the right people.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SySwyyaykKI/AAAAAAAAAig/V_ti8vmXHhA/s1600-h/IMAG0181.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SySwyyaykKI/AAAAAAAAAig/V_ti8vmXHhA/s320/IMAG0181.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Then it was time for the much-anticipated JavaScript on Android talk by &lt;a href="http://divineprogrammer.blogspot.com/"&gt;Mikael Kindborg&lt;/a&gt;. I was really impressed with the research Mikael had done and what he had managed to do.&lt;br /&gt;&lt;br /&gt;First he had compiled Rhino for the Dalvik VM and used that to parse incoming JavaScript string. So far, so good. To do that he had made a simple JavaScript app server called RhinoDroid (You can get it&lt;a href="http://github.com/mikaelkindborg/RhinoDroid"&gt; here &lt;/a&gt;from github) that made it simpler to push JS from an external source (like a browser, or in Mikael's case, the Squeak Smalltalk environment. That's was really cool in itself. What happened then I could have understood if I had thought about it, but I hadn't had the time.&lt;br /&gt;&lt;br /&gt;Since all Android APIs (that has been compiled into the RhinoDroid app) are accessible by the JavaScript script when running, Mikael showed how he could build up a simple Android interface&amp;nbsp;asynchronously, adding some buttons, which popped up on the Androdi screen, push those a bit - nothing happens.&lt;br /&gt;&lt;br /&gt;Then send some JavaScript event handlers that bind to those buttons, which get dynamically evaluated and then the button do something. So he was building an Android UI - and changing it - in realtime. Think about that for a while.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SySyv1gGkcI/AAAAAAAAAio/gB-HDQKpCdo/s1600-h/IMAG0184.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SySyv1gGkcI/AAAAAAAAAio/gB-HDQKpCdo/s320/IMAG0184.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;The next talk was Johan Burell who did a run-down of the &lt;a href="http://unclescript.blogspot.com/2009/12/gtug-android-hackathon-2811-2009.html"&gt;Android Hackathon the previous Saturday;&lt;/a&gt; Which apps had been created, which ones had _almost_ been created, and so on. Several people who had been present was in the audience as well, so we had some recaps and discussions about team @froderik's Android Hudson front-end and the other apps as well.&lt;br /&gt;&lt;br /&gt;The last talk for the night was by Sony Ericsson's strategy manager Thomas Bailey, who did show and pass around an actual X10 Android phone. It's surprisingly and reassuringly heavy and a screen that is 'right' sized. The interesting parts of Thomas' talk was the fact that Sony Ericsson is starting their own Android App store, to be able to offer developers a more controlled environment to publish their apps to, and Sony Ericsson's signature apps (Organizing and formatting activity streams and media) which will exist only on their phones but can be extended using XML files, which will pop in future sources of contacts, media and other things, which is a neat concept in itself.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SyTPDzFhVyI/AAAAAAAAAiw/zSZQGMZmcfE/s1600-h/IMAG0189.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SyTPDzFhVyI/AAAAAAAAAiw/zSZQGMZmcfE/s320/IMAG0189.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Our next meeting will be on &lt;a href="http://events.linkedin.com/GTUG-Stockholm-January-2010/pub/180846"&gt;January 14th&lt;/a&gt;, where we will cover the following topics:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, 'Nimbus Sans L', sans-serif; font-size: 10px; line-height: 11px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;li style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-size: 13px; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;br /&gt;&lt;div style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 8px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: medium;"&gt;Peter Svensson - State of the code (+some Dojo layout goodness)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;br /&gt;&lt;div style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 10px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 8px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: medium;"&gt;Ingemar Resare - Google Apps use cases.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: medium;"&gt;Peter Sönnergren - App Engine + Java&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: medium;"&gt;Johan Burell - Google Go (+ Android Cntrllr)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: medium;"&gt;Leonard Axelsson - App Engine + Groovy&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;See you guys then, and a Merry Spaghettimas to you all!&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-8171501708471426894?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/8171501708471426894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=8171501708471426894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8171501708471426894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8171501708471426894'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/12/gtug-stockholm-meeting-december-2009.html' title='GTUG Stockholm meeting December 2009'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SySvEruGHVI/AAAAAAAAAiY/l2JJYYqwH7Y/s72-c/IMAG0175.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-8310921001407416064</id><published>2009-12-09T09:25:00.000-08:00</published><updated>2009-12-09T09:25:59.544-08:00</updated><title type='text'>Full Brighton</title><content type='html'>And actually, this blog *should* be about how to avoid common pitfalls when using Dojo widgets inside hidden ContentPanes (as when using Stack- or TabContainers), but I have a huge queue of, oh, two or so posts to go before that.&lt;br /&gt;&lt;br /&gt;Todays topic is of course the unreasonably nice JavaScript conference in Brighton recently - Full Frontal.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/Sx_SAlNqypI/AAAAAAAAAhs/LwAXN5la9tQ/s1600-h/IMAG0077.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/Sx_SAlNqypI/AAAAAAAAAhs/LwAXN5la9tQ/s320/IMAG0077.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;I have never been to Brighton before, and one of the experience was walking about the city itself.&lt;br /&gt;&lt;br /&gt;Which&amp;nbsp;despite&amp;nbsp;the pedestrian nature of above statement is not&amp;nbsp;particularly&amp;nbsp;easy, even if it's nice (sharing&amp;nbsp;properties&amp;nbsp;with several other activities I could think of..).&lt;br /&gt;&lt;br /&gt;The reason for the lack of simplicity is that the city is actually at least two cities, which don't like each other very much and have crashed into one another in a desperate struggle to the very end, throwing streets and towers as you please, leaving the unwary resident in crossing with no less than three busy streets, often multiples of that, where two or more have steel railings to avoid being crossed in reasonable manners.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/Sx_TPVXN0FI/AAAAAAAAAh0/keqkHcsbSyo/s1600-h/IMAG0079.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/Sx_TPVXN0FI/AAAAAAAAAh0/keqkHcsbSyo/s320/IMAG0079.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I had managed to hitch a ride out of the airport with @icaaq, or actually @icaaq's cousin, who was living with her family in Brighton since years back. After a quick freshening up in the Hotel room I managed to get to something I&amp;nbsp;believe&amp;nbsp;is the west end of Brighton which is chock-full of pubs, of which me and a motley crew of web developers, media folks, CEOs, CSS gurus and JavaScript madmen went to at least three (or so they say).&lt;br /&gt;&lt;br /&gt;The evening was punctuated by Christian Heilman was nice enough to lead the way to the actual beach (at 2am) to see a work of art of some sort, where I managed to take a photo of him and Lieke Arendts of Ajax.org and Javelin fame (uppermost above).&lt;br /&gt;&lt;br /&gt;The conference was set in a beautiful fin-de-last-but-last-again-ciecle cinema named Duke of York Cinema. You know what? All conferences should be in cinemas. Problem with ventilation? Nope. Too hot or cold? No way. A cinema is made for large number of people sitting for a long time looking at whatever's up on the stage. Perfect!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sx_VMRJeTEI/AAAAAAAAAh8/t1CSjEQtmKU/s1600-h/IMAG0088.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sx_VMRJeTEI/AAAAAAAAAh8/t1CSjEQtmKU/s320/IMAG0088.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;And was it great! One of the best things was that I wasn't even speaking. I had no last-minutes slides to perfect, no slow parts of my talk to worry about - nothing. I could just sit down and enjoy the show.&lt;br /&gt;&lt;br /&gt;But even though JSConf.eu wins due to the sheer amount of good content, Full Frontal still manage to out-wattage JSConf.eu on the mere fact that it was *so* right in just one day, managing by luck or engineering to get almost every speaker not only be the right kind but sort of building upon each others talks.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/Sx_XtSirhbI/AAAAAAAAAiE/Z-xxKeyROpI/s1600-h/IMAG0091.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/Sx_XtSirhbI/AAAAAAAAAiE/Z-xxKeyROpI/s320/IMAG0091.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Everything was good, but the absolute highlights for me was Jake Archibalds talk on JavaScript optimization. Not only for the hard data on what to do and not to do - between different browser, but he had a stunning presentation technique. First of all his slides were top-notch (can he possible be that skilled? Or do he have some secret connections in the Beeb's media departments?), and secondly he had a comic timing that made his talk the most fun-packed of the day.&lt;br /&gt;&lt;br /&gt;He had this slide of a He-man doll, which he&amp;nbsp;referred to as the power of the JavaScript VMs of the moderns browsers&amp;nbsp;, but crossed with terminator (next slides showing he-man with Borg eye), and a crustacean forming a battlecrab! (bext slides showing a cyborged he-man doll with a large crab-like derierre), and so on. I don't make him credit, but it was really great.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/Sx_ayrgnisI/AAAAAAAAAiM/Cq9G21RMd5Y/s1600-h/IMAG0111.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/Sx_ayrgnisI/AAAAAAAAAiM/Cq9G21RMd5Y/s320/IMAG0111.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;The next best part was the closing act, where Simon Willison had ditched his prepared talk (something about web APIs) after seeing the presentations on JSConf the week earlier, and promptly slammed together his own talk on node.js, using fluffy rabbits, cute hamsters and octopuses (OK, just one octpus), to describe the difference between threaded event handling and event-callbacks.&lt;br /&gt;&lt;br /&gt;The talk had just the same effect on Full Frontal. people whooped and became generally agitated about the idea to use their front-end kung-fu to start building heavy-hitting serve-side stuff as well. No new idea (and the Javelin guys were quietly commenting on their own KLOCs of C++ to make their own SSJS platform one of the speediest, doing essentially the same - and more), but the magic bullet here is one of perceived complexity;&amp;nbsp;Noone in the room thought that they would have a hard time picking up node.js and try something out with it. Just as with CouchDB, it simple to explain and simple to use. Well, OK, I'll shut up about it for now, but&amp;nbsp;expect&amp;nbsp;me to be back on the topic!&lt;br /&gt;&lt;br /&gt;Anyhoo.. the after-party was nice, full of back-clapping and camaraderie,and just the right size too. I think that the superpower of the current JavaScript movement that's building is twofold; people are super-amateurish and quirky, and also nice. Really, really nice.&lt;br /&gt;&lt;br /&gt;Amateurism in really bright people means playfulness and a lowering of barriers, so that using hamsters for request is seen as OK - not very academical, but fun and getting the point across.&lt;br /&gt;&lt;br /&gt;I'll definitely be back next year (there too :)&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-8310921001407416064?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/8310921001407416064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=8310921001407416064' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8310921001407416064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8310921001407416064'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/12/full-brighton.html' title='Full Brighton'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/Sx_SAlNqypI/AAAAAAAAAhs/LwAXN5la9tQ/s72-c/IMAG0077.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-3781279457932540283</id><published>2009-12-01T10:17:00.000-08:00</published><updated>2009-12-01T10:19:29.315-08:00</updated><title type='text'>GTUG Android Hackathon 28/11 2009</title><content type='html'>Earlier this year, I had an idea for an all-day event for hacking on some Google technology. When I proposed this to the group at a GTUG meeting, I was reasonably certain that Wave was going to be chosen as the technology in question, and to my surprise instead Android took home most of the votes.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVA0vAqeEI/AAAAAAAAAgA/GqGWrVykOZA/s1600/IMAG0123.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVA0vAqeEI/AAAAAAAAAgA/GqGWrVykOZA/s320/IMAG0123.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So, Android it was. No worries, though, as I'm a great friend of the platform - even though it is still officially restricted to Google's brand of Java, but more of that this Thursday when&lt;a href="http://sites.google.com/site/stockholmgtug/agenda_mote_3_12"&gt; Mikael Kindborg will do a talk on JavaScript on the Android&lt;/a&gt;, among other talks (including Sony Ericsson's Strategy Manager Thomas Bailey).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVCfBE7VfI/AAAAAAAAAgI/nSd1TSME61o/s1600/IMAG0126.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVCfBE7VfI/AAAAAAAAAgI/nSd1TSME61o/s320/IMAG0126.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;The process running up to the Hackathon was almost Kafkanesque in nature. Not at the beginning, where Bwin Games agreed to host the Hackathon (on a Saturday) at their lavish premises in central Stockholm. Later, when it was apparent that the budget was rather tight at Q4 (in (yet another) year of recession) to provide dinner - something I felt was a necessity for an event stretching from 9.00am to 8.00pm.&lt;br /&gt;&lt;br /&gt;After getting literally dozens of great leads after I reached out to the community, on twitter (I'm @psvensson) and beyond, I had as many as four different companies that tried to find resources within their organizations to no avail (but thanks for the effort nonetheless!). Finally I got a possible sponsor, but then it turned out that sponsorship is a sensitive issue and the company in question had agendas parallell to that of Bwin for providing the venue in the first place.&lt;br /&gt;&lt;br /&gt;With only days left, I had to call in the cavalry and use my contacts at Google (Thanks Serge and Stephanie!) who agreed to take the bill for the dinner.&lt;br /&gt;&lt;br /&gt;What? You want to know about the Hackathon and not my orgnaizational ramblings? Why didn't you say so? Here goes:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxVERi0QUGI/AAAAAAAAAgQ/Sll8WrPNyNc/s1600/IMAG0128.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxVERi0QUGI/AAAAAAAAAgQ/Sll8WrPNyNc/s320/IMAG0128.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;As many as 49 people had signed up for the Hackathon, 43 on LinkedIn and 6 by direct email, and after all was said and done 33 showed up, but what a group. We got people from Plusfoursix, Isotop, everbody from Appcorn (who had attended whole day iPhone developer event the day before), HiQ, COMBOL and many others.&lt;br /&gt;&lt;br /&gt;Several people came just to see Dirk Groten, CTO &amp;nbsp;from the progressive Augmented Reality company &lt;a href="http://layar.com/"&gt;Layar&lt;/a&gt;, who had graciously agreed to come up to Stockholm and demonstrate how to build service and applicaitons with their system. Layar is just at the time of this writing about to reveal their new polygonal 3D service, which lets developers created fairly complex polygons at specific geographical locations, which ups the ante a bit.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVF3G6bgVI/AAAAAAAAAgY/WznnBuDXPMA/s1600/IMAG0129.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVF3G6bgVI/AAAAAAAAAgY/WznnBuDXPMA/s320/IMAG0129.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;After Dirk, we had a talk from our own Johan Burell, who had a thorough walk-through of the &lt;a href="http://code.google.com/p/rokon/"&gt;Rokon&lt;/a&gt; gaming library for Android, which provides a lot of simplifying wrappers for 2D gaming, which several of the groups later used.&lt;br /&gt;&lt;br /&gt;After the talks were done, we had a light but satisfying wraps-based lunch provided by Bwin and then on to coding.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVHrou6q7I/AAAAAAAAAgg/eWF9QKshEJQ/s1600/IMAG0130.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVHrou6q7I/AAAAAAAAAgg/eWF9QKshEJQ/s320/IMAG0130.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The atmosphere during the whole day was very open and friendly. Teams helped each other out on several occasions, fixing solutions to MapView dynamic updating to getting the current GPS position.&lt;br /&gt;&lt;br /&gt;Also, there was (at least I had quite a few :) a lot of general discussions on and off, about whether it was amoral for Craigslist to provide free advertising, thus putting newspapers out of business, the recent split of the &lt;a href="http://www.squeak.org/"&gt;Squeak&lt;/a&gt; Smalltalk platform into &lt;a href="http://www.pharo-project.org/home"&gt;Pharo&lt;/a&gt;, CouchDb REST musings and lots of other stuff.&lt;br /&gt;&lt;br /&gt;What I mean to say is that these coders weren't your garden variety lockergnomes, these were hard people, OK? just saying :)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxVIo_a6hSI/AAAAAAAAAgo/eSEDnaO8nJo/s1600/IMAG0141.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxVIo_a6hSI/AAAAAAAAAgo/eSEDnaO8nJo/s320/IMAG0141.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Some teams borrowed meeting rooms from Bwin to doodle on white boards, but most teams huddled down in groups, hacking intently as the dusk fell over Stockholm. Actually, dusk was all we had that day, steel-blue clouds and a mere thirty seconds or so of sun.&lt;br /&gt;&lt;br /&gt;At the end of the day, each time got one minute - sometimes a verrry long minute - to present their application. After everyone had presented, everybody present (some people had to leave before the presentations) voted by raising their hands (only one vote per person) on the app they liked best - and one was not allowed to vote for ones own. As it turned out first price went to the Bwin team with their app "Crimesweeper", which got real-time police crime scene data, and mashed it up in a MapView, awarding points for players who visited the scene (vigilante.apk?)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVJ4TynH2I/AAAAAAAAAgw/BZ1ckeQ_tGA/s1600/IMAG0145.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVJ4TynH2I/AAAAAAAAAgw/BZ1ckeQ_tGA/s320/IMAG0145.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;The second-price winners had made a very creative game app which tracked the players and plotted them on each others screens, and provided a method for throwing virtual water baloons at each other.&lt;br /&gt;&lt;br /&gt;Then one team had made a very useful Hudson front-end for Android where you could start Java build jobs and check their statuses.&lt;br /&gt;&lt;br /&gt;One team had made almost a space shooter with the Rokon library, but due to time constraints it was actually a "space dodger" - tasteful nonetheless.&lt;br /&gt;There was an app which demonstrated a CouchDB library for the Android, something really useful.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVXrB-_J-I/AAAAAAAAAg4/-wGJ2DsvoBU/s1600/IMAG0146.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVXrB-_J-I/AAAAAAAAAg4/-wGJ2DsvoBU/s320/IMAG0146.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;One app which was made by an attendee who was forced to leave before the voting (please comment if you remember who - thx!) made an app for kids learning words using images and rotating letters - which was very appreciated, but got few votes. Strange, but what do you do? :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxVaRSv9NzI/AAAAAAAAAhA/50GN6eGyxXY/s1600/IMAG0147.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxVaRSv9NzI/AAAAAAAAAhA/50GN6eGyxXY/s320/IMAG0147.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;We had another app by single-team @sharj, which used the twitter API to get a random twitter user bio and let you follow if you liked it. In the future he means to add support for recommending users based on usage patterns.&lt;br /&gt;&lt;br /&gt;And he got another one as well, which used the recent Google Movies API to list movies and to say which ones you were going to see, foursquare-style, of sorts.&lt;br /&gt;&lt;br /&gt;@burre83's team made a rhythm-action app, which was surprisingly catchy, tempting the player to hit random parts of the screen in time to the music.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxVasy-z_8I/AAAAAAAAAhI/Bp9KcyHnxTM/s1600/IMAG0150.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxVasy-z_8I/AAAAAAAAAhI/Bp9KcyHnxTM/s320/IMAG0150.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A couple of teams did not finish, but a couple came surprisingly far, given their ambitions.&lt;br /&gt;&lt;br /&gt;What was interesting was that so many teams had such divergent &amp;nbsp;ideas, and that so many attendees came without really any prior Android development experience - and still managed to produce runnable code!&lt;br /&gt;&lt;br /&gt;The winners and the second place teams got each a book from Apress called "Pro Android" which in my opinion is the most comprehensive one out there. The winning team also got some really nice Google drinking bottles and my very last Android keyring trinkets,which were much appreciated.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVcHt0awJI/AAAAAAAAAhQ/BaBWGtH2Ua8/s1600/IMAG0153.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVcHt0awJI/AAAAAAAAAhQ/BaBWGtH2Ua8/s320/IMAG0153.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This left me with a couple of books left (since Apress had sent me 10), which after due consideration was given to to teams which I felt needed them the most, for different reasons.:)&lt;br /&gt;&lt;br /&gt;When everything was wrapping up, we decided to go down to the local pub Bishops Arms at Vasagatan for some beers and lots of discussion - some about Psytrance and scouting if I recall correctly.&lt;br /&gt;&lt;br /&gt;In retrospect the day went very smooth, mostyl due to the&amp;nbsp;playful&amp;nbsp;professionalism&amp;nbsp;of all present. Also, since most of the day was spent by the attendees hacking I had several hours on and off where I could blog about my adventures in Russia and other events that needed some writing.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVdGOKMJNI/AAAAAAAAAhY/8hUiko4CsLk/s1600/IMAG0156.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVdGOKMJNI/AAAAAAAAAhY/8hUiko4CsLk/s320/IMAG0156.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This had been hanging over me for some time, and it felt really good to be in a position to do something about it, between coaching sessions and general discussions.&lt;br /&gt;&lt;br /&gt;Something that really meant a lot to me was that three separate people, on separate occasions, went up to me and said how great they thought the event was and thanked me for arranging it. Me, who really didn't do much in particular, other than yakking and blogging :)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVdqTdSfHI/AAAAAAAAAhg/KEqUTLI_JTU/s1600/IMAG0162.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SxVdqTdSfHI/AAAAAAAAAhg/KEqUTLI_JTU/s320/IMAG0162.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Thank you so much! ^-^&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-3781279457932540283?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/3781279457932540283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=3781279457932540283' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3781279457932540283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3781279457932540283'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/12/gtug-android-hackathon-2811-2009.html' title='GTUG Android Hackathon 28/11 2009'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rRWdAFxWBEM/SxVA0vAqeEI/AAAAAAAAAgA/GqGWrVykOZA/s72-c/IMAG0123.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6901755880957895451</id><published>2009-11-28T09:55:00.000-08:00</published><updated>2009-11-28T09:55:45.742-08:00</updated><title type='text'>From Russia with ow!</title><content type='html'>So, I had this meeting. The rationale behind it went something like this; Google will soon be releasing certifications and courses related to those certifications to developers. That mean not only 'learn how to administer adwords' but 'learn how to develop with the Maps API' or 'learn how to make a decent App Engine app in Python', that kind of stuff.&lt;br /&gt;&lt;br /&gt;OK.&lt;br /&gt;&lt;br /&gt;I was talking to Shannon, who is a training and documentation manager at Google, about starting up a Swedish Qualified Education Center focusing on hardcore development rather than administrative tasks. She was going to be in Europe in the beginning of November, together with Stephanie, my GTUG boss (and a lot of other people) doing the Google Developer Days in Prague and Moscow. I was going to go to Berlin the very day of the Prague GDD, so my only option was to met her in Moscow.&lt;br /&gt;&lt;br /&gt;Now, Moscow isn't really Europe. At all. Whatsoever. Regretting my decision daily, I began the ridiculously Kafkan process of applying for a Visa for Russia. The most poignant memory of that was realizing that they would keep my passport for a whole week (no doubt shipping it by nuclear submarine to Irkutsk to be steamed open and copied to numerous spetsnaz operatives), which had me standing in line to get my passport back in the morning, the very same day I was flying to Berlin!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFPQZhQaMI/AAAAAAAAAfI/GmBK8llkkfg/s1600/IMAG0058.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFPQZhQaMI/AAAAAAAAAfI/GmBK8llkkfg/s320/IMAG0058.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Also, I was home about 8 hours from Jsconf.eu before getting in the Taxi again, going to the plane that was taking me to Moscow, seeing my family only briefly. &amp;nbsp;After arriving to the commandeered cinema where the GDD event took place, I recognize the Hookah lounge from pictures Stephanie has posted on twitter (which was very helpful).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFQOXGQmgI/AAAAAAAAAfQ/7iJ26zbgwV0/s1600/IMAG0059.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFQOXGQmgI/AAAAAAAAAfQ/7iJ26zbgwV0/s320/IMAG0059.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;I then try (after doing some panic work for one of my favourite clients, involving a Layar REST endpoint) to talk to Stephanie (pictured with wine above, which I served her and Shannon on a Gitub coaster, courtesy of the github developers I met at jsconf) and Shannon about my training center plans. However, the place is quite noise, and a lot of people come in and ask questions about Google things, mostly directed to me, not even being a Google employee - I'm just the unofficial PR manager :).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFRBIjpN-I/AAAAAAAAAfY/sC2kSfcNtpU/s1600/IMAG0068.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFRBIjpN-I/AAAAAAAAAfY/sC2kSfcNtpU/s320/IMAG0068.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;After the evening progresses (and I haven't even checked in to my fairly remote hotel yet, schlepping around my computer case), I get invited to a Google post-conference dinner with the speaker and arrangers of the day. It was really cool to meet and shake hands with some of the Wave team, the EMEA Sales manager (hi Timbo!), The PM for the V8 JS Engine (Hi Anders!) and lots of other really cool people.&lt;br /&gt;&lt;br /&gt;Here's a pic where the Wave team respond to the "Who wants vodka?" call. And as you can see, the food was epic. Grilled cheeses, soups, sausages, blinies, pancakes, breads, pies and so on. Thank you (again, for the tenth time) so very, very much.&lt;br /&gt;&lt;br /&gt;Naturally, there's no real time to talk shop during the dinner, so in the wee hours, Shannon and I agree to meet the next day at the Moscow sales offices instead. Great. No problem. The very nice Russian head of office (whose name I've forgot - sorry) helps me get into a cab on the street, where he negotiates price, direction, duration,&amp;nbsp;associations&amp;nbsp;and who knows what to put the driver in a customer-friendly mood.&lt;br /&gt;&lt;br /&gt;However, after 45 minutes we start to veer out into industrial areas, spotty lighting, semi-rural fields and people sitting and drinking on the sidewalk. Here my driver stops and walks out of the car.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFbADHtlzI/AAAAAAAAAfg/MfX-UNYw8YQ/s1600/IMAG0069.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFbADHtlzI/AAAAAAAAAfg/MfX-UNYw8YQ/s320/IMAG0069.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It turns out he's asking directions from the drinking people. Good call. Sort of. He gets back in, swerves around and starts backing up for a long, long way, going here and there after that in the adjoining industrial neighborhoods. It's in the middle of the night, the driver doesn't speak English and he don't know the way. Great.&lt;br /&gt;&lt;br /&gt;Eventually, to spare you more details, he does manage to find the hotel, and I collapse in the surprisingly roomy 'suite', knowing that I have to get up in six hours to get to the actual meeting back in the city center. Woe to you oh earth and sea, et.c.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxFiIIbc2II/AAAAAAAAAfo/9aFlhPc36Cg/s1600/IMAG0071.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxFiIIbc2II/AAAAAAAAAfo/9aFlhPc36Cg/s320/IMAG0071.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Then the taxi I managed to get hold of tries to renegotiate the price when we start driving, which gets me so mad, I scream at the driver to stop immediately and open my door without thinking of the consequences. We'travelling quite slowly, and the driver gets kind of upset - but so am I. After some intense broken English negotiations, I get the original price and our drive continue in a communal, surly silence.&lt;br /&gt;&lt;br /&gt;When I arrive at the sales office, two things are apparent; 1) There's no Shannon working there (I know, she's from the MTV office) and there's no meeting scheduled (since it was agreed upon in the middle of the night), which makes the security-minded secretary less than open towards my feeble efforts in trying to stay in the office. Just when I really have to leave, before the situation becomes unbearable, Shannon calls the office. That first picture with me in front of the Google logo is taken in the sales office, which happened to be the wrong office. Time for another quick taxi across town..&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxFi8cG_vGI/AAAAAAAAAfw/S-a5yw_pOMM/s1600/IMAG0072.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxFi8cG_vGI/AAAAAAAAAfw/S-a5yw_pOMM/s320/IMAG0072.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It turns out that a quick dash across town takes almost an hour, at which time Shannon is 15 minutes away to take her own cab back to the airport. I do find time to get my picture taken in front of the other office's logo and steal up on some iced tea (thanks!).&lt;br /&gt;&lt;br /&gt;In the end, we conduct a very interesting meeting in the very cab back to the airport, even if it finds me twiddling my thumbs for a number of hours, waiting for my own flight to come up.&lt;br /&gt;&lt;br /&gt;It was a roller-coaster adventure, buffeted only by the kindness of Google employees along the way. I would have had a much rougher visit ion Moscow without access to the right people (including my own connections who picked me up at the airport; Hi Alexander!), but then again, without those very people it would never had crossed my mind to visit.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxFkFd7Zu8I/AAAAAAAAAf4/8j1qkI5_MOc/s1600/IMAG0073.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxFkFd7Zu8I/AAAAAAAAAf4/8j1qkI5_MOc/s320/IMAG0073.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-6901755880957895451?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6901755880957895451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6901755880957895451' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6901755880957895451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6901755880957895451'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/11/from-russia-with-ow.html' title='From Russia with ow!'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rRWdAFxWBEM/SxFPQZhQaMI/AAAAAAAAAfI/GmBK8llkkfg/s72-c/IMAG0058.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-2791438417751973301</id><published>2009-11-28T06:35:00.000-08:00</published><updated>2009-11-28T06:35:28.210-08:00</updated><title type='text'>November GTUG Stockholm Meeting</title><content type='html'>My apologies for not having time to blog about this sooner (Hi Steph! :) but there you go. The 5/11&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxEwc7bToSI/AAAAAAAAAeo/si7XkiAS_bw/s1600/IMAG0024.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxEwc7bToSI/AAAAAAAAAeo/si7XkiAS_bw/s320/IMAG0024.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;meeting was a bit shorter on attendance than what we were used to. It turned out quite that at the very same day, we had attendual interference from the week-long Öredev developer event, a local Java users group meeting and an open house day at The Royal Technical Highschool (IIRC), so we got somewhere between 40 and 50 people (of which only 30 or so registered - due to some people showing up a bit late, things happens).&lt;br /&gt;&lt;br /&gt;The order of the day was yet another Wave demo with some focus on how a Wave bot works (I used the Wolfram Alpha source code), and a thorough 2-part talk by Jonas Burell on his upcoming open-source collaborative music-making Android application called Cntrllr.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxE0thnWcXI/AAAAAAAAAew/loMt5ZgRv24/s1600/IMAG0029.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SxE0thnWcXI/AAAAAAAAAew/loMt5ZgRv24/s320/IMAG0029.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Since I had two different speakers defaulted on their presentations for this meeting, I threw in a beta of my upcoming Jsconf.eu talk on dojox.gfx cross.browser 2D graphics.&lt;br /&gt;&lt;br /&gt;As always there was a lot of great discussions over a broad range of subjects of beers and sandwiches in the pauses in between talks, and as always great and passionate people attending. Did I mention I like arranging these things? :)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxE1INlK-fI/AAAAAAAAAe4/aSHarrlSHi0/s1600/IMAG0030.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxE1INlK-fI/AAAAAAAAAe4/aSHarrlSHi0/s320/IMAG0030.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-2791438417751973301?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/2791438417751973301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=2791438417751973301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2791438417751973301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2791438417751973301'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/11/november-gtug-stockholm-meeting.html' title='November GTUG Stockholm Meeting'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SxEwc7bToSI/AAAAAAAAAeo/si7XkiAS_bw/s72-c/IMAG0024.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-2191889239856230108</id><published>2009-11-24T12:45:00.000-08:00</published><updated>2009-11-28T06:38:50.728-08:00</updated><title type='text'>The German Connection</title><content type='html'>Hoo boy, I'm still tired from Berlin :) Or maybe it's the accumulated trips that have caught up with me. Either way it has taken me some time to get around to unload the camera and sleep and work and.. oh wait, I just realized I had planned to post about the latest GTUG Stockholm meeting. Oh well, next up I guess.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SwwryaMeKFI/AAAAAAAAAd4/iicv468NCkA/s1600/IMAG0031.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SwwryaMeKFI/AAAAAAAAAd4/iicv468NCkA/s320/IMAG0031.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I missed the original and first JSConf in Washington, since I had a client default on me at around that time. No nice experience, double so because of missed attendance.&lt;br /&gt;&lt;br /&gt;I was dead set at not missing the European JSConf.eu at any price, and was more than happy when I was admitted as a speaker with my dojox.gfx talk. I had never been to Berlin before and to Germany only once, twenty years ago (yes I am that old!), so I had no idea what to expect, really.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/Swwy1JmzziI/AAAAAAAAAeA/Nhb19KJl0gI/s1600/IMAG0036.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/Swwy1JmzziI/AAAAAAAAAeA/Nhb19KJl0gI/s320/IMAG0036.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Well, two things stuck me at once: 1) Berlin is *huge*, 2) It's also beautiful. Due to the first fact, you have to take Taxi everywhere (which generally a) lack onboard GPS and Maps R2D2, b) lack any card readers, forcing you to luggage around lots of Euros).&lt;br /&gt;&lt;br /&gt;Oh, the conference? The conference was a huge success, but more than that it was immensely enjoyable. Day one had a great opening by Dion Almaer (now, as we all know, of Palm).&lt;br /&gt;&lt;br /&gt;What I took away from most of the speeches is that I probably need to brush up on the noble art of making slides. Dion's presentation was fun, tons of fun, and also very nice to look at. What do I have? Slapped together pictures and pages of code. Not much fun that :) Actually, that was also a theme underlying much of Dion's speech,something I know but don't react enough on - sex sells, people want to have fun, et.c.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sww0WdMRVyI/AAAAAAAAAeI/Yi9MUDrUl9Y/s1600/IMAG0038.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sww0WdMRVyI/AAAAAAAAAeI/Yi9MUDrUl9Y/s320/IMAG0038.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Some other notable talks was Remy's HTML5 presentation (mot least because it contained Sharks with lasers!), The&amp;nbsp;cappuccino&amp;nbsp;presentation by Francisco Tomalsky was also really good, but after a lot of head-wrangling I feel that I somehow still want to code my clients and that the WYSIWYG will only get in the way. Well, right, they had stellar support for hand-coding as well. OK, OK, I admit it, I'm just jealous. There, I said it, can we move on?&lt;br /&gt;&lt;br /&gt;The CommonJS and Server-Side JavaScript in general lay as a barely audible hum throughout the two days of presentations. A comment from Malte on how he had used Joose on the server-side, the OpenAjax guys (Hi Lieke, Mike and everyone else from Javeline), naturally who made their very own SSJS VM, and lots of other comments in and around the talks made SSJS feel very present.&lt;br /&gt;&lt;br /&gt;The natural focus of Server-Side would of course had been Kris Kowal's CommonJS talk, which was&amp;nbsp;very&amp;nbsp;good in itself, but what really dropped a bomb was @ryah's node.js unveiling. Naturally, as everybody (now) knows, node.js has been going on for over half a year, but it hasn't had lots of attention. Until now. What got our attention was the off-beat assertion by Ryan&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sww4T8h3xZI/AAAAAAAAAeQ/xWY1iqwYLiM/s1600/IMAG0043.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sww4T8h3xZI/AAAAAAAAAeQ/xWY1iqwYLiM/s320/IMAG0043.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;that using thread-based logic was doing everything wrong.&lt;br /&gt;&lt;br /&gt;He talked about how he had done quite a lot of advanced magic (with threads, inside node.js) to be able to expose system events, pipes, sockets and services to be handled by JavaScript callbacks- that is node.js.&lt;br /&gt;&lt;br /&gt;By implementing non-blocking I/O and using event handlers instead of threads, the logic for common servers and services could be made much simpler.&lt;br /&gt;&lt;br /&gt;He had a simple IRC server going, which was implemented in its entirety in JavaScript. I have done some of that before, having fiddled with 10gen's application server, but instead of living inside Rhino, node.js includes the Google V8 JavaScript VM, and exposes system services, such as streaming file operations and DNS lookup (non-blocking you see :).&lt;br /&gt;&lt;br /&gt;I could go on, and probably will, but for the record, node.js was the mount everest peak ascent, or maybe Roswell crash of JSConf. Nothing will be the same ever again. But in a good way.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sww-9ZcpQ8I/AAAAAAAAAeY/iVZNXYBNMAU/s1600/IMAG0045.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/Sww-9ZcpQ8I/AAAAAAAAAeY/iVZNXYBNMAU/s320/IMAG0045.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And the partying was excellent. I finally got to met the Uxebu Dojo folks, including Nikolai Onken (@nonken), PHP, github and jQuery people, including @paulca and @furf (who just had reinvented deferred's (something I've never done)) and lots and lots of other people, champion drinkers one and all.&lt;br /&gt;&lt;br /&gt;Almost noone managed to get hit by quick bicycle ladies in the early morning, and most of us got some sleep between the two conference days, but it was a total blast. I had also a small request from @frebro who has designed my business cards - could I possibly take a photo of them in a cool setting?&amp;nbsp;Not to let him down I shot them together with both Remy Sharp and&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SwxD3e3S_tI/AAAAAAAAAeg/gMGn8CTWZO0/s1600/IMAG0049.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SwxD3e3S_tI/AAAAAAAAAeg/gMGn8CTWZO0/s320/IMAG0049.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Douglas Crockford, who were&amp;nbsp;nice&amp;nbsp;enough to lend their star&amp;nbsp;quality&amp;nbsp;to my nefarious purposes.&lt;br /&gt;&lt;br /&gt;The day I was travelling home, on Monday, I had planned to do some general shopping four hours before the plane should lift, and then take a quick taxi to the airport some two hour later. &amp;nbsp;Little did I know that this specific Monday was the 20 year celebration of the fall of the Berlin wall, unification and so on. The traffic stood practically still. it took me nearly all of the time I had to get to the airport in time.&lt;br /&gt;&lt;br /&gt;I arrived home late in the evening, fully aware that I was leaving for Moscow 10.20 the day after. but more of that in another blog post.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxE1yAiGk4I/AAAAAAAAAfA/kjH1Wr9QLLA/s1600/jsconf_eu_2009_rocknroll.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SxE1yAiGk4I/AAAAAAAAAfA/kjH1Wr9QLLA/s640/jsconf_eu_2009_rocknroll.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And that's me in the middle. The long-haired, thin guy without a beard.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-2191889239856230108?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/2191889239856230108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=2191889239856230108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2191889239856230108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2191889239856230108'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/11/german-connection.html' title='The German Connection'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SwwryaMeKFI/AAAAAAAAAd4/iicv468NCkA/s72-c/IMAG0031.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-7995977542984583030</id><published>2009-11-08T04:35:00.000-08:00</published><updated>2009-11-08T04:35:12.337-08:00</updated><title type='text'>My JSConf presentation</title><content type='html'>So, still a bit tired from yesterdays awesome Nokia-sponsored party at Homebase in Berlin, I managed to survive my presentation on dojox.gfx, cross-browsed native 2D graphics. I got a lot of comments from people afterwards that they had no idea that this existed, which made me even happier for my subject choice.&lt;br /&gt;&lt;br /&gt;And without further ado, here's the slides:&lt;br /&gt;&lt;iframe src="http://docs.google.com/present/embed?id=dfxgjqrf_454cf36hjw7" frameborder="0" width="410" height="342"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-7995977542984583030?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/7995977542984583030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=7995977542984583030' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7995977542984583030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7995977542984583030'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/11/my-jsconf-presentation.html' title='My JSConf presentation'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-3942780614431747548</id><published>2009-10-16T06:09:00.000-07:00</published><updated>2009-10-16T06:09:14.435-07:00</updated><title type='text'>Yak Coiffures</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.junglewalk.com/animal-pictures/503/Yak-10066.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="199" src="http://www.junglewalk.com/animal-pictures/503/Yak-10066.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I am a very emotional and 'colorful' person and tend to rant quite a lot about things that I deem important. Lots of those happens to fall inside an body of supposed knowledge called 'software engineering'.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I am often talking about the importance to find ways to cut down the time being spent when developing a program that is not actual programming. Currently, I'm using 'find . -exec grep ..' in various parts of various repositories trying to understand how server-side templating is causing subtle bugs in a pedestrian, yet important web service, for a customer.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;But never mind that. What I want to write about today is a simple rule to follow if you want to weigh your language and/or platform of choice in terms of complexity.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;Assertion&lt;/b&gt;: Every step that produces an intermediate file creates complexity.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;Example&lt;/b&gt;: A compiler takes source code files and generates binary files.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;Why:&lt;/b&gt;&amp;nbsp;Each step that converts files between formats must be managed and maintained.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This is pretty hard to object to. Really. If you use Java, you need to manage compilation by either an ant file or maven, or perhaps a custom shell-script. These need to be maintained. They will not be maintained. This will lead to grief.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;If you need to package your generated files before deployment, the script for that needs to be maintained. See above.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;These operations are hard to duck, but that doesn't mean you shouldn't try. Every time you get one extra dot between yourself and the final, running application, that dot needs to be maintained. And that means documenting it, integrating it into other subsystems, referring to it, checking it in, adding it to a repository, what have you. Every point.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Also, frequently, they will become stop-blocks that makes it impossible to do things, until they guy that does packaging comes in, et.c.&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;One of the simpler ways to minimize yak-shaving of this kind is to adopt a scripting-language as your server-side language. Whether it is Groovy, SSJS, Ruby, Python, PHP or anything else is beside the point, because the main point is this;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;A scripting language gets compiled inside the VM.&lt;/li&gt;&lt;li&gt;A scripting language has at least two steps less complexity than a compiled one&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So whatever you do, for future generations of programmers: Never, ever again use a compiled language, for any project, for any reason.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Just Say No! :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-3942780614431747548?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/3942780614431747548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=3942780614431747548' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3942780614431747548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3942780614431747548'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/10/yak-coiffures.html' title='Yak Coiffures'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-5167481080884235270</id><published>2009-10-05T03:38:00.000-07:00</published><updated>2009-10-11T10:29:29.194-07:00</updated><title type='text'>Todays status of the Wave (unofficial) Invitation Queue Tracker</title><content type='html'>There's a Wave for people to track when their invites was sent out and when the recipients of the invites got it from Google. Since I have eight wandering invites myself, and a lot of people have asked about it, here's the current status of the tracking list:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;First Nomination Sent— First Invitation Received (delay DD:HH:MM)&lt;br /&gt;2009-09-30, 16:30 UTC — 2009-10-01, 08:20 UTC (00:15:50)&lt;br /&gt;2009-09-30, 17:30 UTC — 2009-10-01, 04:20 UTC (00:10:50)&lt;br /&gt;2009-09-30, 20:43 UTC — 2009-10-01, 08:44 UTC (00:12:01)&lt;br /&gt;2009-10-01, 02:00 UTC — 2009-10-01, 23:30 UTC (00:21:30)&lt;br /&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:07 UTC (00:19:07)&lt;br /&gt;2009-10-01, 04:00 UTC — 2009-10-01, 22:07 UTC (00:18:07)&lt;br /&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:00 UTC (00:19:00)&lt;br /&gt;2009-10-01, 04:30 UTC —&lt;br /&gt;2009-10-01, 05:10 UTC —&lt;br /&gt;2009-10-01, 05:30 UTC —&lt;br /&gt;2009-10-01, 06:45 UTC —&lt;br /&gt;2009-10-01, 06:59 UTC —&lt;br /&gt;2009-10-01, 07:00 UTC —&lt;br /&gt;2009-10-01, 07:15 UTC —&lt;br /&gt;2009-10-01, 09:00 UTC —&lt;br /&gt;2009-10-01, 10:00 UTC —&lt;br /&gt;2009-10-01, 11:45 UTC —&lt;br /&gt;2009-10-01, 13:30 UTC —&lt;br /&gt;2009-10-01, 16:30 UTC —&lt;br /&gt;2009-10-01, 16:40 UTC — &lt;br /&gt;2009-10-01, 18:00 UTC —&lt;br /&gt;2009-10-02, 15:00 UTC —&lt;br /&gt;2009-10-03, 00:30 UTC —&lt;br /&gt;2009-10-04, 18:55 UTC —&lt;br /&gt;&lt;br /&gt;[UPDATE 2009-10-6]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: bold;"&gt;First Nomination Sent— First Invitation Received (delay DD:HH:MM)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30, 16:30 UTC — 2009-10-01, 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30, 17:30 UTC — 2009-10-01, 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: Helvetica, sans-serif;"&gt;2009-09-30, 20:43 UTC — 2009-10-01, 08:44 UTC (00:12:01)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 02:00 UTC — 2009-10-01, 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01, 03:00 UTC — 2009-10-01, 23:53 UTC (00:20:53)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 05:10 UTC —&lt;span style="background-color: yellow;"&gt; 2009-10-06, 06:27 UTC (05:01:17)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 05:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 06:45 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 06:59 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:00 UTC —&lt;span style="background-color: yellow;"&gt; 2009-10-06, 06:45 UTC (5 days)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:15 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 09:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 10:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 11:45 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01, 13:20 UTC —&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;br class="AK" contenteditable="false" style="background-color: #ffd0d0; text-decoration: line-through;" /&gt;&lt;/span&gt;&lt;/span&gt;2009-10-01, 13:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01, 15:30 UTC —&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 16:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 16:40 UTC — &lt;span style="background-color: yellow;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 18:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-02, 14:00 UTC —&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02, 15:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03, 00:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04, 18:55 UTC —&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;[Update 3 2009-10-06 8.28pm CET+1]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: bold;"&gt;First Nomination Sent— First Invitation Received (delay DD:HH:MM)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30, 16:30 UTC — 2009-10-01, 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30, 17:30 UTC — 2009-10-01, 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: Helvetica, sans-serif;"&gt;2009-09-30, 20:43 UTC — 2009-10-01, 08:44 UTC (00:12:01)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 02:00 UTC — 2009-10-01, 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 03:00 UTC — 2009-10-01, 23:53 UTC (00:20:53)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:30 UTC —&lt;span style="background-color: yellow;"&gt; 2009-10-06, 01:31 UTC (4.9 days)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 05:10 UTC — 2009-10-06, 06:27 UTC (05:01:17)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 05:30 UTC — 2009-10-06, 07:00 UTC (&lt;span style="background-color: yellow;"&gt;0&lt;/span&gt;5&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt; days&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;:&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;01:30&lt;/span&gt;)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01, 06:35 UTC —&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 06:45 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 06:59 UTC —&lt;span style="background-color: yellow;"&gt;2009-10-06, 07:44 UTC (05:00:45)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:00 UTC — 2009-10-06, 06:45 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:00 UTC — 2009-10-06, 07:00 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:15 UTC — 2009-10-06, 07:32 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01, 08:10 UTC — 2009-10-06. 05:56 UTC (04:21:46) &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 09:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 10:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 11:45 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 13:20 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 13:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 15:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 16:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 16:40 UTC —  &lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 18:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02, 14:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02, 15:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03, 00:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04, 18:55 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-06, 10:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-06, 12:55 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;-----&lt;br /&gt;&lt;br /&gt;[Update 2 2009-10-06]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: bold;"&gt;First Nomination Sent— First Invitation Received (delay DD:HH:MM)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30, 16:30 UTC — 2009-10-01, 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30, 17:30 UTC — 2009-10-01, 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: Helvetica, sans-serif;"&gt;2009-09-30, 20:43 UTC — 2009-10-01, 08:44 UTC (00:12:01)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 02:00 UTC — 2009-10-01, 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 03:00 UTC — 2009-10-01, 23:53 UTC (00:20:53)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:00 UTC — 2009-10-01, 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 04:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 05:10 UTC — 2009-10-06, 06:27 UTC (05:01:17)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 05:30 UTC — 2009-10-06, 07:00 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 06:45 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 06:59 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:00 UTC — 2009-10-06, 06:45 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:00 UTC — 2009-10-06, 07:00 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 07:15 UTC — 2009-10-06, 07:32 UTC (5 days)&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 09:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 10:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 11:45 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 13:20 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 13:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 15:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 16:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 16:40 UTC —  &lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01, 18:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02, 14:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02, 15:00 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03, 00:30 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div class="simulated-li bullet-type-0" style="display: list-item; list-style-position: outside; list-style-type: disc; margin-bottom: 0px; margin-left: 17px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04, 18:55 UTC —&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;[Update 2009-10-07]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: bold;"&gt;First Nomination Sent—First Invitation Received (delay DD:HH:MM)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 16:30 UTC — 2009-10-01 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 17:30 UTC — 2009-10-01 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 20:43 UTC — 2009-10-01 08:44 UTC (00:12:01)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 02:00 UTC — 2009-10-01 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:30 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:10 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:30 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:45 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:59 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:00 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:15 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 08:00 UTC — 2009-10-07 04:49 UTC (05:20:49)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — 2009-10-06 18:00 UTC (05:11:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 10:00 UTC — 2009-10-07 04:13 UTC (0&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;5&lt;/span&gt;:18:13&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 11:45 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 12:00 UTC — 2009-10-07 06:30 UTC (05:18:30)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 13:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:40 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 18:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 23:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02 15:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03 00:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04 18:55 UTC — &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[Update 2009-10-08]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: bold;"&gt;First Nomination Sent—First Invitation Received (delay DD:HH:MM)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 16:30 UTC — 2009-10-01 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 17:30 UTC — 2009-10-01 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 20:43 UTC — 2009-10-01 08:44 UTC (00:12:01)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 02:00 UTC — 2009-10-01 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:30 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:10 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:30 UTC — &lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;2&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;009-10-06 07:00 UTC (05:01:30)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 06:35 UTC — 2009-10-07 16:19 UTC (06:09:44)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:45 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:59 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:00 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:15 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 08:00 UTC — 2009-10-07 04:49 UTC (05:20:49)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — 2009-10-06 18:00 UTC (05:11:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 10:00 UTC — 2009-10-07 04:13 UTC (0&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;5&lt;/span&gt;:18:13&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 11:45 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 12:00 UTC — 2009-10-07 06:30 UTC (05:18:30)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 13:30 UTC —&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt; &lt;/span&gt;&lt;span style="background-color: yellow;"&gt;2009-10-07 04:55 UTC (05:15:25)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:40 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 18:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 23:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02 15:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03 00:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04 18:55 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;-----&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;[Update 2009-10-09]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 16:30 UTC — 2009-10-01 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 17:30 UTC — 2009-10-01 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 20:43 UTC — 2009-10-01 08:44 UTC (00:12:01)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 02:00 UTC — 2009-10-01 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:30 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;br class="AK" contenteditable="false" style="background-color: #ffd0d0; text-decoration: line-through;" /&gt;&lt;/span&gt;&lt;/span&gt;2009-10-01 05:10 UTC — &lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;2&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;009-10-06 05:33 UTC (05:00:23)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:30 UTC — 2009-10-06 07:00 UTC (05:01:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:35 UTC — 2009-10-07 16:19 UTC (06:09:44)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:45 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:59 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:00 U&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;TC — ?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;T&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;C — ?&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:15 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 08:00 UTC — 2009-10-07 0&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;6&lt;/span&gt;:49 UTC (05:&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;20&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;1&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;8&lt;/span&gt;:49)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — 2009-10-06 18:00 UTC (05:11:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 10:00 UTC — 2009-10-07 04:13 UTC (05:18:13)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 10:?? UTC — 2009-10-08 ??:?? UTC (07:??:??)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 11:45 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 12:00 UTC — 2009-10-07 06:30 UTC (05:18:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 13:30 UTC — 2009-10-07 04:44 UTC (05:15:15)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 13:30 UTC — 2009-10-07 04:55 UTC (05:15:25)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 14:30 UTC — 2009-10-09 04:00 UTC (07:13:30)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 16:00 UTC — 2009-10-09 01:30 UTC (07:09:30)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:40 UTC — &lt;span style="background-color: yellow;"&gt;2009-10-08 22:50 UTC (07:06:10)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 18:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;br class="AK" contenteditable="false" style="background-color: #ffd0d0; text-decoration: line-through;" /&gt;&lt;/span&gt;&lt;/span&gt;2009-10-01 19:30 UTC —&lt;span style="background-color: yellow;"&gt; 2009-10-09 01:17 UTC &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-01 21:00 UTC — 2009-10-09 00:55 UTC (07:03:55)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 23:00 UTC — &lt;span style="background-color: yellow;"&gt;2009-10-08 23:25 UTC (07:00:25)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;br class="AK" contenteditable="false" style="background-color: #ffd0d0; text-decoration: line-through;" /&gt;&lt;/span&gt;&lt;/span&gt;2009-10-02 15:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;"&gt;2009-10-02 21:00 UTC — 2009-10-09 01:25 UTC&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02 06:30 UTC &lt;span style="-webkit-user-modify: read-only;"&gt;&lt;span style="-webkit-user-modify: read-only; white-space: pre-wrap;"&gt;&lt;span style="background-color: #ffd0d0; text-decoration: line-through;"&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: yellow;"&gt;—&lt;/span&gt; &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03 00:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04 18:55 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div&gt;----------&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;[Update 2009-10-11]&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: small; line-height: 17px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: bold;" x="y"&gt;First Nomination Sent—First Invitation Received (delay DD:HH:MM)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 16:30 UTC — 2009-10-01 08:20 UTC (00:15:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 17:30 UTC — 2009-10-01 04:20 UTC (00:10:50)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-09-30 20:43 UTC — 2009-10-01 08:44 UTC (00:12:01)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 02:00 UTC — 2009-10-01 23:30 UTC (00:21:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:07 UTC (00:19:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 22:07 UTC (00:18:07)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:00 UTC — 2009-10-01 23:00 UTC (00:19:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 04:30 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:10 UTC — 2009-10-06 05:33 UTC (05:00:23)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 05:30 UTC — 2009-10-06 07:00 UTC (05:01:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:35 UTC — 2009-10-07 16:19 UTC (06:09:44)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:45 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 06:59 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:00 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 07:15 UTC — ?&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 08:00 UTC — 2009-10-07 06:49 UTC (05:18:49)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — 2009-10-06 18:00 UTC (05:11:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 09:00 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 10:00 UTC — 2009-10-07 04:13 UTC (05:18:13)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 10:?? UTC — 2009-10-08 ??:?? UTC (07:??:??)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 11:45 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 12:00 UTC — 2009-10-07 06:30 UTC (05:18:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 13:30 UTC — 2009-10-07 04:44 UTC (05:15:15)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 13:30 UTC — 2009-10-07 04:55 UTC (05:15:25)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 14:30 UTC — 2009-10-09 04:00 UTC (07:13:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:00 UTC — 2009-10-09 01:30 UTC (07:09:30)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 16:40 UTC — 2009-10-08 22:50 UTC (07:06:10)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 18:00 UTC — 2009-10-09 01:05 UTC &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 19:30 UTC — 2009-10-09 01:17 UTC &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 20:45 UTC — 2009-10-09 01:44 UTC (07:05:00)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 21:00 UTC — 2009-10-09 00:55 UTC (07:03:55)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-01 23:00 UTC — 2009-10-08 23:25 UTC (07:00:25)&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02 15:00 UTC — &lt;span style="background-color: yellow;" x="y"&gt;2009-10-10 08:00 UTC&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;" x="y"&gt;2009-10-02 15:30 UTC — 2009-10-11 14:30 UTC (08:23:00)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02 21:00 UTC — 2009-10-09 01:25 UTC&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-02 06:30 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-03 00:30 UTC —&lt;span style="background-color: yellow;" x="y"&gt; 2009-10-11 01:40 UTC (08:01:10)&lt;/span&gt; &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;" x="y"&gt;2009-10-03 04:45 UTC — 2009-10-11 00:45 UTC (08:20:00)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;2009-10-04 18:55 UTC — &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: yellow;" x="y"&gt;2009-10-07 16:44 UTC — ?&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;------------&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Note that this list is updated and maintained manually by people who want to share information, so I take no responsibility of the accuracy or completeness of the information in it. It does look like something hit the fan last Thursday which made everything stop invite-wise. My guess is that when whatever it is they're doing is finished, invites will start to appear again. &lt;br /&gt;&lt;br /&gt;I'll update this post whenever I get new info on the status of Wave invites.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-5167481080884235270?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/5167481080884235270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=5167481080884235270' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5167481080884235270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5167481080884235270'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/10/todays-status-of-wave-unofficial.html' title='Todays status of the Wave (unofficial) Invitation Queue Tracker'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4364172697675723701</id><published>2009-10-04T08:06:00.001-07:00</published><updated>2009-10-07T03:34:59.396-07:00</updated><title type='text'>GTUG Stockholm meeting 1/10 2009</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_rRWdAFxWBEM/Ssi6bYHHGiI/AAAAAAAAAdU/_f3qHN5pMN8/s1600-h/IMAG0015.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5388761933640309282" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/Ssi6bYHHGiI/AAAAAAAAAdU/_f3qHN5pMN8/s200/IMAG0015.jpg" style="cursor: hand; cursor: pointer; float: left; height: 134px; margin: 0 10px 10px 0; width: 200px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_rRWdAFxWBEM/Ssi6WrAQesI/AAAAAAAAAdM/srrJTdJrNHY/s1600-h/IMAG0014.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5388761852812491458" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/Ssi6WrAQesI/AAAAAAAAAdM/srrJTdJrNHY/s200/IMAG0014.jpg" style="cursor: hand; cursor: pointer; float: left; height: 134px; margin: 0 10px 10px 0; width: 200px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_rRWdAFxWBEM/Ssi6QUvwzeI/AAAAAAAAAdE/ChP4L1X228M/s1600-h/IMAG0013.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5388761743758511586" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/Ssi6QUvwzeI/AAAAAAAAAdE/ChP4L1X228M/s200/IMAG0013.jpg" style="cursor: hand; cursor: pointer; float: left; height: 134px; margin: 0 10px 10px 0; width: 200px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;This last &lt;span style="font-family: arial;"&gt;Thursday was incredible! I had hoped to get at least as many attendees as last time, but I got even more. I counted to 90 people sharp, but I might have missed one or two. Also, people lined up in front of the registration desk instead of bolting for the beer (as I would have). People were very nice, courteous and happy.  Even when Google's Serge LaChapelle was unable to connect to the projector and was forced to switch to a smaller panel-mounted TV.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;We got people from Bwin, Mindspring, Tieto, Skype, KTH, Skatteverket, Unibet and *lots* of other companies and organizations. Between the sessions we had discussions breaking out everywhere. Also interesting was that between 25-50% of the people present had done some or a lot of Android development, which only made the big announcement even nicer: Bwin Games AB will host GTUG Stockholm's Android Hackathon the 28/11. Details will be forthcoming during the coming week.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;The schedule for our second GTUG Stockholm meeting was as follows:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;17.30 - 18.00     Mingle. Register at the laptop.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;18.00 - 18.10     Presentation Ottoboni / Peter S.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;18.10 - 18.20     GTUG Stockholm news / pres.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;18.20 - 19.00     Johan Nilsson, Bwin; Android/iGlaset&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;19.00 - 19.30     Break   &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;19.30 - 20.00     Serge LaChapelle, Google, om Gmail Video Chat&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;20.00 - 20.30     Jacon Gyllenstierna, Enemy Unknown on OpenSocial&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;This was great since it cut my time talking down from pretty much the whole time, last time, to just presenting the event and the sepakers. Don't get me wrong, I love talking, but I feel that it is better for the community to have lots of different speakers with lots of different experiences.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;First off was Johan Nilsson, from Bwin, who presented two useful Android apps he had made; &lt;/span&gt;&lt;a href="http://markupartist.com/sthlmtraveling/"&gt;&lt;span style="font-family: arial;"&gt;STHLM Travelling&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: arial;"&gt; and &lt;/span&gt;&lt;a href="http://www.androlib.com/android.application.com-markupartist-iglaset-qnqA.aspx"&gt;&lt;span style="font-family: arial;"&gt;iGlaset&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: arial;"&gt;. We got some good practical examples on what to do (and not to do) when developing an Android app and lots of good pointers to resources.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;Then came Serge LaChapelle from Google Sweden, originally working for the Swedish company Marratech, which was bought by Google some years ago to use Marratech's technology to create what was to become Gmail video chat. Serge did a great presentation with a live video demonstration and dozens of technical questions asked by the attendees, like which was better of GMail chat and Skype (both have their strengths and weaknesses), How much overhead the new&lt;/span&gt;&lt;span style="font-family: arial;"&gt; &lt;/span&gt;&lt;span style="color: #333333; line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;H264/SVC codec demand (1-2% CPU tops), why they don't use SIP (since they build everything on top of Gmail chat and XMPP, it felt cumbersome to create a separate infrastructure. Google have apparently really good internal oomph for juggling XMPP (pusubhubbub anyone?)).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;Our last talk was Jacob Gyllenstierna from Enemy Unknown who did a great presentation on how OpenSocial works and how the cotnainer (web site) interacts with the OpenSocial apps. These guys are interesting because they are one of the few companies I know of that have created their own OpenSocial compatible platform (in Ruby, no less) and have OS applications created by the community which ties directly into their services. The also do consulting, if you have an OpenSocial project that you need developed. Normally I'd recommend myself, but these guys are just much tougher :).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;One of the more interesting things that was brought up over beers after the main talks was that several people wanted some more business-oriented information, like someone who has implemented Google Apps for an existing customer, or sales-oriented certfication for different Google Products. Google does have some certifications available, and more will be forthcoming, but I will take this to heart and try to have some more nuggets avilable for the business oriented Google Entepreneur next time. promise!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt;[Update: &amp;nbsp;More (and better.. ahem) pictures from @vilcans:&amp;nbsp;&lt;a href="http://www.flickr.com/photos/10185883@N05/sets/72157622370852645/"&gt;http://www.flickr.com/photos/10185883@N05/sets/72157622370852645/&lt;/a&gt; ] &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #333333; line-height: 18px;"&gt;&lt;span style="font-family: arial;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;1] Slides from Johan/Android&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;a href="http://docs.google.com/present/view?id=djszmqj_2d584vcdw"&gt;http://docs.google.com/present/view?id=djszmqj_2d584vcdw&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;2] Slides from Serge/GMail video chat&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre;"&gt;&lt;a href="http://docs.google.com/fileview?id=0BxFzwqvEUKapOTFiMjI1NTYtMjU2ZC00MDA1LTkxMDAtZGZiZGZhYThiMzdh&amp;amp;hl=en"&gt;http://docs.google.com/fileview?id=0BxFzwqvEUKapOTFiMjI1NTYtMjU2ZC00MDA1LTkxMDAtZGZiZGZhYThiMzdh&amp;amp;hl=en&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;3] Slides from Jacob/OpenSocial&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;a href="http://www.slideshare.net/jgyllenstierna/opensocial-gtug-stockholm-meeting-oct-1-2009"&gt;http://www.slideshare.net/jgyllenstierna/opensocial-gtug-stockholm-meeting-oct-1-2009&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4364172697675723701?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4364172697675723701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4364172697675723701' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4364172697675723701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4364172697675723701'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/10/gtug-stockholm-meeting-110-2009.html' title='GTUG Stockholm meeting 1/10 2009'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/Ssi6bYHHGiI/AAAAAAAAAdU/_f3qHN5pMN8/s72-c/IMAG0015.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6943546910458850792</id><published>2009-10-02T06:38:00.000-07:00</published><updated>2009-10-25T01:54:28.175-07:00</updated><title type='text'>Presenting at JSConf.eu</title><content type='html'>Wow! I will be presenting at JSConf, together with most of the really cool people I know. I'm really happy and proud to be chosen to attend this Battlestar Galactica Epic conference dedicated to just JavaScript, the best of the best. :)&lt;br /&gt;&lt;br /&gt;You can peer at the bearded fellow in the presentation abstract here (I'll talk about the dojox.gfx and dojox.charting cross-browser graphics packages); &lt;a href="http://jsconf.eu/2009/speaker/peter_svensson_-_using_dojoxgf.html"&gt;http://jsconf.eu/2009/speaker/peter_svensson_-_using_dojoxgf.html&lt;/a&gt;  but just in case, the text is copied below;&lt;br /&gt;&lt;br /&gt;Peter Svensson will give us deep insights into real-time 2D graphics in the browser.&lt;br /&gt;&lt;br /&gt;The Dojo Ajax Toolkit has a multitude of different features that help save time for the harried JavaScript developer. One of the most powerful and yet least known is the Canvas like dojox.gfx API, which adapts itself to the browser's 2D capabilities. It can use VML, SVG, Canvas and Silverlight, depending on what the browser supports. On top of the dojox.gfx library is also built the dojox.charting API which leverages the cross-browser graphics of dojox.gfx to provide snappy, versatile, themable and configurable charting with tooltips, dynamic scaling and general eventing.&lt;br /&gt;&lt;br /&gt;Peter's Bio&lt;br /&gt;Peter Svensson is an entrepreneur and Java developer turned Ajax and JavaScript evangelist.&lt;br /&gt;He is a contributor to the Dojo Ajax Toolkit and author of the book "Learning Dojo". When not talking at conferences, he's busy developing his company "Hermit Village" with competences ranging from Dojo, Android, and App Engine to OpenSocial, Layar and Google Friend Connect. He is also the organizer of the Scandinavian Web Developer Conferences and the Google Technology User Group for Stockholm, Sweden.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;What? There was an equally Epic Google technology User Group - Stockholm meeting last night, with over 90 people present. True, but this has been a hectic week and I really need to sleep first before attempting that post. Coming during the weekend though. Films at eleven. beep.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-6943546910458850792?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6943546910458850792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6943546910458850792' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6943546910458850792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6943546910458850792'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/10/presenting-at-jsconfeu.html' title='Presenting at JSConf.eu'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-2062327241222451777</id><published>2009-09-17T03:46:00.000-07:00</published><updated>2009-09-28T12:19:35.253-07:00</updated><title type='text'>jQuery workshop in Stockholm with Remy Sharp</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://remysharp.com/images/remysharp-2009.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://remysharp.com/images/remysharp-2009.jpg" border="0" alt="" /&gt;&lt;/a&gt;For the first time in Stockholm, Sweden. Hermit Village in conjunction with Left Logic proudly presents a 1-day workshop with the acclaimed jQuery contributor &lt;b&gt;Remy Sharp&lt;/b&gt;.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The workshop will be held &lt;b&gt;October 22&lt;/b&gt; at DFS, &lt;b&gt;Vasagatan 8-10 in Stockholm&lt;/b&gt;, right across the central station.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Remy Sharp is a world-class JavaScript and jQuery guru who not only speaks at, ut organizes his own conferences.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Read more about him &lt;a href="http://remysharp.com/"&gt;here&lt;/a&gt;, and check out the upcoming Full Frontal JavaScript conference &lt;a href="http://2009.full-frontal.org/"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Workshop details:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" color: rgb(153, 153, 153); line-height: 19px; font-family:helvetica, arial, sans-serif;"&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;You'll be learning jQuery from a practical point of view: what you can use out of the box to quickly get effects and interaction live in to your wireframes, prototypes and web sites. The aim *isn't* to teach you JavaScript, but to teach you what you need to know to be able to leverage jQuery to do your bidding.&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;The workshop will cover topics such as:&lt;/span&gt;&lt;/p&gt;&lt;ul style="margin-top: 0px; margin-right: 23px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 1em; vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; list-style-type: none; list-style-position: initial; list-style-image: initial; float: left; background-position: initial initial; "&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 16px; vertical-align: baseline; background-image: url(http://2009.dconstruct.org/images/bullet.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; line-height: 1.5em; background-position: 0px 0.5em; "&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;JavaScript &amp;amp; debugging basics: how to fake it as a JavaScripter&lt;/span&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 16px; vertical-align: baseline; background-image: url(http://2009.dconstruct.org/images/bullet.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; line-height: 1.5em; background-position: 0px 0.5em; "&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Progressive enhancement &amp;amp; Graceful degradation - what's what&lt;/span&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 16px; vertical-align: baseline; background-image: url(http://2009.dconstruct.org/images/bullet.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; line-height: 1.5em; background-position: 0px 0.5em; "&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;jQuery: how do bend the DOM to your will&lt;/span&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 16px; vertical-align: baseline; background-image: url(http://2009.dconstruct.org/images/bullet.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; line-height: 1.5em; background-position: 0px 0.5em; "&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Effect and animations - things that go whizz bang!&lt;/span&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 16px; vertical-align: baseline; background-image: url(http://2009.dconstruct.org/images/bullet.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; line-height: 1.5em; background-position: 0px 0.5em; "&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Ajax: it's even simpler than you think&lt;/span&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 16px; vertical-align: baseline; background-image: url(http://2009.dconstruct.org/images/bullet.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; line-height: 1.5em; background-position: 0px 0.5em; "&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Using jQuery UI for instant widgets, for zero work&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;The workshop audience is aimed at beginners to intermediates - and it's very hands on!&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;We'll start with covering the basics of JavaScript so that you have a good grounding and you can fake your way through coding. This will include anonymous functions, scope, context (what 'this' means in different places) and objects. Then we'll move on to tabbing systems, how they work, how to recognise them when they don't look like tabbing systems, and then on to the juicier stuff such as effects, Ajax and jQuery UI.&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;To register for this workshop, mail organizer Peter Svensson at &lt;a href="mailto:psvensson@gmail.com"&gt;psvensson@gmail.com&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;The price for this one-day event is&lt;b&gt; €495&lt;/b&gt;, but if you register before&lt;i&gt;&lt;b&gt; October 1&lt;/b&gt;&lt;/i&gt;, you will get an early-bird price at &lt;b&gt;€&lt;/b&gt;&lt;b&gt;400&lt;/b&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Also, BYOL (Bring your own laptop)&lt;/span&gt;&lt;/p&gt;&lt;p   style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.385em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial;  vertical-align: baseline; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background- clear: left; background-position: initial initial; font-size:1em;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Cheers,&lt;br /&gt;PS&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-2062327241222451777?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/2062327241222451777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=2062327241222451777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2062327241222451777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2062327241222451777'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/09/jquery-workshop-in-stoclholm-with-john.html' title='jQuery workshop in Stockholm with Remy Sharp'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-8185391749445137677</id><published>2009-09-16T01:46:00.000-07:00</published><updated>2009-09-28T12:20:01.908-07:00</updated><title type='text'>Striking our on my own - while remaining employed</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/8/86/Elton_John_-_Goodbye_Yellow_Brick_Road.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://upload.wikimedia.org/wikipedia/en/8/86/Elton_John_-_Goodbye_Yellow_Brick_Road.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;b&gt;Into the loking-glass&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After a long period of medium-sized soul searching, I am finally starting my own company.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What's funny is that I'm not quitting the company I work for, Nethouse, which I had fully expected when drawing the plans for my new venture.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have been employed by Nethouse (a Swedish consultancy firm) for over four years and I even though the colleagues that have left the company, have done so on amicable terms, starting what could be interpreted as a competitor (...) made me take measures to be able to jump ship very soon, as I could not count on applause from my boss and current company.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Unexpected support&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, what happened was that we had a complete mind-opener of a conversation. Far from being cross (I would suspect that my boss had anticipated some sort of move on my part), he was very reasonable and suggested that I continue to work part-time for Nethouse, but in a business development position instead, as they/we are moving towards a new positioning in the market (which I wholly support and am actually quite exited about).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Coopetition&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So will I or won't I compete with my current/former company? Well, for over two years I have been the only one in the company with an inclination and competency in front-end web development, since Nethouse has vey much been a .Net shop with some Java inroads - the classical consultancy company, in fact.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So my new clients are mostly international, which I have garnered through this blog and various conference appearances during the last years. Our clientele don't really overlap, so to speak. On the other hand, my expert knowledge is handy for some local customers as well, even if there is not yet so much demand for cutting-edge Dojo front-end applications in Sweden.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Happy start&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All in allm this only proves that you can never predict what will happen when you make a sea-change, neither who will be your friend.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So on November 1, I will start on my new company (tentatively named Hermit Village - after the Monty Python skit, and the interconnectedness of actually single individuals that the Internet provides), working 75% with my newfound customers and the rest with secret plan X for Nethouse world domination (it's large, we'll fit all of us :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And by them, I promise to cut down to only ten or so side-projects. Really!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&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/7919361321436933137-8185391749445137677?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/8185391749445137677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=8185391749445137677' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8185391749445137677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/8185391749445137677'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/09/striking-our-on-my-own-while-remaining.html' title='Striking our on my own - while remaining employed'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-3121433761922774611</id><published>2009-09-07T01:37:00.000-07:00</published><updated>2009-09-08T04:51:28.696-07:00</updated><title type='text'>First GTUG Stockholm meeting!</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SqTH7w2EuGI/AAAAAAAAAcU/j3CxKs4TUyw/s1600-h/IMAG0001.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SqTH7w2EuGI/AAAAAAAAAcU/j3CxKs4TUyw/s320/IMAG0001.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5378643684525127778" /&gt;&lt;/a&gt;&lt;br /&gt;After lots of preparation, sleepless nights and thrown in as a happy spanner in the midst of all other activities, the first GTUG Stockholm meeting managed to fly off the runway without as much as a single missing wing or fuselage. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:Arial, Verdana, sans-serif;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;I was on place at Ottoboni as early as possible, since I have had many years as an instructor, wise to the ways simple things can take a long time to fix in the last minute.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Ottoboni have floor 12 and 13 in a very 1998 kind of building. Lots of glass, space and white, wide tables. Nice.&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's the final schedule for the evening:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="  ;font-family:Arial, Verdana, sans-serif;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;17.30 - 18.00     Mingle. Getting machinery to work :)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;18.00 - 18.10     Presentation Ottoboni /Google /Peter S.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;18.10 - 18.45     Google Code. APIs and stuff!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;18.45 - 19.15     Beer break (and some food)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;19.15 - 19.45     Google Wave presentation / demo&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;19.45 - 20.00 &lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Break   &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;20.00 - 20.30     Android development (AR)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;20.30 - Later      Chat, breakout sessions, beer.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Me and Markus from Ottoboni dashed back and forth to aarrange chairs, tables, cables and whatnot. On a ussgenstion form Markus I created a quick Google doc which I shared with him, and which he opened on a portable inside the enterance to let people register themselves, and it worked! Or it worked somehwat, because it wasn't easy to find the portable among all the people pouring in, but we got almost 40 people registering themselves as GTUGers among somwhere above 60 attendees, which quite OK in my book.&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SqTItX5ZqvI/AAAAAAAAAcc/YxbaZouIeh0/s1600-h/IMAG0003.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SqTItX5ZqvI/AAAAAAAAAcc/YxbaZouIeh0/s320/IMAG0003.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5378644536821656306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="  ;font-family:Arial, Verdana, sans-serif;"&gt;Above sits half of our participants, waiting for me to stop taking pictures and get on with it already.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="  ;font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SqTI1mNWfiI/AAAAAAAAAck/aYHbYFUxiag/s1600-h/IMAG0004.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SqTI1mNWfiI/AAAAAAAAAck/aYHbYFUxiag/s320/IMAG0004.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5378644678102384162" /&gt;&lt;/a&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;We got Daniel Rytterstöm from Google Sweden (right) to annoint our first meeting, and Markus Blomkvist from ottoboni (left) welcomed everyone to the posh venue. In between them we see a cautious-looking local JavaScript hero Robert Nyman.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We were actually supposed to have an Engineer from Google to speak on some topics, but he had to pull the plug on some Gmail servers (just joking! :) so I had to speak for the entire event (as usual), but at least I couldn't complain over the quality of the speakers..&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;During the evening I took a poll on what theme people would like to have for our upcoming (TBA) hackathon, and I must admit I was siltenly rooting for a Wave hackathon, the overwhelming majority opted for an Android hackathon (which is really, really OK as well, naturally) and we're now trying to uncover the identity of a Google Sweden employee who is a truly savvy Android developer and can help me talk between hacks at that event. more to come on that one.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I want to thank Ottoboni for being such gracious hosts, for Google Sweden for delivering such large quantities of beer and wonderful, varied, small sandwhiches (watchamacallits) to the event, and of course all of you who attended. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Måns Jonasson (who helped me demo Wave) have some variable quality videos from the event taken from his non-Android mobile phone, and can be viewed here; &lt;a href="http://bambuser.com/channel/MungoBBQ/broadcast/256538"&gt;http://bambuser.com/channel/MungoBBQ/broadcast/256538&lt;/a&gt; (Watch out for that bearded fellow in the last one)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The morning after, I was whisked off to a two-day conference, so I felt I missed a lot of tweets and other commentary, but in all I felt that the event was well received. The next time will be &lt;b&gt;October 1st&lt;/b&gt;, and I will put up a LinkedIn event for that as well, and mail out to all of you who registered in good time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also note that all GTUGers can get up to 40% discounts on any Oreilly, Apress or Packtpub book, if you mail me about it (I have teh s3cret c0de), since GTUG Stockholm (thanks to Stephanie at Google) is a User group for all three publishers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[Update: Ottoboni has a post up at their site with some more info and way better pictures: &lt;a href="http://www.ottoboni.se/sv/Bloggen/Sveriges-forsta-Google-Technology-User-Group/"&gt;http://www.ottoboni.se/sv/Bloggen/Sveriges-forsta-Google-Technology-User-Group/&lt;/a&gt;]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&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/7919361321436933137-3121433761922774611?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/3121433761922774611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=3121433761922774611' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3121433761922774611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3121433761922774611'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/09/first-gtug-stockholm-meeting.html' title='First GTUG Stockholm meeting!'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SqTH7w2EuGI/AAAAAAAAAcU/j3CxKs4TUyw/s72-c/IMAG0001.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4596681289443866991</id><published>2009-08-29T02:50:00.000-07:00</published><updated>2009-08-29T04:52:17.611-07:00</updated><title type='text'>The Joys of Android</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SpkHmj5Na6I/AAAAAAAAAb0/JJAeeSyWEMA/s1600-h/device.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SpkHmj5Na6I/AAAAAAAAAb0/JJAeeSyWEMA/s320/device.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5375335989295016866" /&gt;&lt;/a&gt;&lt;b&gt;Positive feedback:&lt;/b&gt;&lt;div&gt;&lt;br /&gt;Instead of continuing to bash the flotsam of obsolete programming languages like I did last week, today I'm going to describe a really nice experience I just had in the programming department instead; Developing an Andoid application.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Enter the Client:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The specification that my client had was clear; He wanted a demo/PoC of a smartphone application (iPhone or Android) that among other things first showed a Google map of an area with some markers on it, and when one of the markers was clicked, it would switch to augmented reality mode (AR) to display the markers in an overlay on top of what the camera in the phone dislay, so that people can orient towards points of interests in 3D using local landmarks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And it was supposed to be done in under ten days. It sounded crazy hard to do, and at first I asked a couple of iPhone developers I knew if they could take it on, but they had their hands full, so I did some more research to see if I could do it myself.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Layar to the rescue:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It turned out that a very interesting Dutch company called &lt;a href="http://layar.com/"&gt;Layar&lt;/a&gt;, which develops an Augmented Reality service by the same name. That's right, it's a service. That means that if you can get your user to download their (free) app from the Android appstore &lt;a href="http://layar.uservoice.com/pages/20979-general"&gt;(iPhone support is coming soon, as a high priority)&lt;/a&gt;, you can create your own headless REST service which pop up among available AR layers to choose from. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://layar.com/catalog/ContentCatalog.html"&gt;Here's a list&lt;/a&gt; of the currently created layers. If you get a quick idea of what you could use an AR layer for, it's probably already been implemented :) so check there first.&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SpkIf6SHinI/AAAAAAAAAb8/Rq9d7UHtREg/s1600-h/device5+(copy).png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SpkIf6SHinI/AAAAAAAAAb8/Rq9d7UHtREg/s320/device5+(copy).png" border="0" alt="" id="BLOGGER_PHOTO_ID_5375336974557612658" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That means that 'all' I had to do was to create an android app that showed a map, and when clicked started the Layar app and pointed it to a special layer that I could create once I got my deveoper keys from Layar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Luckily, I had just formed the Stockholm GTUG( Google Technology User Group), which among other things was eligible to receive review copies of books from O'reilly, Pragmatic Press and others, so I had several good Android books to browse through. Then I went out and bought myself a HTC Magic with extra toppings and flat rate internet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;SDK impression:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I used (naturally) Eclipse 3.4 with the spanking new 1.5v3 Android SDK which contained Google API support for maps and other things. It was very easy to get started, despite using Java. The APIs for various funcitons were mostly sane, meaning that they could be used without creating four extra levels of classes and the methods you really wanted to have for convenience sake were there, instead of missing so you had to write them yourself (classic Java). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SpkLxcOQnXI/AAAAAAAAAcE/1gPzfv3T_js/s1600-h/device7+(copy).png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SpkLxcOQnXI/AAAAAAAAAcE/1gPzfv3T_js/s320/device7+(copy).png" border="0" alt="" id="BLOGGER_PHOTO_ID_5375340574260895090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;My first try in developing the app used an internal webkit inside an Android app. I was really happy to find examples on how to do this in one of the books, since that meant that I could focus on effective development (in JavaScript) for a brwoser pretending to be a 'desktop' application.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I managed very quickly to embed a Google map in the 'internal' web page, and writing a shim that let me call Java methods from JS (and vice versa) was very straightforward.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The downside of this method was that (at least for the HTC Hero) it took over 15 seconds for the app to initialize. If tha map hadn't been the first screen, I could probably have used a background thread for webkit initialization, but I ended up ditching the browser method - despite its clear advantages.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead I found a View (A view is a kind of layout manager, which organizes other content for the Android app)  called the MapView. I recommend following&lt;a href="http://developer.android.com/guide/tutorials/views/hello-mapview.html"&gt; the 'official' example &lt;/a&gt;(which has a few typos in it), here. This view demanded a special application key from google code (&lt;a href="http://code.google.com/android/add-ons/google-apis/mapkey.html"&gt;You can get one here)&lt;/a&gt;, which turns out to be a critical piece to do right. The problem is not obtaining the key, but to use the right public key from you SDK when applying for one. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Killer Keys:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There's a default keystore created for you when you install the Android SDK which has no password, and using the signature of that results in a developer key which only works inside a debug version of an app, so if you generated an .apk file and sign it using another keystore, the maps API key in your app will not work.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SpkO3bW0wmI/AAAAAAAAAcM/0mexnVn4AVU/s1600-h/device2+(copy).png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SpkO3bW0wmI/AAAAAAAAAcM/0mexnVn4AVU/s320/device2+(copy).png" border="0" alt="" id="BLOGGER_PHOTO_ID_5375343975642481250" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is really simple and sound straightforward when I write it here, but when you're developing, it is very simple to forget to change codes and/or to forget which key signature to use when applying for one. This in itself would be very simple to spot &lt;i&gt;if you get an error&lt;/i&gt;, which you don't.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What happens is that your markers show up at the correct place in the mapview, but the map is clean, consisting of just a thin grid of grey lines. The first times you see this, you immediately think that you have made a coding error, since the mapview do actually force you to create extra classes, implement extra methods and do the work that you really needed support for yourself - in a true, classical Java style. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if you ever get those gray lines - I'd give you a 90% chance of having used the wrong keys somwhere. Just so you know, OK?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once I got the mapview working, I needed to trap the screenpresses, so I could launch the Layar app.  This is where Android started to shine. For every application in Android you can define different 'Intents' which are for all effective purposes 'Events'. So in an (ugh) external XML file, you define which intent string your app listens for and which class and method handles those intents.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Effective use of  Events:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This means that each an devery app has an intent that starts it. This also means that it's possible to define intents that the app traps and handles before it has even been started (and which can start it on demand). I used this as a finishing touch, letting the app listen to incoming SMS, searching for a keyword. When it found the keywork it sent a message to the intent that started the main application. Worked like a charm :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I also used this method when starting the Layar app. By browing through the log that I got from a shell that displayed ./adb logcat from my physical device (The HTC Hero) over USB, I saw the classname for the Layar App (com.sprx.layar), which I then used to create a new activity object, like this;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;    &lt;span class="Apple-style-span"  style="color:#000099;"&gt;Intent intent = new Intent();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;    intent.setClassName("com.sprx.layar", "com.sprx.layar.Main");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;    ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;    this.startActivity(intent);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And that's how an app start's other apps in Android. Pretty simple, isn't it?&lt;/div&gt;&lt;div&gt;Layar works like this; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) You apply for a developer key &lt;a href="http://dev.layar.com"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;2) You login to Layar and create and name you first layer.&lt;/div&gt;&lt;div&gt;3) In the new and named layer, you point out a lot of things, but most important is the url that this new layer will get its POIs (Points Of Interests, for you non-mapping geeks ) from. &lt;/div&gt;&lt;div&gt;4) You implement the REST based service at the required url.&lt;/div&gt;&lt;div&gt;5) You download a special developer version of Layar, where you can enter you developer key and which will show all your dev layers in a specific tab inside the app.&lt;/div&gt;&lt;div&gt;6) Load your layer. Scream, curse, despair, check logs, read up on coordinates. Check in Google Earth. repeat.&lt;/div&gt;&lt;div&gt;7) Success!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;REST assured:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Item number (4) here sounds ominous, but it really isn't. I naturally implemented the service in Googel App Engine vanilla python. It took all of two hours to register, create, upload and get something visible, and part of that time was dinner. There was two reasons that this went fast; a) I was only doing a demo, so all POIs I returned was hardwired into the source code, b) you really only need to implemenet GET, since Layar only ever (for now :-P ) reads info from your backend.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had a lot of small troubles converting coordinates and making them show correctly in my layer, and almsot all of them was due to rounding errors or plain stupidity on my part. When I started checking all coordinates I sent back in Google Earth (where you can just enter degree coordinates into the search field) and I found myself north of Scotland or in Dubai, I had an easier time finding my bugs. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I managed to deliver the PoC app on record time, fixing design erros quickly due to the web-based nature of both App Engine and the Layaer adminstrative interface. I'm actually a bit on an Augmented Reality tear at the moment and will present and demo the app on out first GTUG meeting next Thursday. Now for some more coding :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&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/7919361321436933137-4596681289443866991?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4596681289443866991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4596681289443866991' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4596681289443866991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4596681289443866991'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/08/joys-of-android.html' title='The Joys of Android'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SpkHmj5Na6I/AAAAAAAAAb0/JJAeeSyWEMA/s72-c/device.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-2283402312685026630</id><published>2009-08-16T01:24:00.000-07:00</published><updated>2009-08-16T08:48:57.037-07:00</updated><title type='text'>Software Complexity in Practice</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SofFg0tO5WI/AAAAAAAAAbM/_pXgyWvpP34/s1600-h/butterflyex270.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 270px; height: 270px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SofFg0tO5WI/AAAAAAAAAbM/_pXgyWvpP34/s320/butterflyex270.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5370478248357455202" /&gt;&lt;/a&gt;I had a minor epiphany last week, but have been having too much to do until now to blog about it. It revolved around the now quite common (for those who have made the effort to learn a second (or third) language properly) question:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Why does x takes longer to implement in Java than in my-scripting-language-of-choice&lt;my&gt;?&lt;/my&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And what goes for implementation also goes for maintaince, et.c.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having had the opportunity (..) for the last two months (OK, I had a four week vacation in there somwhere :) to work with a system that was based on using Maven for everything server-side, it struck me how dangerous it is to use compiling languages at all. Listen to this;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The services ( that I am working with, in Java) are generic to a fault, and use Spring applicationContext.xml files to hold specific information such as hostnames, DAOs and a host of other stuff.  Now, I have nothing in principle against using config files for properties, but when the property files start to contain logic and 'mixins' for the rest of the program, things start to get fishy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By 'fishy' I mean hard to maintain.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So we have the following;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) Java code which is quite generic _and_ depentent on Spring to work.&lt;/div&gt;&lt;div&gt;2) an applicationContext.xml file which partly describe which classes to compile in (to the Java program)&lt;/div&gt;&lt;div&gt;3) A maven pom.xml file which perform magic on the applciationContext.xml file (and other things) to force things like development and test environments for the service in question. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The basic premis is to be able to move the code and use it somwhere else, and just change config files. The basic problem is that the config files are (as always) not documented, even though they are now completely logically intermeshed with the code they are acting upon.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This means that if you are making a very minor change to a part of a service, the risk is high that you need to understand how the configurations files interact with your new code. This is not very modular.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, I suspect that one of the reasons one want to do this is to be able to use the oh-so-smart dependency injection to be able to hot-wire in new behavior in the Java classes, even after (gasp) they are compiled. This behavior being defined in various configuration files, naturally.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Duck typed languages doesn't need dependency injection (magically replacing or inserting chunks of actual logic on the fly) because they alrady have that functionality.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This means that that the Java community (and others..) have taken 5-7 years to work around a big problem and finally (some years ago) had a great system for dependency injection. The reason for this workaround is that Java is a compiled language. The compiled class-files were _supposed_ to be static and non-dynamic. It's the whole point. Errors and general no-nos were supposed to be caught at compile time. It's that kind of language.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, many years later one finally have a solution to all this, and it's not even needed if you're using a Python, Ruby or JavaScript (et.c.) since it's an inherent part of the language. If you want to add a new functon to an object, at any time, on a lark, you just write;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;foo.newfunc = function(a,b){ .....}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, I could have put the logic for that in a configuration file, but then I would have to have some kind of framework which read that file, which would make my work as a programmer more complex. And it's here that my little epiphany comes back into the story, namely;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) For every extra configuration-file that link out from the file that contain the code, complexity increases dramatically.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I mean by 'link out from' I mean that the code might be dependent on configuration file x, which in turn might be dependent on configuration file y (See maven -&gt; Spring -&gt; Code example above). Also 'dramatically' is not a very specific number, but since there are next to no research in this area it's all I can do to argue that all logic you can keep inside your code files lead to less complexity, even though it might lead to less flexibility.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK, hold the horses, you might say now, all this Java-bashing is making me dizzy (thanks, that was my intention :); isn't the whole point with Java (et.c.) that the additional security of exception-checking, static typing and public/private/protected access guard you from making a lot of horrible mistakes? If we would using these flimsy little scripting languages, we would all be lost!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, here's another rub of mine: Static typing is supposed to help me make less mistakes. I have coded in JavaScript almost exclusively for the last three years (and almost exclusively in Java four years before that), and in all the JavaScript code I have written, not once have I sat down and cried silently, wishing for someone to hand me enforced static typing for JavaScript. It has not bogged me down, it has not made me confused, in reality it has made me more productive.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How is that? I have a creeping feeling that these 'safety features' are more good in formal proving of things than in actual engineering of stuff.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, I was able to quickly write a (qute shabby, but working) REST service implementation in only a page or two of (server-side) JavaScript code. The main reason for that is IMO that I didn't need to jump through hoops either creating complex class-hierarchies for the data - or- casting myself to high heaven and back - or - generating miles of try/catch code which I knew was not really needed. Sometimes the code bombed, I checked the logs, added a try/catch, and later removed it when I had fixed the problem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, as &lt;a href="http://steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html"&gt;Steve Yegge correctly has pointed out&lt;/a&gt; &lt;a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html"&gt;at great length,&lt;/a&gt; javaScript (etc) lead to dramatically reduced Lines of Code in a program. Mostly due to the non-existence of enforced 'security'. And here is a more specific thing to chew on;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) All security features of a programming language does not confer the same amount of benefits.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This ties back to my unspecific 'dramatical'  level of complexity above. There simply does not exist any research in this area, which is sorely needed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My point here is that for a given security feature of a langauge, you receive a certain level of benefits, but it also costs you an amount of flexibility. These are all realtive values for now. But from my personal experience, the following has become more and more glaringly obvious;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) The lack of a security feature from a language gives more benefits from increased flexibility than the secutiry feature gave when present.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if I use a language which already have duck-typing, I don't need dependency injection, and I don't need to manage that injection. Moreover, if I need to manage the duck-typing in any way, I might as well do it in the scripting language itself, since there is no compilation step, thus reducing complexity from linked configuration files. I can keep all logic in the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All comments welcome :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-2283402312685026630?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/2283402312685026630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=2283402312685026630' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2283402312685026630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2283402312685026630'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/08/software-complexity-in-practice.html' title='Software Complexity in Practice'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SofFg0tO5WI/AAAAAAAAAbM/_pXgyWvpP34/s72-c/butterflyex270.jpg' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-945647661280889317</id><published>2009-08-06T00:33:00.000-07:00</published><updated>2009-08-19T04:25:13.913-07:00</updated><title type='text'>Google Technology User Group - Stockholm, Sweden</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sites.google.com/site/stockholmgtug/_/rsrc/1244884633474/Home/gtug2sthlm.png?height=170&amp;amp;width=420"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 417px; height: 170px;" src="http://sites.google.com/site/stockholmgtug/_/rsrc/1244884633474/Home/gtug2sthlm.png?height=170&amp;amp;width=420" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SnqJDpv7qBI/AAAAAAAAAbE/3pk11PvohYU/s1600-h/12387015731494213381tom_Autumn_leaves_on_branch.svg.med.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 279px; height: 300px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SnqJDpv7qBI/AAAAAAAAAbE/3pk11PvohYU/s320/12387015731494213381tom_Autumn_leaves_on_branch.svg.med.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5366752601804875794" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;OK, so summer is over. The spring became a sprint for me with customer and voluntary projects crowding me from all sides, a little conference to arrange and a new major customer to get accustomed to.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the middle of all this, I still tried to find some worthwhile monthly communal activity, maybe not so far-out as &lt;a href="http://news.ycombinator.com/item?id=730673"&gt;functional alcoholics&lt;/a&gt;, but still good fun.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So while I was gearing up this idea, trying to flesh it out, suddenly Google, of all people, sprung the excellent idea of starting &lt;a href="http://sites.google.com/a/gtugs.org/www/Home"&gt;Google Technology User Groups&lt;/a&gt;, GTUGs for short.  I grabbed the Stockholm spot within minutes, naturally :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you're interested in GTUGs but happen to live far from Stockholm, Sweden, I've heard that there are some oher cities around the world, where GTUGs have ben known to form, &lt;a href="http://www.gtugs.org/directory"&gt;go find one for yourself&lt;/a&gt;, or better yet, &lt;a href="http://sites.google.com/a/gtugs.org/www/so-you-want-to-start-a-gtug"&gt;start your own&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Starting a GTUG doesn't mean that you have to becoma part of Google, or even know anyone who works there, it's basically a worldwide coders club, where we can share each others presentations, get some T-shirts or other schwag, if we're lucky, and teach each other about Google related APIs and other technologies.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Our first meeting will be the 3/9, graciously hosted at Ottoboni at Skanstull in Stockholm. The homepage for the GTUG is &lt;a href="http://sites.google.com/site/stockholmgtug/"&gt;here&lt;/a&gt;, and we currently have speaker for OpenSocial and getting started on Android development.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;If you are interested in coming, please&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt; comment&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt; on this post, so we know how many people to arrange for. Thx!!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#006600;"&gt;[Update: There's now also a LinkedIn group for those of you who use it: h&lt;a href="http://events.linkedin.com/Google-Technology-User-Group-Stockholm/pub/105365"&gt;ttp://events.linkedin.com/Google-Technology-User-Group-Stockholm/pub/105365&lt;/a&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'll see you there :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-945647661280889317?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/945647661280889317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=945647661280889317' title='31 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/945647661280889317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/945647661280889317'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/08/gogle-technology-user-group-stockholm.html' title='Google Technology User Group - Stockholm, Sweden'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SnqJDpv7qBI/AAAAAAAAAbE/3pk11PvohYU/s72-c/12387015731494213381tom_Autumn_leaves_on_branch.svg.med.png' height='72' width='72'/><thr:total>31</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6835459796376047241</id><published>2009-05-19T01:41:00.000-07:00</published><updated>2009-05-19T01:47:13.720-07:00</updated><title type='text'>Sista rycket inför SWDC2009</title><content type='html'>&lt;p&gt;Jag fick just reda på av DFS att vi stänger dörrarna i morgon för registreringar till Scandinavian Web Developer Conference 2009. Så om ni har funderat på att ta del av världens Webutvecklar-stjärnor på Måndag, registrera er _nu_ :)&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.swdc2009.com"&gt;http://www.swdc2009.com&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Mvh,&lt;/p&gt;&lt;p&gt;PS&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-6835459796376047241?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6835459796376047241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6835459796376047241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6835459796376047241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6835459796376047241'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/05/sista-rycket-infor-swdc2009.html' title='Sista rycket inför SWDC2009'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-477788089342295553</id><published>2009-05-12T23:55:00.000-07:00</published><updated>2009-05-12T23:59:20.926-07:00</updated><title type='text'>Promotion for "Learning Dojo"</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.packtpub.com/images/100x123/1847192688.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 100px; height: 123px;" src="http://images.packtpub.com/images/100x123/1847192688.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Here's a little something for anyone wavering about getting "Learning Dojo" or not.  To get a 12% discount, do the following;&lt;/p&gt;&lt;p&gt;1.) Visit the book page: &lt;a href="http://www.packtpub.com/tutorial-for-building-interactive-interfaces-with-dojo/book"&gt;http://www.packtpub.com/tutorial-for-building-interactive-interfaces-with-dojo/book&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;2.) Click the "ADD TO CART" button to add the book to your shopping cart.&lt;br /&gt;&lt;br /&gt;3.) Enter your promotion code: &lt;span style="color:#000099;"&gt;Dojo2688&lt;/span&gt; in the Promotion Code field in your shopping cart, and click the Update button. The discounted price should now be reflected in your order.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-477788089342295553?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/477788089342295553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=477788089342295553' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/477788089342295553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/477788089342295553'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/05/promotion-for-learning-dojo.html' title='Promotion for &quot;Learning Dojo&quot;'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-5297311314667554592</id><published>2009-04-08T05:30:00.000-07:00</published><updated>2009-04-08T05:39:46.456-07:00</updated><title type='text'>Rhino JavaScript working on App Engine Java Edition</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_dLfQMJsmsaI/SdvwPx8hz5I/AAAAAAAAACY/I_DEfn6nQjc/s320/ae_gwt_java.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 247px;" src="http://2.bp.blogspot.com/_dLfQMJsmsaI/SdvwPx8hz5I/AAAAAAAAACY/I_DEfn6nQjc/s320/ae_gwt_java.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;I was super-excited this morning, when I saw the announcement that Google had released a &lt;a href="http://code.google.com/appengine/docs/java/runtime.html"&gt;Java version of their App Engine environment&lt;/a&gt;. My heart sank a bit when I read that they had a class white-list for security reasons, and told myself that I wouldn't be surprised if that means that you cant run Server-side JavaScript at all.&lt;/p&gt;&lt;p&gt;However, after reading &lt;a href="http://olabini.com/blog/tag/gae/"&gt;Ola Bini's quick article on how to enable JRuby&lt;/a&gt;, I felt that it might be doable, after all, JS doesn't even have Threads (which more or less thankfully are disabled in GAE). It _should_ work.  &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;So I went and downloaded the eclipse plugin, created a new project, which came with its own "Hello World" servlet and dropped the Mozilla labs JS version 1.7 jar (from the Dojo Ajax Toolkit's util/shrinksafe folder) into the lib/ folder of the GAE project, added some paths here and there -- and it worked.&lt;/p&gt;&lt;p&gt;I tried something really simple like this;&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;String s = "var foo = {foo: 17, bar: 4711}; foo.foo;";&lt;/p&gt;&lt;p&gt;Object result = cx.evaluateString(scope, s, "&lt;cmd&gt;", 1, null);&lt;/p&gt;&lt;p&gt;resp.getWriter().println(Context.toString(result));&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;And out I got a &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;17&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;:)&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I just saw that Google has limited the Java GAE SDK for the 10 first to register. I guess Sweden was the right place to be :)  If you want to see my sample project, you can download it from here;&lt;/p&gt;&lt;p&gt;&lt;a href="http://genericwitticism.com/rhino.zip"&gt;http://genericwitticism.com/rhino.zip&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-5297311314667554592?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/5297311314667554592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=5297311314667554592' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5297311314667554592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5297311314667554592'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/04/rhino-javascript-working-on-app-engine.html' title='Rhino JavaScript working on App Engine Java Edition'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_dLfQMJsmsaI/SdvwPx8hz5I/AAAAAAAAACY/I_DEfn6nQjc/s72-c/ae_gwt_java.png' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1067986118766288869</id><published>2009-03-27T04:23:00.000-07:00</published><updated>2009-03-27T05:09:36.022-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Small clouds - Large clouds</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/Scy542asJtI/AAAAAAAAAaE/oP7xVuoXTEk/s1600-h/cloud_computing.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 180px; height: 228px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/Scy542asJtI/AAAAAAAAAaE/oP7xVuoXTEk/s320/cloud_computing.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5317829646348986066" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;So, I attended this seminar recently, in which the usual suspects were paraded in front of a saucer-eyed audience; There was Amazon, Salesforce, local hopes and established players in equal measures. The first presentation was by a Swedish guy named Joakim Lindbom, CTO at Cap Gemini in Sweden - a really sharp guy, by the way.&lt;/p&gt;&lt;p&gt;His talk was about Amazon EC2, and I had heard a lot of it before, but not everything. Joakim focused on the architectural choices that Amazon had made when creating their different services, being an architect himself. He argued successfully the common knowledge that it really isn't possible to scale a relational database to do what Amazon have to do, and that the same apply to services.&lt;/p&gt;&lt;p&gt;In general a cloud-based architecture means that you use a distributed queueing service both to store incoming requests and to communicate between system parts. Yes, a kind of ESB, if you will, but simple!&lt;/p&gt;&lt;p&gt;It also means using schemaless databases that don't mind adding another column even though there's already 1.0E9 items in the table. &lt;/p&gt;&lt;p&gt;And then it struck me; If it is absolutely critical to use ___SIMPLE___ (meaning non-complex, OK?) services which are both asynchronous (queued, event-driven) and dynamically or non-typed, to be able to build a system over a certain size - why is this not critical when building smaller system?&lt;/p&gt;&lt;p&gt;Or, to phrase the questions differently; How comes it is possible to build systems that does not comply with these traits, since they have been proven to be just critical? Size, is the answer of course.&lt;/p&gt;&lt;p&gt;But to expand that answer is to get to the core of the problem; Smaller sized systems can skimp on doing things right, because it doesn't show up until they get larger. And what small system doesn't?&lt;/p&gt;&lt;p&gt;So, essentially, what has been discovered to be critical in building large-scaled 'cloud' systems is just as essential in building smaller system, it just isn't as evident. Which of course can be translated as saying that it isn't critical. And, no, sure, it isn't critical. But what I'm saying is that even smaller system will by necessity cost less to build, if built according to the same principles the larger-scale system use, if nothing else but the simple fact that they will grow over time.&lt;/p&gt;&lt;p&gt;One of the successes of Erlang has been the reational approach to distributed proecessing; Since interprocess communication in Erlang is message-based, putting those messages on a bus á la Amazon's simple queue service, will be transparent to the processes using it, and also, those very processes need not know where they are and can so be safely dotted out in the cloud somewhere.&lt;/p&gt;&lt;p&gt;Imagine if someone would do that kind of stuff to another cool language, maybe one with first-class and anonymous functions, duck-typing (Simple, 'schemaless'), closures and late binding (i.e. easy to code in), like ... JavaScript? Maybe someone already has? :) &lt;/p&gt;&lt;p&gt;No wait, nobody has to, right. It usable that way right off the bat. &lt;/p&gt;&lt;p&gt;Have a nice weekend all y'all.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1067986118766288869?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1067986118766288869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1067986118766288869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1067986118766288869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1067986118766288869'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/03/architectural-choices-for-cloud.html' title='Small clouds - Large clouds'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/Scy542asJtI/AAAAAAAAAaE/oP7xVuoXTEk/s72-c/cloud_computing.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-5577274608244138087</id><published>2009-03-10T06:20:00.000-07:00</published><updated>2009-03-10T06:35:42.872-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open social'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='gadgets'/><category scheme='http://www.blogger.com/atom/ns#' term='authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='gfc gogle friend connect'/><category scheme='http://www.blogger.com/atom/ns#' term='programming web'/><category scheme='http://www.blogger.com/atom/ns#' term='oauth'/><category scheme='http://www.blogger.com/atom/ns#' term='opensocial'/><title type='text'>Google Friend Connect Public Key finally released :)</title><content type='html'>Yes! After months of general agonizing and a feeling that everything I knew about security *might* be wrong, Google releases the public key for the certificate that signs the signed requests coming from custom GFC gadgets back to your server.&lt;br /&gt;&lt;br /&gt;Arne Rooman-Kurrik (at Google) posted the certificate to the OpenSocial mailing list yesterday, and it looks like this;&lt;br /&gt;&lt;br /&gt;-----BEGIN CERTIFICATE-----&lt;br /&gt;MIICSjCCAbOgAwIBAgIJAKy5FQe8xe&lt;div id=":1gr" class="ii gt"&gt;&lt;wbr&gt;W/&lt;wbr&gt;MA0GCSqGSIb3DQEBBQUAMCMxITAfBg&lt;wbr&gt;NV&lt;br /&gt;BAMTGGZyaWVuZGNvbm5lY3QuZ29vZ2&lt;wbr&gt;xlLmNvbTAeFw0wODEyMTkxOTQ3NDla&lt;wbr&gt;Fw0w&lt;br /&gt;OTEyMTkxOTQ3NDlaMCMxITAfBgNVBA&lt;wbr&gt;MTGGZyaWVuZGNvbm5lY3QuZ29vZ2xl&lt;wbr&gt;LmNv&lt;br /&gt;bTCBnzANBgkqhkiG9w0BAQEFAAOBjQ&lt;wbr&gt;AwgYkCgYEAvvHLRIP0tKwFGExqfIOf&lt;wbr&gt;25Ad&lt;br /&gt;2WHq/Oz4CuuspA75pvXg5+&lt;wbr&gt;w9E4P5oMNmGNENO7LAA+xSrXLND+&lt;wbr&gt;FdDg4STH/5FW0Y&lt;br /&gt;ycPhw7LvqsefQwnntn1oHGTYffWRPb&lt;wbr&gt;ovHZBDcCBJZ2cgzXnmsXG9D7rO06fi&lt;wbr&gt;kTaa&lt;br /&gt;6aSw1mVt7sFvwZDegEkCAwEAAaOBhT&lt;wbr&gt;CBgjAdBgNVHQ4EFgQUITh3OCFLiiyT&lt;wbr&gt;PEsq&lt;br /&gt;LKmuALCpfXwwUwYDVR0jBEwwSoAUIT&lt;wbr&gt;h3OCFLiiyTPEsqLKmuALCpfXyhJ6Ql&lt;wbr&gt;MCMx&lt;br /&gt;ITAfBgNVBAMTGGZyaWVuZGNvbm5lY3&lt;wbr&gt;QuZ29vZ2xlLmNvbYIJAKy5FQe8xeW/&lt;wbr&gt;MAwG&lt;br /&gt;A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQ&lt;wbr&gt;EFBQADgYEAvnVl15uganMvEwABVxRw&lt;wbr&gt;MAys&lt;br /&gt;ICPuzrxvdgAHXDl1/&lt;wbr&gt;FCv68CEbTatHYPHBTLiY66DL8HICWw&lt;wbr&gt;FuIx4j0DTuj6IWHRG&lt;br /&gt;iP2BFvtcRvogURixojA+&lt;wbr&gt;JXsvIjafoShzqAioDptVUx1aIHM+&lt;wbr&gt;af3B5zE6+wDVmRUz&lt;br /&gt;1WeG3BvhoqPq1pUdWig=&lt;br /&gt;-----END CERTIFICATE-----&lt;br /&gt;&lt;br /&gt;It was later verified to work by a guy called videomap (should work at Google).&lt;br /&gt;&lt;br /&gt;For old readers of my blog the magnitude of this event is simple to understand, but just to be sure, it goes like this;&lt;br /&gt;&lt;br /&gt;1) You think that GFC is kind of cool. You put a gadget (or several) on the pages of your site, Google manages login, authentication, friend management et.c and people can chat , rate and have fun on your pages.&lt;br /&gt;2) You realize that allthoug people are having fun there is zero (0) interactivity between the GFC gadgets and your site, and/or&lt;br /&gt;3) You would really like to know the unique user id of the GFC loggged in user that sees you page right now.&lt;br /&gt;&lt;br /&gt;So, you..&lt;br /&gt;&lt;br /&gt;4) Learn how to create a custom GFC gadget (Exactly like creating a custom OpenSocial gadgets. Just grab one of the smallest sample code files, and you're done. Well, you have to get the 'wrappin' HTML for it from the GFC admin console for your site. Whatever).&lt;br /&gt;5) You put the gadget on your ite in a nice, shiny directory&lt;br /&gt;6) You enter the wrapping code in your page that loads you custom gadget *through* Google's GFC servers.&lt;br /&gt;7) You browse through the OpenSocial 8.x AP docs and realize that you need to do a makeRequest() call back to an url of your server, getting the usr id (and picture) is dead simple, so you have that already in the other hand.&lt;br /&gt;8) Yay, Your custom gadget actually send back the info! Great.&lt;br /&gt;&lt;br /&gt;But then you realize...&lt;br /&gt;&lt;br /&gt;9) Anythion on your page could actually have sent back that info. A malign ad might inject some script which runs and just send back 0000 or something. Translation: You can't trust informatiuon sent from the client.&lt;br /&gt;10) You find a great option to makeRequest in the OpenSocial API called SIGNED requests. This will make the container (the GFC server in this case) sign the data you send. But also add signed and correct user ids for the viewer and owner of the current data. Yay!&lt;br /&gt;&lt;br /&gt;It doesn't work. Until..&lt;br /&gt;&lt;br /&gt;11) It suddenly does, a couple of weeks ago GFC decides to activate SIGNED requests. Wild joy. Everything seems ok.&lt;br /&gt;&lt;br /&gt;Until&lt;br /&gt;&lt;br /&gt;12) You realize you don't have the public key the GFC uses, so you can't actually verify that some *other* server on the internet tries to look like it is a GFC server and feed you false data. Eugh.&lt;br /&gt;&lt;br /&gt;But then&lt;br /&gt;&lt;br /&gt;13) They did publish the public key (Above), so now the circle is finally closed. We can now use GFC as a universal login mechanism, get a unique user id back to our server,a nd connect that to any data we choose.&lt;br /&gt;&lt;br /&gt;Thanks Google!!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-5577274608244138087?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/5577274608244138087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=5577274608244138087' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5577274608244138087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5577274608244138087'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/03/google-friend-connect-public-key.html' title='Google Friend Connect Public Key finally released :)'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-5346562104581511708</id><published>2009-02-22T05:15:00.001-08:00</published><updated>2009-02-28T08:58:07.471-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open social'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='gfc'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='opensocial'/><title type='text'>Google Friend Connect finally support signed request</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SaFQcaASyqI/AAAAAAAAAZs/tPWvjGh5qqU/s1600-h/gfc_diagram.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 226px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SaFQcaASyqI/AAAAAAAAAZs/tPWvjGh5qqU/s320/gfc_diagram.png" alt="" id="BLOGGER_PHOTO_ID_5305610284966267554" border="0" /&gt;&lt;/a&gt;Why is that a big deal?&lt;br /&gt;&lt;br /&gt;Here's the short answer; Now you can get the viewer id of a user loading your page and send it back to your server in a trusted way.&lt;br /&gt;&lt;br /&gt;Before (up to two weeks ago, when I last tried it) it was only possible to send back info from the web page in an untrusted way.&lt;br /&gt;&lt;br /&gt;What I mean by that is that you could load a custom opensocial gadget, which got the viewer id using the opensocial api, and then proceeded to use the opensocial makeRequest() call to route that information back to an url on your server. However, since this information orgiginated in the browser, potentially someone might somehow get a malign script to run on your page (from an ad, perhaps) and make up any old id, to then send back to your server.&lt;br /&gt;&lt;br /&gt;In the opensocial specification, there is different modes of makeRequest, of which one is to make a signed request. To describe a signed request, I've drawn a small diagram above. Let's walk through it, and return to the signed request in a little while.&lt;br /&gt;&lt;br /&gt;Let's say that you have copied in some Google Friend Connect gadgets on one of your pages, by registering your site with GFC, noting your sites code, and so on, the first thing that happens is that a person going to you site loads your page &lt;span style="font-weight: bold;"&gt;(1)&lt;/span&gt;. In your page lies the gfc gadget references, which load the gadgets themselves from the GFC proxy servers (I call them proxies since much of what they do is route information back and forth third parties) &lt;span style="font-weight: bold;"&gt;(2)&lt;/span&gt;. If this is the first time the users has been to the site and/or the user have not 'joined' the site on a GC sense, he/she may now proceed to do so (still &lt;span style="font-weight: bold;"&gt;(2)&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Now you have written your own, custom opensocial gadget, which is also loaded into the page in&lt;span style="font-weight: bold;"&gt; (2)&lt;/span&gt;. It probably resides on your server, but could actually be loaded from any server on the internet. That gadget does the following;&lt;br /&gt;&lt;br /&gt;a) Get the id of the viewer&lt;br /&gt;b) tell the gfc/opensocial JavaScript api that is loaded to post the data to an url on your server. Two weeks ago, this could only be done without authentication.&lt;br /&gt;&lt;br /&gt;This will send the data (viewer id) first to the gfc proxies&lt;span style="font-weight: bold;"&gt;(3)&lt;/span&gt;, which will then route it forward to your server &lt;span style="font-weight: bold;"&gt;(4)&lt;/span&gt;.&lt;br /&gt;On your server is a special script that parses the post data out from the HTTP request &lt;span style="font-weight: bold;"&gt;(5)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The only thing that has changed now is that the makeRequest call can use the authentication mode gadgets.io.AuthorizationType.SIGNED, which will result in a 'stamp' made by the gfc proxies as the message passes through them. This is what it looks like in a small PHP script I wrote to collect the incoming signed info;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2009-02-22 12:41:36&gt;---------------------&gt; id=82146293318299142645, nick=psvensson&lt;br /&gt;2009-02-22 12:41:36&gt;    post param --   the_user_id -&gt; 32146007816295742145&lt;br /&gt;2009-02-22 12:41:36&gt;    post param --   the_user_nickname -&gt; psvensson&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   opensocial_owner_id -&gt; 03600513378691222179&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   opensocial_viewer_id -&gt; 78096296444182405045&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   opensocial_app_id -&gt; 09127246177732455082&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   opensocial_app_url -&gt; http://xxxyyyzzz.com/osaccess.xml&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   xoauth_signature_publickey -&gt; pub.1008283802.-8019269915578004945822.cer&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   oauth_version -&gt; 1.0&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   oauth_timestamp -&gt; 981102302897&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   oauth_consumer_key -&gt; friendconnect.google.com&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   oauth_signature_method -&gt; RSA-SHA1&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   oauth_nonce -&gt; 01831428822001149500&lt;br /&gt;2009-02-22 12:41:36&gt;    get param --   oauth_signature -&gt; MviLJcsxuU2tN9hQTkMEqZrEaC7ZUX31Cz7HH17I00vT2q8NJWH28OzvDab1Cl,01YtetX+Yln/IkuTj+I11SzFwZu5aXQda5D9HBeq+zjdxwWfuLGo62AaMjm5lvJGwWrMW6q+vm33MVOFWecxuXzSPmDfsCE9Tyf+b3M=&lt;br /&gt;&lt;br /&gt;Numbers and other stuff are messed with a bit, due to posting :) But the thing is that two weeks ago, only the two POST lines were getting though, and any signed request returned and error in th browser.&lt;br /&gt;&lt;br /&gt;This is the dawn of maybe not a new era, but a new eralischimo. Now you can use trusted user ids without having to manage the users, changing password, creating capthcas (and keeping up with the bots), listing friends and manage those connections, et.c. Now you just slam a gadget on the page, and get an id back you can trust. Not half bad eh?&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[UPDATE]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;OK, this is a bit silly. There is more to this than just using signed makeRequests :)  The reason I forgot this, is that the magic sauce was something I added in desperation some time ago when I tried to make signed requests work; I added a certificate to my domain using google accounts;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.google.com/accounts/ManageDomains"&gt;https://www.google.com/accounts/ManageDomains&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Where you can upload a x.509 certificate that you can associate with your domain. The process is explained in more detail here;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html"&gt;http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Including how to generate x.509 certs from scratch on Windows and Linux (Maybe mac as well).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-5346562104581511708?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/5346562104581511708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=5346562104581511708' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5346562104581511708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5346562104581511708'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/02/google-friend-connect-finally-support.html' title='Google Friend Connect finally support signed request'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SaFQcaASyqI/AAAAAAAAAZs/tPWvjGh5qqU/s72-c/gfc_diagram.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4580268253575908042</id><published>2009-01-23T00:48:00.000-08:00</published><updated>2009-01-24T01:52:29.340-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Using Dojo to implement the 12 standard screen patterns</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://theresaneil.files.wordpress.com/2008/12/standard_screen_patterns.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 476px; height: 705px;" src="http://theresaneil.files.wordpress.com/2008/12/standard_screen_patterns.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I really enjoyed reading&lt;a href="http://designingwebinterfaces.com/designing-web-interfaces-12-screen-patterns"&gt; Theresa Neil's article&lt;/a&gt; just recently on the 12 standard screen layout types. She gave a lot of examples, but what I found lacking was some nice templates that could be used if you wanted to jump right in and implement one or two of the patterns. I've been meaning to write a post about Dojo's Layout containers for a while now, so my initial idea was to provide Dojo examples to each of the 12 screen patterns.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As it turns out, not all patterns exist today as plain off-the-shelf examples, I decided to skip some of the patterns, since my blogging time is a bit limited, and just bite the bullets that I can quickly show.&lt;br /&gt;&lt;br /&gt;Since we've just concluded that I'm really lazy, It will come as no suprise that I'll just provide links (where possible) to existing Dojo unit tests, that can be copied straight off (possibly changing where the css and js loads from, but I assume you're familiar with such procedures)&lt;br /&gt;&lt;br /&gt;1. Master/Detail&lt;br /&gt;&lt;br /&gt;[Would be simple to do with StackContainer. I have a releated, flipped&lt;a href="http://genericwitticism.com/dojo-1.2/test/test_scaffold.html"&gt; example here, &lt;/a&gt;which loads html page snippets using Ajax and flip them over 'hypercard'-like when menu selection changes]&lt;br /&gt;&lt;br /&gt;2. Column Browse.&lt;br /&gt;&lt;br /&gt;There's actually a faily new Dojo widget that provides this 'mac explorer' kind of cuntionality. Data source riven and all. Verry snappy :)&lt;br /&gt;&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/widget/tests/test_RollingList.html"&gt;&lt;br /&gt;http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/widget/tests/test_RollingList.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3. Search / Results&lt;br /&gt;&lt;br /&gt;This pattern is of course the perfect fit for Dojo's DataGrid with filtering queries to the data store from where it draws its contents; Note that the example uses Google's cross-domain JS API to get the data which the grid is filled with;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/data/demos/demo_GoogleSearchStore_Grid.html"&gt;http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/data/demos/demo_GoogleSearchStore_Grid.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4. Filter DataSet.&lt;br /&gt;&lt;br /&gt;This is also a tricky one to find as-is. Several data stores in Dojo support complex queries, and creating a filtering panel that let the user apply filters to the tiems retrieved from the data store is not particlarly hard. Mail me or comment here if you really want an example, and I'll post one later.&lt;br /&gt;&lt;br /&gt;5. Form&lt;br /&gt;&lt;br /&gt;No worries here. There's forms galore;&lt;br /&gt;&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dijit/tests/form/Form.html"&gt;&lt;br /&gt;http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dijit/tests/form/Form.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;6. Palette / Canvas&lt;br /&gt;&lt;br /&gt;Due to Dojo's unique cross-browser native 2D api, which detect if it should use SVG, VML, Canvas or Silverlight, there are several other DOjo API's which utilizes this for charting and other things. There'sfor example an excellent &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/sketch/tests/test_full.html"&gt;Sketching API&lt;/a&gt; which support manipulations of SVG files, as well as a&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/gfx/demos/inspector.html"&gt; related example&lt;/a&gt; in the dojox.gfx section. I chose these tests because they both provide a palette / canvas like experience, involving actual graphics. You should also check out &lt;a href="http://draw2d.org/draw2d/examples_short"&gt;openJacob's draw2D &lt;/a&gt;if you are the least interested in that kind of stuff :)&lt;br /&gt;&lt;br /&gt;7. Dashboard.&lt;br /&gt;&lt;br /&gt;This patterns has me a bit confused. Except for the charting / graphing widgets it seems to me to be similar to a form or something. Perhaps an assymetric DataGrid. Let's focus on the charting then. There are &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/charting/tests/test_chart2d_dynamics.html"&gt;several&lt;/a&gt; &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/charting/tests/test_event2d.html"&gt;good&lt;/a&gt; &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/charting/tests/test_themes.html"&gt;dojox.charting &lt;/a&gt;examples available, all which build on the work of dojox.gfx.&lt;br /&gt;&lt;br /&gt;8. Spreadsheet&lt;br /&gt;&lt;br /&gt;This is again a prime candidate for DataGrid, depending on whether to implement a real spreadheet or just look a bit like one. No exmaple included.&lt;br /&gt;&lt;br /&gt;9. Wizard&lt;br /&gt;&lt;br /&gt;OK, there's no widget for this - exactly- though the pattern would be fairly simple to implement. Again, mail or comment if you really want an exact copy of the pattern in Dojo. Meanwhile, here _is_ a Wizard widget, but it only shows one 'scren' of the wizard at any one time;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/widget/tests/test_Wizard.html"&gt;http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dojox/widget/tests/test_Wizard.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;10. Q:A&lt;br /&gt;&lt;br /&gt;I'm not really sure I get this one exactly. It is just #1 but over-confident, or what?&lt;br /&gt;&lt;br /&gt;11. Parallel Panels&lt;br /&gt;&lt;br /&gt;These we've got. and in spades. There's the obvious &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dijit/tests/layout/test_AccordionContainer_prog.html"&gt;AccordionContaine&lt;/a&gt;r, the classical &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dijit/tests/layout/test_TabContainer.html"&gt;TabContainer&lt;/a&gt;, as well as the fully hackable &lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/dijit/tests/layout/test_StackContainer.html"&gt;StackContainer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;12. Interactive Model.&lt;br /&gt;&lt;br /&gt;This one covers quite a wide area. The emphasis seem to be on graphical interaction, which I'll have to get back to you for, because now it's time for lunch :)&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4580268253575908042?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4580268253575908042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4580268253575908042' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4580268253575908042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4580268253575908042'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/01/using-dojo-to-implement-12-standard.html' title='Using Dojo to implement the 12 standard screen patterns'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-3028861106241164995</id><published>2009-01-13T04:18:00.001-08:00</published><updated>2009-01-23T00:48:12.542-08:00</updated><title type='text'>Upcoming talks</title><content type='html'>So, it is a new year which brings new conferences with it. Yesterday I sent out three proposals to three different conferences, and just one day after, one of them answered! Yay!&lt;br /&gt;&lt;br /&gt;The conference in question is &lt;a href="http://skillsmatter.com/event/ajax-ria/webtech-exchange-2009"&gt;Web Tech Exchange 2009 &lt;/a&gt;in London, May 14-15, and my talk is on the second day, entitled "Leveraging dojo.data to build scalable enterprise applications". It does sound very interesting, doesn't it? :) Now all I have to do is write the actual talk as well.&lt;br /&gt;&lt;br /&gt;But first of all I will do a free Dojo workshop at &lt;a href="http://natverk.dfs.se/node/4295"&gt;Svenska Dataföreningen&lt;/a&gt; this Thursday (15/1). I'll be covering basic Dojo widgets and how you take a simple page and add some stylish Dojo magic to it, maybe some data integration or dojox.charting if there's time for it. You have to register for it and bring your own machine. Oh, and have a local web server of some sort and download&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3-src.zip"&gt; the Dojo 1.2.3 source distro&lt;/a&gt; as well.&lt;br /&gt;&lt;br /&gt;Later this month I'll be holding an intense but character-building talk on Thin Server Architecture at the Swedish &lt;a href="http://www.jfokus.se/jfokus/"&gt;jFokus event,&lt;/a&gt; Januari 28-29.&lt;br /&gt;&lt;br /&gt;Outstanding are stil my proposals for &lt;a href="http://en.oreilly.com/oscon2009/"&gt;O'reillys OSCON2009&lt;/a&gt; in San José and the &lt;a href="http://www.next-conference.com/next09/"&gt;NextWeb Conference&lt;/a&gt; in Hamburg. And do know that I need help with funding to get across the water, just so yo know. Thx! ^_^&lt;br /&gt;&lt;br /&gt;If you want me to speak at your event, or need a workshop/course in Dojo for your company or organization, feel free to mail me at the address in the left column, or twit me at http://www.twitter.com/psvensson&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;br /&gt;[UPDATE]&lt;br /&gt;&lt;br /&gt;Apparently, I will not be speaking at the jFokus event in Stockholm as I initially thought. I was urged to submit a proposal last fall by the organizers, which apparently didn't look as urgent when it came down to it :)&lt;br /&gt;&lt;br /&gt;It might have something to do with me having broken up with Java and the event is _about_ Java. Maybe. Anyway, if you still want me to talk about thing server and all that jazz in Stockholm, please let me know and I'll arrange another venue if there's enough interest. The mail address is as always on the right side of the blog.&lt;br /&gt;&lt;br /&gt;Thx.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-3028861106241164995?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/3028861106241164995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=3028861106241164995' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3028861106241164995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/3028861106241164995'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/01/upcoming-talks.html' title='Upcoming talks'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1093253137477837960</id><published>2009-01-10T03:37:00.000-08:00</published><updated>2009-01-11T03:55:15.374-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>What makes Dojo diferent?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.sitepen.com/blog/wp-content/uploads/2008/06/jsonreststore-simple.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 291px; height: 256px;" src="http://www.sitepen.com/blog/wp-content/uploads/2008/06/jsonreststore-simple.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;in&gt;&lt;br /&gt;&lt;br /&gt;Dojo (and also Ext, IIRC) have a couple of semi-unique features, being proper data abstractions in the client layer and extendable, hierarchical widgets systems.&lt;br /&gt;&lt;br /&gt;I know Dojo best, so I'll use that as an example;&lt;br /&gt;&lt;br /&gt;Data abstraction means a separate API layer between widgets (or other classes) and the actual data. All dojo.data datastores (as they are called) have the same kind of API, but manages access to data differently. For example theres one store called ItemFileReadStore, which just read in a JSON object from an url and provide it as a bag of items to widgets.&lt;br /&gt;&lt;br /&gt;Let's say that you use this data store to provide data to a combobox which implements type-ahead (which the Dojo one does). After testing you want to have a more advance data store which only fetches some items at a time (because the amount of data on the server is too large to load at once) and caches it. That means switching to the JsonRestStore, which uses the same API as the first one, et.c.&lt;br /&gt;&lt;br /&gt;Here are some good articles that give more meat on dojo.data;&lt;br /&gt;&lt;a href="http://www.sitepen.com/blog/2008/06/13/restful-json-dojo-data/"&gt;&lt;br /&gt;http://www.sitepen.com/blog/2008/06/13/restful-json-dojo-data/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The widget system in Dojo let you define custom widgets and place them on the page, using a single element with special properties. Dojo scans for these elements and look up the widget definition (in a JavaScript file and the HTML template for the widget (pointed out by the JavaScript file).&lt;br /&gt;&lt;br /&gt;Dojo then calls special functions in the widget class according to lifecycle events, and also manage unique id creation for html template elements, instantiation of subwidgets, et.c.&lt;br /&gt;&lt;br /&gt;Dojo uses this system for all its own widgets internally, and many custom widget projects I do for customers start out with subclassing an existing widget (using Dojo's pseudo- OO). The reason this work so well is that Dojo have proper namespacing, which also correspond (but can be overridden) to directory hierarchies, so class/widget lookup is both straightforward and understandable.&lt;br /&gt;&lt;br /&gt;At the moment jQuery have no data abstraction or widget subsystem (unless I've misunderstood jQuery UI completely, in which case I would very much like to be corrected :), and neither have YUI.&lt;br /&gt;&lt;br /&gt;Now I've done it again. :) This is my next blog post, apparently.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;/in&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1093253137477837960?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1093253137477837960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1093253137477837960' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1093253137477837960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1093253137477837960'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/01/what-makes-dojo-diferent.html' title='What makes Dojo diferent?'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6913981243379681732</id><published>2009-01-08T04:04:00.000-08:00</published><updated>2009-01-08T04:08:19.911-08:00</updated><title type='text'>A possible solution for siteful user authentication  in friend connect</title><content type='html'>I just posted this to the gfc mailing list, but since it relates to my earlier post on google friend connect authentication, I'll recap here;&lt;br /&gt;&lt;br /&gt;At the moment it's not possible to use a makreRequest call back to your server with the id and general data for the current vieweing gfc user, through Google's servers using SIGNED authentication.  What that would mean is that googles servers guarantees that the data is correct and stamps it in a way, since they recently authenticated the user themselves.&lt;br /&gt;&lt;br /&gt;Google _is_ prioritizing this, so we'll probably see a new release of the GFC API's that allows for this quite soon.&lt;br /&gt;&lt;br /&gt;But what if you want to get the friend connect user id of the viewer anyway?&lt;br /&gt;&lt;br /&gt;Although, having thought about this a bit, a weaker kind of security can be had if you just decide to trust the scripts running in the page.&lt;br /&gt;&lt;br /&gt;1) You store your own custom xml file describing your own opensocial gadget on your server&lt;br /&gt;2) You store the page containing the gadget on your own server.&lt;br /&gt;3) When the page is loaded, it first load GFC from google's servers&lt;br /&gt;4) The it tells GFC to load your custom opensocial gadget _through_ googles servers, acting as a proxy.&lt;br /&gt;5) You could in essence generate the xml file containing the widget in a server-side template (ugh!) which contains a unique session cookie you keep track of on the server&lt;br /&gt;6) When the widget snarfs viewer info et,c, and send it back to your server again, through googles server, using makeRequest, it also passes on the magic cookie&lt;br /&gt;7) Then you might be reasonably certain that you haven't been fooled around with.&lt;br /&gt;&lt;br /&gt;However, anything coming from the client should be treated with great scepticism, even if cookie is correct, the data collected might have been tempered with, resulting that you associate an action with the wrong user id. Still, I think this is a reasonably safe solution.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-6913981243379681732?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6913981243379681732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6913981243379681732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6913981243379681732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6913981243379681732'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2009/01/possible-solution-for-siteful-user.html' title='A possible solution for siteful user authentication  in friend connect'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-5364101753676487991</id><published>2008-12-18T01:22:00.000-08:00</published><updated>2008-12-18T12:05:46.930-08:00</updated><title type='text'>Google Friend Connect site authentication</title><content type='html'>OK. Here's the deal:&lt;br /&gt;&lt;br /&gt;I want to use GFC to authenticate users for my site.&lt;br /&gt;&lt;br /&gt;It sounds like it should be doable, right? I think it is, but at the moment it's kind of hard. In fact it's so hard (or I'm so soft) that I haven't been able to do it (yet). Let recap a bit what it is GFC (Google Friend Connect) does;&lt;br /&gt;&lt;br /&gt;1. If you enable GFC for your site, you can add GFC widgets which let people comment and rate the page you add the widgets to and interact in various ways. You can also add any custom OpenSocial widget you like (AFAIK)&lt;br /&gt;&lt;br /&gt;2. One of the widgets you must have is the login widget which let anybody 'join' your site. When they do so, Google open up a separate window which let them choose their method of authentication; Google, Yahoo, OpenId, et.c., with various suboptions in Google's case).&lt;br /&gt;&lt;br /&gt;3. Now Google keeps track of unique users that act on the widgets on your site, let them unjoin, log in and out, and so on.&lt;br /&gt;&lt;br /&gt;4. The original identity provider (Google, Yahoo, et.c.) is still used as always for changing password, user info, et.c.&lt;br /&gt;&lt;br /&gt;This is really great. The immediate thought when realizing how things work is that you want somehow to leverage this great new functionality that Google provide: To have a secure, authenticated site where you don't need to manage anyones identity, password changes, et.c.&lt;br /&gt;&lt;br /&gt;So, I started trying to do so.&lt;br /&gt;&lt;br /&gt;The first easy thing was to create a custom OpenSocial widget on my own site, that I pull in using the custom widget option on the 'social gadgets selection' on the GFC admin site; &lt;a href="http://www.google.com/friendconnect"&gt;http://www.google.com/friendconnect&lt;/a&gt;  .&lt;br /&gt;&lt;br /&gt;What happens is that you let GFC generate a HTML snippet that loads an open social script from google, which in turn pulls in your script - through - google's proxy server. In any event, the script resides on a directory on your server, and get to land on you page (which was just recently in another directory) and can then suddenly utilize all GFC magic - check the id and name of current viewer, his/hers friend list, et.c. Neat.&lt;br /&gt;&lt;br /&gt;But.&lt;br /&gt;&lt;br /&gt;If you just post this info back to your server using standard Ajax - and trust the info you get - you're lost. How can you be sure that it really was your script that send that info?  No, you need to make Google's GFC server send certified info back to your server about the current viewer.&lt;br /&gt;&lt;br /&gt;Luckily enough, there's an OpenSocial call called (..) makeRequest, which makes an ajax call through the Container (Googl'es GFC servers, in this case, since Google/GFC is the Container. The Container would normally be LinkedIn, MySpace, Orkut, et.c.) to any given destination. For example your server, which actually hosts the page where the GFC widgets are hopping about.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/apis/opensocial/docs/0.8/reference/gadgets/#gadgets.io.makeRequest"&gt;http://code.google.com/apis/opensocial/docs/0.8/reference/gadgets/#gadgets.io.makeRequest&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Is a great place to learn what can be done with this. For one thing, you can send back some good info. My simple OpenSocial script did just this, and made sure to begin in a nice and easy manner, not forcing any encryption, using AuthorizationType.NONE, like this;&lt;br /&gt;&lt;br /&gt; ...&lt;br /&gt; ...&lt;br /&gt;            var params = {};&lt;br /&gt;params[gadgets.io.RequestParameters.CONTENT_TYPE] =  gadgets.io.ContentType.TEXT;&lt;br /&gt;params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.NONE;&lt;br /&gt;params[gadgets.io.RequestParameters.REFRESH_INTERVAL] =  5;&lt;br /&gt;            var url = "http://xxxxxxxxxxxxx";&lt;br /&gt;console.log("calling url... '"+url+"'");&lt;br /&gt;gadgets.io.makeRequest(url, reqcb, params);&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;function reqcb(data)&lt;br /&gt;{&lt;br /&gt;console.log("reqcb called....");&lt;br /&gt;console.dir(data);&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;And this works well. Looking more carefully into the link above, one reads the following:&lt;br /&gt;&lt;br /&gt;&lt;p&gt; If &lt;code&gt;&lt;em&gt;opt_params&lt;/em&gt;[gadgets.io.RequestParameters.AUTHORIZATION]&lt;/code&gt; is set to &lt;code&gt;gadgets.io.AuthorizationType.SIGNED&lt;/code&gt;, the container needs to vouch for the user's identity to the destination server. The container does this by doing the following: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;   Removing any request parameters with names that begin with &lt;code&gt;oauth&lt;/code&gt;, &lt;code&gt;xoauth&lt;/code&gt;,      or &lt;code&gt;opensocial&lt;/code&gt; (case insensitive). &lt;/p&gt; &lt;/li&gt;&lt;li&gt;&lt;p&gt;   Adding the following parameters to the request query string:&lt;/p&gt;   &lt;dl&gt;&lt;dt&gt;      opensocial_viewer_id&lt;/dt&gt;&lt;dd&gt;&lt;em&gt;Optional.&lt;/em&gt;&lt;br /&gt;    The ID of the current viewer, which        matches the &lt;code&gt;getId()&lt;/code&gt; value on the viewer person object.&lt;/dd&gt;&lt;dt&gt;      opensocial_owner_id&lt;/dt&gt;&lt;dd&gt;&lt;b&gt;Required.&lt;/b&gt;&lt;br /&gt;   The ID of the current owner, which        matches the &lt;code&gt;getId()&lt;/code&gt; value on the owner person object.&lt;/dd&gt;&lt;dt&gt;      opensocial_app_url&lt;/dt&gt;&lt;dd&gt;&lt;b&gt;Required.&lt;/b&gt;&lt;br /&gt;   The URL of the application making the        request. Containers may alias multiple application URLs to a single        canonical application URL in the case where an application changes        URLs. &lt;/dd&gt;&lt;dt&gt;       opensocial_instance_id&lt;/dt&gt;&lt;dd&gt;&lt;em&gt;Optional.&lt;/em&gt;&lt;br /&gt;    An opaque identifier        used to distinguish between multiple instances of the same application        in a single container.  If a container does not allow multiple        instances of the same application to coexist, this parameter may be        omitted.  The combination of &lt;code&gt;opensocial_app_url&lt;/code&gt; and        &lt;code&gt;opensocial_instance_id&lt;/code&gt;        uniquely identify an instance of an        application in a container. &lt;/dd&gt;&lt;dt&gt;      opensocial_app_id&lt;/dt&gt;&lt;dd&gt;&lt;em&gt;Optional.&lt;/em&gt;&lt;br /&gt;      An opaque identifier for the        application, unique to a particular container.          Containers that wish to maintain backwards compatibility        with the opensocial-0.7 specification may include this parameter.      &lt;/dd&gt;&lt;dt&gt;      xoauth_public_key&lt;/dt&gt;&lt;dd&gt;&lt;em&gt;Optional.&lt;/em&gt;&lt;br /&gt;      An opaque identifier for the        public key used to sign the request.  This parameter may be omitted by        containers that do not use public keys to sign requests, or if the        container arranges other means of key distribution with the target of        the request. &lt;/dd&gt;&lt;/dl&gt;   &lt;/li&gt;&lt;li&gt;&lt;p&gt;      Signing the resulting request according to section 9 of the      &lt;a href="http://oauth.net/core/1.0/#signing_process"&gt;OAuth       specification&lt;/a&gt;.&lt;/p&gt;    &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;So, if I could use a SIGNED request instead, the GFC proxy servers would add all the info I need and crave for my service, especially a guaranteed identity of the current page viewer. Using this unique id in my tables gives me to power to associate this identity with anything I'd like on my site. Ok. Fine.&lt;br /&gt;&lt;br /&gt;What happens when I use SIGNED?  Well, the callback function always gets back the verbose, detailed and informative error message "404: Not found", in a JSON object, but still..&lt;br /&gt;&lt;br /&gt;Now you might think that I don't know the first thing about public cryptography, signing requests and tossing certificates about in the rich and useful variety of almost-compatible formats the joyful and friendly cooperation between related companies in the beginning of this century gave rise to, but you'd be wrong.&lt;br /&gt;&lt;br /&gt;I can't call myself an expert (any longer), but I have quite a good working knowledge of the above. the problem here is that the documentation makes references to the public certificate of the container, which the receiving service need to verify.&lt;br /&gt;&lt;br /&gt;great, but the Container is GFC. Where's their certificate? Maybe this is obvious, I don't know. It isn't for me, anyway. Reading another page which digs deep in the OAuth spec, I find a links I've never seen before, which let me register sites with google and deploy their public certificates;&lt;br /&gt;&lt;a href="http://code.google.com/intl/sv-SE/apis/gdata/articles/oauth.html"&gt;&lt;br /&gt;http://code.google.com/intl/sv-SE/apis/gdata/articles/oauth.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Has some links that lead to the registration page for web-based applications;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.google.com/accounts/ManageDomains"&gt;https://www.google.com/accounts/ManageDomains&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So I do just that, and use the OAuth playground;&lt;br /&gt;&lt;a href="http://googlecodesamples.com/oauth_playground/"&gt;&lt;br /&gt;http://googlecodesamples.com/oauth_playground/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;to verify that things (seem to work).&lt;br /&gt;&lt;br /&gt;Now, I'm not sure that my site, not being an OpenSocial container (surely!) need to register a certificate with Google, but just in case this was needed to make the SIGNED request work, I did so and played around with it.&lt;br /&gt;&lt;br /&gt;No luck. The result stays the same; "404: not found". Great.&lt;br /&gt;&lt;br /&gt;What I (and possibly **ALL** other site owners starting to use GFC) need, is some information. Anything of the below will be fine, if not else to give some info back to the community instead of the usual Google no-walling;&lt;br /&gt;&lt;br /&gt;1. Here's a simple example which demonstrates how to write a simple OS gadget which post back the current viewers unique id and info.&lt;br /&gt;2. Rick caught the flu last week and haven't had the time to write the example. We'll get on it in a couple of weeks.&lt;br /&gt;3. We'll never give that information, stupid Englishmen! Go and boil your bottoms, sons of a silly person!&lt;br /&gt;4. It's impossible to do what you want. Go back to bed.&lt;br /&gt;5. Wow, that's an interesting idea. We hadn't thought of that! We'll get back to you.. &lt;fading&gt;&lt;br /&gt;&lt;br /&gt;Having emptied my reservoir of frustrated incompetence, I must end with stating the fact that despite all the trouble I've had in trying to get the site authentication to work, I've at least got my money's worth :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[UPDATE]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Kevin Marks commented on one of my posts on the open social mailing list that GFC does not support signed requests at the moment. We got a number 4!! Yay!  Thanks for the info, and let's hope that this gets added real soon.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;/fading&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-5364101753676487991?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/5364101753676487991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=5364101753676487991' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5364101753676487991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/5364101753676487991'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/12/google-friend-connect-site.html' title='Google Friend Connect site authentication'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-9125299054555820723</id><published>2008-12-13T11:30:00.000-08:00</published><updated>2008-12-13T12:12:05.189-08:00</updated><title type='text'>Towards a better integration of i18n in Dojo widgets</title><content type='html'>Maybe this is old hat to some, but I've been doing some research into i18n and come up with what I think is an interesting way to get better integration with internationalization in layout containers.&lt;br /&gt;&lt;br /&gt;To recap, Dojo has, and uses internally, an internationalization system which makes sure that the Cancel button button read 'Anulla' if your browser says that your locale is 'it', and so on.&lt;br /&gt;&lt;br /&gt;I have been thinking about various ways of making the use of i18n more dynamic. My first stab at this was a small widget, which could be embedded in a page (at any amount of places) which treated its innerHTML as a key string to be looked up in the i18n system and exchanged for the actual message du jour.&lt;br /&gt;&lt;br /&gt;This was a rather heavyweight solution (and I also wrongly used dojo.requireLocalization inside the widget, instead of by the dojo.require statements where it should be. It was just insane to do that every time an instance of the widget was created, but that's how I roll :), and was unable to handle translations of html properties, like the title="" inside an anchor element, for example.&lt;br /&gt;&lt;br /&gt;I then thought of extending dijit._Templated (the superclass of all Dojo widgets whichuses 'normal templates) to do roughly the same for all all widget templates. But somehow it felt not really spot on for my problem.&lt;br /&gt;&lt;br /&gt;What I had, was a number of pages, which I had been translating to a number of hmtl 'snippet' files, which only contained the markup for what they wanted to do - no body, header or stuff like that. They are used inside ContentPanes which are managed in turn by a StackContainer, which simulates page transitions but within preloaded html snippet, getting you a mighty quick site where all parts are already loaded in the browser,but only one shown at a time.&lt;br /&gt;&lt;br /&gt;Each of these 'pages' have a lot of text, which should be translated, as well as a number of title="" and related element properties which also should be translated, so having a solution which only worked for widget templates would only solve part of the problem.&lt;br /&gt;&lt;br /&gt;SP what Idid was to create a widget which sublassed dijit.ContentPane, and which overrode the function called when the pane is done loading remote content (the file containing the html snippet), onDownloadEnd.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;dojo.provide("layout.TranslationPane");&lt;br /&gt;&lt;br /&gt;dojo.require("dijit.layout.ContentPane"); &lt;br /&gt;dojo.require("dojo.i18n");&lt;br /&gt;&lt;br /&gt;dojo.declare("layout.TranslationPane", dijit.layout.ContentPane,&lt;br /&gt;{    &lt;br /&gt;  onDownloadEnd: function(pane)&lt;br /&gt;  {&lt;br /&gt; console.log("layout.TranslationPane callback onDownloadEnd called.");&lt;br /&gt; var html = this._getContentAttr(); &lt;br /&gt; var res = dojo.i18n.getLocalization("layout", "salutations");   &lt;br /&gt; html = dojo.string.substitute(html, res); &lt;br /&gt; this._isDownloaded = true;&lt;br /&gt; this.setContent(html);&lt;br /&gt;  }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;Not much code? No, that's because I solve my problems a) at the machine they appear, b) in JavaScript, and c) on the shoulders of Dojo. So there.&lt;br /&gt;&lt;br /&gt;That leave me with snippet files which contain any number of ${title_of_stuff} anywhere at all, since the 'page' is treated as a string. &lt;br /&gt;&lt;br /&gt;I think that this would be a great thing to add to ContentPane permanently, with a couple of extra properties to it, which would point out locale overide and (not optional) the name of the package and translation file to use for any ${keywords} appearing in the markup loaded.&lt;br /&gt;&lt;br /&gt;WDYT?&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-9125299054555820723?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/9125299054555820723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=9125299054555820723' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/9125299054555820723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/9125299054555820723'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/12/towards-better-integration-of-i18n-in.html' title='Towards a better integration of i18n in Dojo widgets'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6642557809015020938</id><published>2008-12-01T10:32:00.000-08:00</published><updated>2008-12-01T12:26:03.923-08:00</updated><title type='text'>Sample chapter from my new book - Layout</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.packtpub.com/images/full/1847192688.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 340px; height: 466px;" src="http://images.packtpub.com/images/full/1847192688.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Promotion is a strange thing. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I mean, I have written this book and it would be nice if people read it. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, I'm no marketing expert and despite appearances, tend to be a bit dismissive of my achievements.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having said that, let me tell you what's great about the book I wrote;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) It's just 250 pages long&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2) It covers dojo.data in the most approachable way I could write about it - not common :)&lt;/div&gt;&lt;div&gt;3) It delves into as many parts of dojox as I could muster, not just the usual stuff but DragPanes, ExpandoPanes and GridContainers, with examples and tutorials as well.&lt;/div&gt;&lt;div&gt;4) Uses a lot of the actual (svn) source code of Dojo to show and explain different kinds of funcitonality.&lt;/div&gt;&lt;div&gt;5) Describes the creation of custom Dojo widgets at every opportunity.&lt;/div&gt;&lt;div&gt;6) Heavily opinionated.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That's not enough for you, eh? OK, &lt;a href="http://genericwitticism.com/learning-dojo-sample-chapter-6-layout.pdf"&gt;grab a sample chapter on layout right here,&lt;/a&gt; and tell me what you think. No really, please mail me so I get some feedback on how usable it is to actually learn Dojo, since that's what the title is about, isn't it?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;/div&gt;&lt;div&gt;PS&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/7919361321436933137-6642557809015020938?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6642557809015020938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6642557809015020938' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6642557809015020938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6642557809015020938'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/12/sample-chapter-from-my-new-book-layout.html' title='Sample chapter from my new book - Layout'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4944306052059989025</id><published>2008-11-25T10:48:00.000-08:00</published><updated>2008-11-26T01:44:06.782-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='i18n'/><title type='text'>The power of Dojo i18n</title><content type='html'>&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;I had said at an early stage that I was going to use Dojos i18n system to translate snippets of text in World Change Network. Now that the time came to actually implement it, I realized I had some learning to do to get all bits and pieces right. As it turned out, using Dojos i18n system for you own purposes is really simple.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;I&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;f you take a look at the unit test for i18n at &lt;/span&gt;&lt;a href="http://download.dojotoolkit.org/current-stable/dojo-release-1.2.2/dojo/tests/i18n.js"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;http://download.dojotoolkit.org/current-stable/dojo-release-1.2.2/dojo/tests/i18n.js&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; you see that it uses three major tricks;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;1.&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; Load the i18n strings bundle of your choice usin&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;g &lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;dojo.requireLocalization("tests","salutations",locale);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;2. Get a specific bundle using var salutaions = dojo.i18n.getLocalization("tests", "salutations", "en");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;3. Get the specific string for a given key using  salutations['hello'];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Let's check the arguments for number (1) and (2; Only the first two are needed, which describe the dojo package to look for bundles in and the name of the bundle. If you want to specify another locale than the one the browser declares, it can be added as third argument, "sv" for Swedish, when the browser would say "en-us", et.c.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;All well and good, but where do we put our different version of strings? As it turns out, in the dojo/test directory a directory named 'nls' can be found. In the root of that is a file called 'salutations.js'. This is the default key-value translation that i18n falls back on if the locale cannot be found.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Then comes a host of subdirectories ; zh, nl, il, dk, de, et.c et.c., one for each locale (that you want or can define). In each of these is a separate 'salutations.js' containing locale-specific resources. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;The file format look like this;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; it: "Italian",  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;ja: "Japanese",  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;ko: "Korean",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;......&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; hello: "Hello",  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;dojo: "Dojo",  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;hello_dojo: "${hello}, ${dojo}!",  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;file_not_found:"The file you reque&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;sted, ${0}, is not found."&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;for the default file, and like this in the 'it' subdirectory;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt; it: "italiano",&lt;/div&gt;&lt;div&gt; hello: "Ciao"&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And that's it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I began creating a small naive custom widget, which subtituted the content of the element where it is declared with the localized string found for the content used as key. It's not very fast, but simple to understand and use.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;dojo.provide("layout.translate");&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;dojo.require("dijit._Templated"); &lt;/div&gt;&lt;div&gt;dojo.require("dijit._Widget"); &lt;/div&gt;&lt;div&gt;dojo.require("dojo.i18n");&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;dojo.declare("layout.translate", [  dijit._Widget ],&lt;/div&gt;&lt;div&gt;{  &lt;/div&gt;&lt;div&gt;  widgetsInTemplate&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;: false,&lt;/div&gt;&lt;div&gt;  string                        : "",&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  postCreate: function()&lt;/div&gt;&lt;div&gt;  {&lt;/div&gt;&lt;div&gt;    if (!this.string)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      this.string = this.domNode.innerHTML;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    console.log("postCreate for layout.translate called. locale == '"+dojo.locale+"'"); &lt;/div&gt;&lt;div&gt;    dojo.requireLocalization("layout", "salutations"); &lt;/div&gt;&lt;div&gt;    var res = dojo.i18n.getLocalization("layout", "salutations");        &lt;/div&gt;&lt;div&gt;    console.log("Translation key was '"+this.string+"'");&lt;/div&gt;&lt;div&gt;    var str = res[this.string];&lt;/div&gt;&lt;div&gt;    this.domNode.innerHTML = str;&lt;/div&gt;&lt;div&gt;  }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note that I just copied the whole nls directory from dojo/test for my own uses, and edited the files, leaving the original filename intact, just in case :)  A better way of utilizing i18n would be to have a base class for all custom widgets, which read in a i18n bundle, and injects all keys into each class, so that every subclass has a lot of this._i18n_command_delete (If we have a naming convention that let all i18n keys begin with '_i18n_' for example).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then we could have all custom widget templates just sprinkle their markup with a lot of ${_i18n_command_delete} and so on, which would pull in the current value of that 'this' property of the widget when it is rendered in the page.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hmm....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Come to think of it, it seems to be possible for this to be put inside dijit._Widget, or possibly _Templated, which would make it spread to all custom widgets automatically. The only thing needed would be to prepend '_i18n_' to all key names, so that 'command_delete' inside a bundle file would become this_i18n_command_delete in the widget.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One would also need to have a convention that this only worked if the developer put a 'nls' directory under the package directory where widgets of a certain package are declared, following the order declared earlier. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Actually, this would be a pretty neat idea. Just my fault for using a blog post instead of TRAC to add feature requests!  Oh, you mean I could do it myself? OK, I'll add it to the queue :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;br /&gt;PS&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;font-family:-webkit-monospace;font-size:13;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4944306052059989025?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4944306052059989025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4944306052059989025' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4944306052059989025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4944306052059989025'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/11/power-of-dojo-i18n.html' title='The power of Dojo i18n'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-6861264572397408171</id><published>2008-11-17T04:47:00.000-08:00</published><updated>2008-11-17T05:48:36.862-08:00</updated><title type='text'>Codebits 2008</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SSFyaHrzc6I/AAAAAAAAASE/1Utv5e-wm1k/s1600-h/20081114254.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SSFyaHrzc6I/AAAAAAAAASE/1Utv5e-wm1k/s400/20081114254.jpg" alt="" id="BLOGGER_PHOTO_ID_5269618832065131426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SSFyUld-RsI/AAAAAAAAAR8/SQHHw_FwFJM/s1600-h/20081114251.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SSFyUld-RsI/AAAAAAAAAR8/SQHHw_FwFJM/s400/20081114251.jpg" alt="" id="BLOGGER_PHOTO_ID_5269618736980969154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SSFyNrqI3PI/AAAAAAAAAR0/41WFgkibiNU/s1600-h/20081114250.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SSFyNrqI3PI/AAAAAAAAAR0/41WFgkibiNU/s400/20081114250.jpg" alt="" id="BLOGGER_PHOTO_ID_5269618618383523058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SSFyH3ONK1I/AAAAAAAAARs/suG7uKe5DxI/s1600-h/20081113246.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SSFyH3ONK1I/AAAAAAAAARs/suG7uKe5DxI/s400/20081113246.jpg" alt="" id="BLOGGER_PHOTO_ID_5269618518408375122" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SSFtk1q-rhI/AAAAAAAAARk/sZFM_HmQ4t0/s1600-h/20081113234.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SSFtk1q-rhI/AAAAAAAAARk/sZFM_HmQ4t0/s400/20081113234.jpg" alt="" id="BLOGGER_PHOTO_ID_5269613518650256914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SSFteLjboRI/AAAAAAAAARc/PkKtI3ci4t4/s1600-h/20081113233.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SSFteLjboRI/AAAAAAAAARc/PkKtI3ci4t4/s400/20081113233.jpg" alt="" id="BLOGGER_PHOTO_ID_5269613404265095442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SSFtXILpHvI/AAAAAAAAARU/lnwa5efrNn4/s1600-h/20081113236.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SSFtXILpHvI/AAAAAAAAARU/lnwa5efrNn4/s400/20081113236.jpg" alt="" id="BLOGGER_PHOTO_ID_5269613283100925682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SSFomHj9IPI/AAAAAAAAARM/omrVfmI1A9s/s1600-h/20081113226.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SSFomHj9IPI/AAAAAAAAARM/omrVfmI1A9s/s400/20081113226.jpg" alt="" id="BLOGGER_PHOTO_ID_5269608043074363634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Last Wednesday I flew down to Lissabon to attend and talk at the SAPO Codebits conference. I had a really great time, meeting a lot of people I've only tweeted or mailed with before.&lt;br /&gt;&lt;br /&gt;As always, Lissabon is a treat. People are helpful and very respectful. A colleague made a very spot on question today when I told him about the trip: "Would you like to go back there again soon", to which I would empathically answer Yes! :)&lt;br /&gt;&lt;br /&gt;Many times, when you've spent a couple of days in a city you get kind of fed up on the experience, but Lissabon is not one of those towns.&lt;br /&gt;&lt;br /&gt;It didn't hurt one bit that I left a cold and rainy Stockholm landing in a sunny and warm (17-20 degrees centigrade) Lissabon.&lt;br /&gt;&lt;br /&gt;The Hotel (Galé 'Opera') and the venue were located in an area just alongside the 'Docas', an hours walk or so from the city centre but with a lot of rustique ambience all of its own.&lt;br /&gt;&lt;br /&gt;I had so many things to attend to before leaving that I was only partially read up on the conference and my fellow speakers. It turned out that the conference was much larger that I had anticipated with a host of Portugals finest hackers.&lt;br /&gt;&lt;br /&gt;In many ways the Codebits conferenc felt like Google I/O; A lot of multi-coloured couches, interesting lighting, free soda and coffee and the ability to turn to _anyone_ at random and strike up a conversation which revolved around important and interesting things, with the person in questions be able to understand you and bring his or her own into the discussion like nothing to it.&lt;br /&gt;&lt;br /&gt;One of my personal surprises was that Mário Valente, who I knew only as a very smart person with a stupendously correct view of the current trends in web development, as well as a extremely decent Python and JavaScript hacker. It turned out he started Portugal's first ISP as well as a couple of other successful ventures - and is also in the middle of something bigger, more of which perhaps later..&lt;br /&gt;&lt;br /&gt;We had been planning on doing some SSJS hacking during the conference but I got entangled in some late minutes changes to my book and Mário had both teaching and business issues to attend to, so it reamined a very good idea. Mário had some really good inpout on the current problems of Server-Side JavaScript efforts; 1) There's no 'killer' framework (yet) for SSJS, 2) If one were to create on, it would not be portable, due to the fact that the system APIs that RHino exposes are not the same that Spidermonkey (for example) does.&lt;br /&gt;&lt;br /&gt;So we were thinking along the lines of arranging for a standard SSJS low-level API, based on the Java-APs exposed by Rhino (Mário's idea) so that SSJS implementors would have a stable platform to work from.&lt;br /&gt;&lt;br /&gt;Also we're planning to do a thorough survey of the cloud or no-cloud SSJS frameworks available today to rank and get inspired by best-of-breed features.&lt;br /&gt;&lt;br /&gt;My talk? It went OK. I managed to miss speaking to anyone in charge which meant I didn't get a headset, which meant I had to hulk under my 20.1 Inch portable Acer 9920, due to the fact that the only other mic was welded to the pulpet.&lt;br /&gt;&lt;br /&gt;No worries though. Expect that I had the wrong settings for the TV-out in Kubuntu and had to turn my head for every slide to orient myself, having no other feedback on the screen. And I got a call in the middle, having forgot to turn off my phone, but other than that, sure things went OK.&lt;br /&gt;&lt;br /&gt;I also had a great time speaking to Jan Lehnardt from CouchDB about REST, Dojo, Erlang and (of course) CouchDB.&lt;br /&gt;&lt;br /&gt;On the speakers dinner I happened to sit across Mitch Altman who had a great number of things to say on all subjects possible, from electronics, dairy products and Brian Eno to art, music, war and interesting people in general. I tried to chip in with some good comments and since this is as good time as any, the books I spoke about was 'My war gone by, I miss you so' (horrible title, one of the best books I've read - not nearly as gory as you might think) by Anthony Loyd, A year of swollen appendices by Brian Eno and On a faraway beach by David Sheppard.&lt;br /&gt;&lt;br /&gt;Another member of the table proved to have alarmingly good knowledge of the inner workings of russian botnet 'corporations', the current evolution of 'black' insurance and  business agreements concerning buying and seelling botnet services, the 'double-NAT-with-homebrew-VM' solution of todays malware containers and the trend towrds the botnets becoming more of a symbiotic affair from the earlier parasitic standpoint, what with the automatic patching and maintenance that must be provided to ensure smooth runnings. A horror ride, to be sure, but not the less fascinating for that.&lt;br /&gt;&lt;br /&gt;Actually, I spoke to so many, most of you had no cards, but please mail me if you want to stay in contact (my address is to the side on this page).&lt;br /&gt;&lt;br /&gt;In all I met an enourmous amount of friendly and interesting people (Celso, João, Jack and everyone else) that it'll probably take me weeks to sort out the experience.&lt;br /&gt;&lt;br /&gt;Thanks a lot to everybody involved!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-6861264572397408171?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/6861264572397408171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=6861264572397408171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6861264572397408171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/6861264572397408171'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/11/codebits-2008.html' title='Codebits 2008'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SSFyaHrzc6I/AAAAAAAAASE/1Utv5e-wm1k/s72-c/20081114254.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1433234350058753164</id><published>2008-11-05T04:55:00.000-08:00</published><updated>2008-11-05T06:15:15.129-08:00</updated><title type='text'>A reasonably complicated custom Dojo widget example</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SRGkQ1efn5I/AAAAAAAAAQ0/CtVOqHiogYc/s1600-h/chap9_gc1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 118px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SRGkQ1efn5I/AAAAAAAAAQ0/CtVOqHiogYc/s320/chap9_gc1.png" alt="" id="BLOGGER_PHOTO_ID_5265170048512663442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I get a lot of questions from people on how to do this and that with Dojo, sometimes very specific and sometimes about how to approach problems in general. I don't really consider myself experienced to speak about all things Dojo, I'm actually just more of a fanboy.&lt;br /&gt;&lt;br /&gt;Most of my answers, though, boil down to some basic things, were the most common is : make a custom widget. This is key, but seemingly missing from many frameworks/toolkits today. I feel like there has been three kind of 'generations' in JavaScript usage in the browser in recent years, and many of the flame-wars and misunderstandings might be due to the fact that people have a lot of misaligned assumptions when speaking of JavaScript programming. In my view the different generations or stages has been the following;&lt;br /&gt;&lt;br /&gt;1. JavaScript inlined in the page - Netscape 4/ IE3 kludgery [Animal House - foodfight scene]&lt;br /&gt;2. Clean html with consistent and meaningful styling and classifications with all JavaScript logic in a couple of separate files which operate on said markup, transforming it, attaching event handlers, et.c. - jQuery [2001 - space shuttle approach to twin-wheel space station].&lt;br /&gt;3. Client-side hierarchical components with modularized logic and templates - Dojo [Basic Instict - the single crotch frame].&lt;br /&gt;&lt;br /&gt;First of all I'd like to say that jQuery might have a modularized templating system, where you separate widget markup from logic - I'm not experienced enough in it (yet) to tell. Please comment if you have some good references. Then I'd like to say that both Ext and JavascriptMVC has excellent templating systems for their components - in a very similar vein to what Dojo has (again, AFAIK). But I had to choose one good example out of each group, or at least it felt that way.&lt;br /&gt;&lt;br /&gt;What do you gain by writing custom components all the time? It seems awfully complicated, doesn't it?&lt;br /&gt;&lt;br /&gt;OK. what do you gain (in Dojo). Let's see;&lt;br /&gt;&lt;br /&gt;1. You get an enforced structure that help you separate view and logic inside the widget.&lt;br /&gt;2. You get opinionated support from the framework for automatic id generation, coupling markup elements to widget references and widget lifecycle management (certain named functions get called at certain times).&lt;br /&gt;3. You get _guarantees_ that the widget is hermetically sealed, unless you do something completely stupid. This means you can take it out from one place and put it somewhere else, or change your mind about having three and putting in four instead. No colissions, no overlaps.&lt;br /&gt;4. Widgets markup html snippet templates can themselves (at least in Dojo) contain other generally arbitrary widgets,. Turtles, all the way down, basically.&lt;br /&gt;5. The whole mélange can be expressed in the HTML file that is actually loaded by the user with one (1) div.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;But other than that, I suppose, not much.&lt;br /&gt;&lt;br /&gt;Since I really only know Dojo, I will be using that in my example.  Let's say that I want to have a widget with dynamically generated JavaScript-only 2D charts, where the charts can be dragged and dropped and reordered just like iGoogle or similar pages. Wouldn't that be cool?&lt;br /&gt;&lt;br /&gt;Let's start with the target HTML file, which look like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SRGl619gazI/AAAAAAAAARE/k_AbxLAkPiA/s1600-h/mc_1.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 375px; height: 252px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SRGl619gazI/AAAAAAAAARE/k_AbxLAkPiA/s400/mc_1.png" alt="" id="BLOGGER_PHOTO_ID_5265171869708872498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I begin by loading some Dojo CSS stuff and the actual toolkit base itself from AOL's CDN (Google would have worked as well, of course). Then I have to configure the djConfig variable a bit so that Dojo find the local files for the widget referenced later, even though it is loaded cross-domain.&lt;br /&gt;&lt;br /&gt;The dojo.require statements check if the referenced classes are available, and if not resolves them and load them (since the custom component 'multichart.main' is not part of dojo, I needed to point out where to find it in the modulePaths setting in djConfig earlier.&lt;br /&gt;&lt;br /&gt;Then as just one, albeit fat, div tag, I define the draggable multichart container. As you see dojo uses custom HTML properties to let its parser instantiate widgets declared in markup (All widgets can also be created programmatically in the classical style, of course). the dojoType property declare a widget which must be loaded already. All other properties after that are inserted as 'this' properties of the instantiated widget class, if it has declared those names already. Works smoothly, truly.&lt;br /&gt;&lt;br /&gt;I basically just pass one argument which is an associative array of names and values. The idea is that the names become title string on the charts, and the values point out urls where json data is provided to generate the charts.&lt;br /&gt;&lt;br /&gt;The test file foo.txt looks like this:&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;series:&lt;br /&gt;{&lt;br /&gt;series1: [{x: 1, y: 0.2}, {x: 2, y: 0.5}, {x: 3, y: 1.2}, {x: 4, y: 0.3}],&lt;br /&gt;series2: [{x: 1, y: 0.5}, {x: 2, y: 1.0}, {x: 3, y: 0.9}, {x: 4, y: 1.7}]&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;So nothing magic, just a json object with a property 'series' and one or more series of numbers, following the standard way of feeding the dojox.chart API.&lt;br /&gt;&lt;br /&gt;But back to the custom widget. Since I declared that Dojo should look for widgets beginning with 'multichart' in the directory of the same name in the directory that the HTML file was loaded from, I place a file called 'main.js' there. Which looks like this;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;dojo.provide("multichart.main");&lt;br /&gt;&lt;br /&gt;dojo.require("dijit._Templated");&lt;br /&gt;dojo.require("dijit._Widget");&lt;br /&gt;&lt;br /&gt;dojo.require("dijit.layout.ContentPane");&lt;br /&gt;dojo.require("dojox.layout.GridContainer");&lt;br /&gt;&lt;br /&gt;dojo.require("multichart.chart");&lt;br /&gt;&lt;br /&gt;dojo.declare("multichart.main", [  dijit._Widget, dijit._Templated ],&lt;br /&gt;{&lt;br /&gt;  templatePath            : dojo.moduleUrl("multichart","templates/main.html"),&lt;br /&gt;  widgetsInTemplate        : true,&lt;br /&gt;&lt;br /&gt;  content                       : {}, // name - url pairs to make draggable charts out of. Must be passed from calling script / page&lt;br /&gt;  columns                       : 3,  // How many columns we want to have in the GridContainer&lt;br /&gt; &lt;br /&gt;  constructor: function()&lt;br /&gt;  {&lt;br /&gt;    console.log("constructor for multichart.main called");&lt;br /&gt;  },&lt;br /&gt; &lt;br /&gt;  postCreate: function()&lt;br /&gt;  {&lt;br /&gt;    console.log("postCreate for multichart.main called mycontainer is "+this.test);&lt;br /&gt;    this.gc = new dojox.layout.GridContainer(&lt;br /&gt;      {&lt;br /&gt;        nbZones: this.columns,&lt;br /&gt;        opacity: 0.7,           // For avatars of dragged components&lt;br /&gt;        allowAutoScroll: true,&lt;br /&gt;        hasResizableColumns: false,&lt;br /&gt;        isAutoOrganized : true,&lt;br /&gt;        withHandles: true,&lt;br /&gt;        acceptTypes: ["multichart.chart"]  // This property must always be present, and can take any kind of widget, including your own&lt;br /&gt;      }, this.test);&lt;br /&gt;    this.gc.startup(); // When creating some dojox widgets programmtaically, you must manually call the startup() function, to make sure it's properly intialized&lt;br /&gt;    var i = 0; // Count for which column we'll place each chart in&lt;br /&gt;    var p = 0; // Count for which row we'll place a chart in&lt;br /&gt;    for(var name in this.content)&lt;br /&gt;    {&lt;br /&gt;      var url = this.content[name];&lt;br /&gt;      var chart = new multichart.chart({name: name, url:url});  // Create a custom chart with the given name and url&lt;br /&gt;      console.log("adding chart "+chart+" to zone "+i+", place "+p);&lt;br /&gt;      this.gc.addService(chart, i, p); // Add the chart to the GridContainer (This function will be called addChild in the future, for conformance with similar containers.&lt;br /&gt;      i++;&lt;br /&gt;      if (i &gt; this.columns-1)  // Go to next row if we've hit the end of the columns&lt;br /&gt;      {&lt;br /&gt;        i = 0;&lt;br /&gt;        p++;&lt;br /&gt;      }&lt;br /&gt;    }   &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;});&lt;/blockquote&gt;&lt;br /&gt;It begins by telling Dojo that it contain the class 'multichart.main', then follow a lot of requiremenets which otherwise would have to be present in the main HTML file. Then follows the widget class declaration.&lt;br /&gt;&lt;br /&gt;As you can see it inherits from two superclasses; _Widget which contain the widget subsystem logic and _Templated, which managed html template snippets.&lt;br /&gt;&lt;br /&gt;Note the 'content' and 'columns' properties which, since they are defined here, can be passed from a markup declaration(or from a programmatic creation where the arguments gets passed in an object literal as first argument to the constructor). This also gives me a good place to put default values which will stand if not overwritten (such as 'columns').&lt;br /&gt;&lt;br /&gt;postCreate gets called when the widget is ready for action, and here is where I usually put most of my init code. What this widget does is to create a Dojo component which mimics an iGoogle page and let the user drag, drop and rearrange all other Dojo widgets inside it. Then it loops over the argument and create any number of yet another custom component, 'multichart.chart', which is also present in the same directory.&lt;br /&gt;&lt;br /&gt;Each widget which derive from _Tenplated can also define a html template inside a string or in an external file. I usually use external files when developing, and then use DOjo's offline build system to inline templates, compress, concatenate files inot one, et.c.&lt;br /&gt;&lt;br /&gt;If you want to se the widget in action for yourself, you can download it as an archive&lt;a href="http://genericwitticism.com/multi_chart.zip"&gt; here&lt;/a&gt;. You might also be interested in &lt;a href="http://www.packtpub.com/tutorial-for-building-interactive-interfaces-with-dojo/book"&gt;my upcoming book "Learning Dojo" &lt;/a&gt;where it it explained more fully, along with numerous other examples :) OK, I admit it, this whole post was mostly a shameless plug for the book, but partly I wanted to define the playing field a bit as well.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1433234350058753164?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1433234350058753164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1433234350058753164' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1433234350058753164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1433234350058753164'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/11/reasonably-complicated-custom-dojo.html' title='A reasonably complicated custom Dojo widget example'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SRGkQ1efn5I/AAAAAAAAAQ0/CtVOqHiogYc/s72-c/chap9_gc1.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1121658130177324909</id><published>2008-11-02T01:39:00.000-07:00</published><updated>2008-11-02T02:17:41.593-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='front-end'/><title type='text'>How to define a front-end developer</title><content type='html'>Devoting myself (or allowing myself to be dragged away by the carneval in childish glee) to Ajax and JavaScript the last years has changed the way I've looked at the composition of software teams and of projects. Today, the breakdown is glaringly obvious to me. But since it is the result of a kind of private mental jorney what is obvious to me need not be so to someone else.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm talking about the emerging role of the front-end developer, of course. Big deal you might say, I know what that guy does, but I'm not completely sure that everyobdy agree on that, hence this post.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the days of yore, what you did on a computer was program, period.  Then came specializations of different kinds, like a dot painted on an expanding baloon becomes a circle. And still the expansion continues.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The traditional breakdown of duties in web-related projects has been in browser-specific things and server-specific things. That's actually very good, since this breakdown at least in part acknowledges the client as an entity. The role of the front-end (browser) team has been to create and manage the design and looks of the application, whereas the back-end team create and manage _all_ application logic, including client states (open trees, selected tabs, et.c.).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The front-end team was to be called designers, with en emphasis on producing HTML/CSS templates and all the Photoshop magic required for the quiltwork of images needed to give an illusion of a real application.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Later on these designers were asked to do some dynamic scripting to produce effects of various kinds, effectively becoming programmers in a way, even though their original vocation was that of esthetics and visual design. I don't say you can't mix the two,I'm just saying that in my experience the two fields draw two different personalities.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And on the other end, since the server-based frameworks need to slice, pickle and transform the provided templates into something that their server-side templating system can use, they get exposed to a lot of borderline design descisions, which is not something they originally signed up for either.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The result is that there is suddenly a risk that people are required and/or forced to make decisions and produce work for which they have both a minor talent in and doesn't really feel like, personally.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But that is a dicsussion of whether or not to use &lt;a href="http://www.dzone.com/links/rss/google_tech_talk_on_thin_server_architecture_and.html"&gt;Thin Server Architecture &lt;/a&gt;(or any of its synonyms and special cases), so let's assume that we have a sane architecture with a cleanly separated front-end and back-end (REST or RESTish, preferrably), how do we look for talent in this brave new world?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Looking at ads for front-end developers shows a plethora of confusion. First of all the same kind of job might be defined as a designer, UI expert, Ajax developer, front-end programmer, Web designer, JavaScript programmer or any permutations thereof, many of which can be applied to a true designer role as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Looking at the skill set that the front-end developer should have we find that he or she must be a veteran of all major US armed conflicts since WWII, be able to design, build and fly a commercial airliner, have discovered at least three different cures for cancer (of which at least should have received the nobel price in either of Medicine, Physics or Chemistry) and also be the founder of two or more major schools of painting, including cubism.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It seems that people are both a little desperate and a little confused. Let me try to make things clearer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In todays world, we need to have a good designer. The word designer will only be used in a classical sense, i.e. visual design. Skill-set: HTML/CSS, Photoshop/Gimp/whatnot, Usability, Fonts, Color theory, et.c.  Secondary skills: JavaScript, HTTP, Networking fundamentals, some Server-side language.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then we have the elusive front-end developer. Skill-set: HTML/CSS, JavaScript, Ajax, &lt;the&gt;, HTTP, Networking (latency, routing, distributed storage and processing, security), REST, XML (to argument against its use), SOAP/WSDL (see last comment). Secondary skills: Usability, some Server-side langauge.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The only changed thing with the skill-sets for the back-end team is that they no longer are forced to understand HTML/CSS and a smattering of JS, since there is no longer any server-side templates to massage.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On of my pet peeves is that there is an architect onboard, but he or she has launched the project without many times even decided on which Ajax toolkit to use. It's comparable to launching a project without having specified which back-end to use (Java? Python? Perhaps SSJS?).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Granted, in many cases the project has _not_ launched and the ad is for someone to come in as a front-end lead for the very prupose of evaulating and recommending technologies to use in the client layer, but there's still enough 'wild card' ads out there to make my hairs stand on end (all three of them).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ok, rant over. I guess what I want to say is that the world is getting larger and more detailed at the same time, and that if you are searching for talent, you have better know what you are looking for, and take the time to be as specific as you can.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;/div&gt;&lt;div&gt;PS&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1121658130177324909?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1121658130177324909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1121658130177324909' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1121658130177324909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1121658130177324909'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/11/how-to-define-front-end-developer.html' title='How to define a front-end developer'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-9083708676933510224</id><published>2008-10-29T06:04:00.000-07:00</published><updated>2008-10-29T15:02:41.299-07:00</updated><title type='text'>Google Summer of Code 2008 [GSoC2008]</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhpbI08cEI/AAAAAAAAAQs/zkZUBSD7d8U/s1600-h/20081025219.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhpbI08cEI/AAAAAAAAAQs/zkZUBSD7d8U/s320/20081025219.jpg" alt="" id="BLOGGER_PHOTO_ID_5262572079529357378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhpPwcNMxI/AAAAAAAAAQk/3KggneYxFqg/s1600-h/20081025212.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhpPwcNMxI/AAAAAAAAAQk/3KggneYxFqg/s320/20081025212.jpg" alt="" id="BLOGGER_PHOTO_ID_5262571884004586258" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhlPvWC_nI/AAAAAAAAAQc/CN0YPTaFAno/s1600-h/20081024211.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhlPvWC_nI/AAAAAAAAAQc/CN0YPTaFAno/s320/20081024211.jpg" alt="" id="BLOGGER_PHOTO_ID_5262567485663805042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhk3LXoEBI/AAAAAAAAAQU/bTLsugPhjhc/s1600-h/20081024210.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhk3LXoEBI/AAAAAAAAAQU/bTLsugPhjhc/s320/20081024210.jpg" alt="" id="BLOGGER_PHOTO_ID_5262567063689891858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SQhkY-RAXiI/AAAAAAAAAQM/Pl2-jUVXRy8/s1600-h/20081024209.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 244px; height: 183px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SQhkY-RAXiI/AAAAAAAAAQM/Pl2-jUVXRy8/s320/20081024209.jpg" alt="" id="BLOGGER_PHOTO_ID_5262566544776388130" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SQhkQfud5XI/AAAAAAAAAQE/HZd-g-C1CNc/s1600-h/20081024208.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 243px; height: 182px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SQhkQfud5XI/AAAAAAAAAQE/HZd-g-C1CNc/s320/20081024208.jpg" alt="" id="BLOGGER_PHOTO_ID_5262566399139505522" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of the three highlights of this young, long-haired gentleman's trip to California was to participate in the GSoC 2008 conference. Earlier this year I had been asked to become a mentor for the Dojo foundation. As you might know Google gives out enormous amounts of money each year to Open Source organization all over the world, earmarked for students so that they can afford to work on a project for their organization during the summer.&lt;br /&gt;&lt;br /&gt;This in itself is really cool and generates (deservedly) no small amount of goodwill for Google. Being a mentor I was invited, along with some 200 other people to the conference. At first it felt a bit strange to have an open source conference. I mean, it felt like having a conference on wearing pants. It's a given, more or less. The only times I normally reflect on Open Source licensing is when I see someone walking down the street sporting a &lt;a href="http://www.microsoft.com/"&gt;nekkid&lt;/a&gt; &lt;a href="http://www.oracle.com/"&gt;lower&lt;/a&gt;&lt;a href="http://www.sap.com/"&gt; half&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Most, if not all of the focus of an Open Source software developer surely lies  in the application or service being created. However, when arriving at the conference I suddenly understood the reason for the conference. Naturally the focus was on Open Source Software, and some of the sessions did indeed focus on project management and licensing issues, but the whole point of the conference was to get to meet the best and the brightest developers in the world - or so it felt at least.&lt;br /&gt;&lt;br /&gt;Most people don't code at all. Of those who code a fair share, say at least 50%,  just code as if it was any other kind of job. No real enthusiasm. Of those who are somewhat enthusiastic, there's maybe one in ten who are _really_ enthusiastic about programming. Of those maybe again 1/10 have the inclination or assertiveness to actually engage themselves in a public Open Source project, and of them not many decide to take on the responsibility of being a mentor (of which I could have made a much better job, actually, but more on that in some later post).&lt;br /&gt;&lt;br /&gt;Anyway, those were the guys I met.  But before the conference there was a traditional Thai dinner in downtown Mountain View. The way to the restaurant look a bit like this from the train station:&lt;br /&gt;&lt;hmm, it="" seems="" that="" no="" matter="" what="" i="" do="" images="" get="" displayed="" in="" reverse="" and="" at="" top="" of="" the=""&gt;&lt;br /&gt;There was a lot of happy confusion, assertive Leslie Hawthorns all over the place and a resounding call to arms for the following beer bash at a nearby establishment built for this very purpose. The volume of all these programmers talking at the same time was positively deafening, despite some truly outrageously tasty local beer. I'm so sorry that I never remember names, but I hope you know who you are! Please mail me if you want to get in contact.&lt;br /&gt;&lt;br /&gt;I met the project manager for the NTP project and was surprised to hear that something that is relied on by so many and used daily for a number of purposes is not getting the economic attention it really deserves. I met a lot of guys from Germany working on MoinMoin, and another that worked on Zope (which I have actually tried out). There was Boombox an Open Source project to replace the OS on an iPod (and other things), several ambitious bio-CMS systems (I'm a reformed molecular biologist hobbyist myself  :) and tons of other people.&lt;br /&gt;&lt;br /&gt;The party went on into the night and I was nearly unable to manage a late night dry martini at the hotel when I got home, where I had a long discussion with a couple from Alaska who liked to travel a lot (he was a geologist and she was a M&amp;amp;A specialist, which gave me a feeling that they were probably able to. Traveling can be exhausting in my opinion, but here were climbers of Kilimanjaro who would not agree :). They were also really nice people) discussing Obama (Yes!), various economic conundrums and how to pronounce Göteborg and whether the city in question resides in Sweden or Denmark (the former).&lt;br /&gt;&lt;br /&gt;Sadly, since I had to be back home on Sunday, I had to leave on Saturday, leaving me only with four hours of conference.  With a rapid taxi out to MTV I decided to make the most of it, and made a great number of good contacts, some with people who agreed with me that we must have met before, but could not recall when (it's just half a world away, really). Tons of good discussions on Dojo and on implenetations of REST and general information managemenet. Thanks everyone I met. It was a pleasure talking to all of you!&lt;br /&gt;&lt;br /&gt;ANd then there was the scale-model (surely?) of the X1 spaceship. And the lebansese buffet, and the juice bars, and the Testing onThe Toilet posters (on the toilet), and the general Googly atmosphere.&lt;br /&gt;&lt;br /&gt;Anyway, most of all; Thanks 1.0E6 to Leslie Hawthorn and Chris diBona (and the rest of the crew) for creating a wonderful experience and creative climate for all of us. And for the Google frisbees. I snacthed two to give to the kids when I got home, who were duly impressed and commenced wrecking our living room immediately :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/hmm,&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-9083708676933510224?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/9083708676933510224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=9083708676933510224' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/9083708676933510224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/9083708676933510224'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/google-summer-of-code-2008-gsoc2008.html' title='Google Summer of Code 2008 [GSoC2008]'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SQhpbI08cEI/AAAAAAAAAQs/zkZUBSD7d8U/s72-c/20081025219.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4260615077734177779</id><published>2008-10-28T07:22:00.000-07:00</published><updated>2008-10-28T13:44:09.004-07:00</updated><title type='text'>Tech Talk on Thin Server Architecture and Dojo at Google</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQciXrS_bWI/AAAAAAAAAP8/qIzSuTiEy08/s1600-h/alexm_peter2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SQciXrS_bWI/AAAAAAAAAP8/qIzSuTiEy08/s320/alexm_peter2.jpg" alt="" id="BLOGGER_PHOTO_ID_5262212479760428386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SQciQbVqHaI/AAAAAAAAAP0/esn16NJreyI/s1600-h/alexm_peter1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SQciQbVqHaI/AAAAAAAAAP0/esn16NJreyI/s320/alexm_peter1.jpg" alt="" id="BLOGGER_PHOTO_ID_5262212355217563042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;While I was in the neighborhood, I managed to get invited to do a tech talk at Google's Mountain View offices this last Friday. I tried to describe the drawbacks with traditional server-centric web frameworks and to use Dojo as an example of how to build true client applications which lead to an increased efficiency for the development team and hence to lower production and maintenance costs.&lt;br /&gt;&lt;br /&gt;People were in general very nice but razor-sharp and to the point. Very good discussions afterward focusing on build systems and SEO issues.&lt;br /&gt;Here's the slides themselves;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/EmbedSlideshow?docid=dfxgjqrf_196fr6ct4f2&amp;amp;size=s" frameborder="0" height="451" width="555"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;And here is the&lt;a href="http://www.youtube.com/watch?v=XMkIZZ7dBng"&gt; Youtube video of my presentation&lt;/a&gt; as it is;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/XMkIZZ7dBng&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;embed src="http://www.youtube.com/v/XMkIZZ7dBng&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;Alex Martelli was there as well, and had to comment on the size of my computer :) Erk Arvidsson who should have been my presenter (since I was so nervous I jus got up and presented myself as I usually do, sorry Erik!) took some pictures of relative computer sizes between mine and Alex's;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4260615077734177779?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4260615077734177779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4260615077734177779' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4260615077734177779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4260615077734177779'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/tech-talk-on-thin-server-architecture.html' title='Tech Talk on Thin Server Architecture and Dojo at Google'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SQciXrS_bWI/AAAAAAAAAP8/qIzSuTiEy08/s72-c/alexm_peter2.jpg' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-74394125729576900</id><published>2008-10-28T05:10:00.001-07:00</published><updated>2008-10-28T05:34:39.410-07:00</updated><title type='text'>AjaxWorld 2008 impressions III</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SQcBqU47QJI/AAAAAAAAAPs/kwoIhl03QRc/s1600-h/20081024204.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SQcBqU47QJI/AAAAAAAAAPs/kwoIhl03QRc/s320/20081024204.jpg" alt="" id="BLOGGER_PHOTO_ID_5262176516279320722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Trying to catch up with recent events from last week. Above a shot of the comfortable room at the Sainte Claire picturing the authors own small and portable Acer 9920 and a jug of local adult beverage.&lt;br /&gt;&lt;br /&gt;One of the talks that I had anticipated most was Chris Keene's WaveMaker presentation where WaveMaker's cloud strategy would be unveiled.  Chris made away with a very thorough and Monty Python themed presentation of the state of the cloud space today, with pros and cons of diferent solutions and wit a special focus on Amazon's EC2/S3 offerings.&lt;br /&gt;&lt;br /&gt;The reason for the Amazon focus is of cours that WaveMaker is building its own service on top of  it. The presentation was unfortunately not so focussed on what WaveMaker's service would look like or work, but on clouds in more general terms. I do hope that they follow some of my suggestions and make the service more of a 'live' development environment than an IDE that happens to be on the web. Time will tell. Sometime in November the site will go live.&lt;br /&gt;&lt;br /&gt;WaveMaker is superficially like Smartclient, TIBCO GI and Bungee labs connect (and MS popfly, et.c.)&lt;br /&gt;What separates Wa veMaker from Smartclient, for example, is that Smartclient is entirely neutral towards the kind of backend being used, whereas WaveMaker projects are exportable as stand-alone WAR arhives, to be dropped in any Java-based app-server of your choice.  If you have a more mixed environment, Smartclient might be a better choice, but if you run a Java-only shop WaveMaker will mean much quicker deployment.&lt;br /&gt;&lt;br /&gt;This is also what separates WaveMaker from Bungee labs (and likes), which push PaaS (Platform As A Service) where they host and manage they produced apps in pretty much the same way Google App Engine does (Except it doesn't come with any IDE). What WaveMaker brings to the table is the possibility of choice (something Chris did emphasize very well) where you can begin hosting your own application, then move it onto (say) an EC2 virtual machine, only to take it back in-house again when the corporate infrastructure or security requirements have changed. It seems that this will only be made simpler with the coming cloud service. We'll wait and see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-74394125729576900?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/74394125729576900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=74394125729576900' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/74394125729576900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/74394125729576900'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/ajaxworld-2008-impressions-iii.html' title='AjaxWorld 2008 impressions III'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SQcBqU47QJI/AAAAAAAAAPs/kwoIhl03QRc/s72-c/20081024204.jpg' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-307299378812922061</id><published>2008-10-27T04:00:00.000-07:00</published><updated>2008-10-27T05:24:06.546-07:00</updated><title type='text'>AjaxWorld 2008 impressions II</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SQWgzqsSmUI/AAAAAAAAAPk/rhkXzC3Bf3c/s1600-h/20081019188.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SQWgzqsSmUI/AAAAAAAAAPk/rhkXzC3Bf3c/s320/20081019188.jpg" alt="" id="BLOGGER_PHOTO_ID_5261788549146122562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;AjaxWorld had nearly all available conference space at the Fairmont Hotel in San José, connected by miles of carpeted classical Hotel vestibules.  All talks had ample room for attending listeners, but the amount present varied (as it does) betwee different talks.&lt;br /&gt;&lt;br /&gt;One interesting fact was that there was two different talks on server-side JavaScript; One from Jaxer and one from the Phobos project. The Jaxer demo was very good. The presenter Ian Selby made a small REST server implementation while we sat there, database tables and all. Sure, he was well prepared but still. The amount of code was very small. All portions that accessed was database  was one line each. That's the way it's supposed to be, really.&lt;br /&gt;&lt;br /&gt;I do hope that Jaxer moves away from the server-side templating stuff and instead emphasize the really nice platform and infrastructure they have in place. Cooking DOM JS on the server and pushing the rendered results to the client when JS is unavailable or wrong version is an edge-case at best, and if no JS is present, ten attaching event-handlers won't be possible anway,  so in practice (having mulled this over the course of some months) I feel that there is little that a server-side DOM processingcan do that can't be done with plain CSS anyway. Please correct me if I'm wrong :)&lt;br /&gt;&lt;br /&gt;The other Server-side JavaScript talk was by Roberto Chinnici who made an excellent presentation of the Phobos SSJS framework. In theory Jaxer and Phobo does pretty much the same thing, but Phobos is much more focussed on language integration. I think that Jaxer has something similar, but OOTB phobos can call and use any Java library or class as well as spawn JavaScript threads.  Not hurting whatsoever is a (coming?) port of ActiveRecord from ruby and a low-level implementation of Gears (wich also works with Jaxer, btw).&lt;br /&gt;&lt;br /&gt;Something that was mentioned as a feature,&lt;a href="https://ajax.dev.java.net/"&gt; jMaki&lt;/a&gt; made me perk my ears up. I checked jMaki out briefly a year or so ago and felt pretty certain that it was something tied to JSF, which made it rabidly uniteresting from my point of view. Luckily Greg Murray, the creator of jMaki was also present and could now refute that fact. jMaki is apparently something quite separate which can be used with Java, Ruby, PHP and now also SSJS.&lt;br /&gt;&lt;br /&gt;All well and good, surely. But what does it do? Quite. jMaki is a cross-toolkit switchboard. What that means is that you can use a from created in Dojo, attach its events to a table from YUI which readsits data using data abstractions from Ext. Is that hot or what???  In the examples available there is always some pesky server-side component needed with generic sounding names at every turn, but it does seem at his point that jMaki is not dependent ona  server-side component and of so, it is pure gold.&lt;br /&gt;&lt;br /&gt;I also saw a presentation by Brent Hamby and Geof Hendrey from &lt;a href="http://nextdb.net"&gt;nextdb.net &lt;/a&gt;which takes my thin server architecture one further step: no server architecture! They have a database service which can be used directly from an ajax page with full transport security. The have a model which is similar to Kerberos, where tickets are issues and encryped by the server, which also includes rules of use which must be preserved.&lt;br /&gt;&lt;br /&gt;Netxdb.net also have an administrative interface where you can define queries and users, in a very simple manner. If you have an applicationwhere you can put most of the logic on the client and only use a data store + security, it's a very interesting solution.&lt;br /&gt;&lt;br /&gt;All talks were recorded, but it will take up to five weeks until we can see them online (including mine),  so I'll post the links to that later.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-307299378812922061?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/307299378812922061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=307299378812922061' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/307299378812922061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/307299378812922061'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/ajaxworld-2008-impressions-ii.html' title='AjaxWorld 2008 impressions II'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rRWdAFxWBEM/SQWgzqsSmUI/AAAAAAAAAPk/rhkXzC3Bf3c/s72-c/20081019188.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1509677023761861580</id><published>2008-10-22T13:46:00.000-07:00</published><updated>2008-10-23T21:42:49.112-07:00</updated><title type='text'>AjaxWorld 2008 impressions I</title><content type='html'>This is the first in a series of post on what I saw, talked about and experienced on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;AjaxWorld&lt;/span&gt; conference this year in San &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;José&lt;/span&gt;. The conference has just ended and I'm sitting in the hotel room after a nice &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;crabcake&lt;/span&gt; burger and a glass of  wine and will soon head off to Mountain View in search for a SF bookstore.&lt;br /&gt;&lt;br /&gt;Anyway.&lt;br /&gt;&lt;br /&gt;My impressions of the conference as a whole and of the state of the industry (which one might hope would have a correlation) is that the world is being split in two. Luckily, most people isn't particularly interested in the bad part :) What I mean by that is that a seizable portion of the talks and booths revolved around products that continue to pile complexity upon complexity on the developers to shield them from the browser.&lt;br /&gt;&lt;br /&gt;I'm primarily talking about Oracle and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Icefaces&lt;/span&gt; here, of course. But also talks on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;GWT&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;PHP&lt;/span&gt;-generated server-side templates for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;JS&lt;/span&gt; did their best to muddle the waters. Of course, this is not really fair in my part, since everyone is trying their best to solve the problems as best they can. If it so happens that someone has struck upon a substandard architecture and haven't had time to think through all the angles, it's certainly not because of &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;malign&lt;/span&gt; intent.&lt;br /&gt;&lt;br /&gt;On the whole I was happily surprised to see a lot of companies present whose products and talks were attracting a lot of attention, who were in essence advocating thin server solutions across the border, wholesale. &lt;a href="http://www.smartclient.com/"&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Smartclient&lt;/span&gt; from isomorphic&lt;/a&gt; has grown a _lot_ since I checked it out a year or so ago.&lt;br /&gt;&lt;br /&gt;They have basically built 50% of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Dojo&lt;/span&gt; all by themselves, for their client side framework, and I couldn't help but thinking: Agnostics what a waste! How much time it must have taken them. And then immediately: Wow, that's really smart, we should have that in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Dojo&lt;/span&gt; :) What I was most impressed with was their efficient focus in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;metadata&lt;/span&gt;. Nowadays we have&lt;a href="http://www.json.com/json-schema-proposal/"&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;JSON&lt;/span&gt;-Schema&lt;/a&gt;, which was not a luxury they had when they started out, of course.  They have a tool which let you import &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;schemas&lt;/span&gt; of different formats, though, so &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;JSON&lt;/span&gt;-Schema support is probably on their radar.&lt;br /&gt;&lt;br /&gt;Why is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;schemas&lt;/span&gt; so important? Well, they have many (all?) components schema-aware, so that if you attach a schema to a Form component, up pops a form with the correct fields, date fields have a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;datepicker&lt;/span&gt;,  int fields have validations for integer values and so on. Also, the form gets generated by itself, of course, and can be remaking itself dynamically. Why don't we have such a thing in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;Dojo&lt;/span&gt;? Actually, there's no reason at all, but right now I'm blogging.  Also their grids work in the same way, and have a couple of extra features like sort fields which can be enabled for any column (filters).&lt;br /&gt;&lt;br /&gt;My only gripe with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;Smartclient&lt;/span&gt; is that the web-based &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;IDE&lt;/span&gt; is non-free (but they have a 60-day demo), and also that they have written a whole new toolkit instead of &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_24"&gt;leveraging&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;jQuery&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;Dojo&lt;/span&gt;, Ext or something. Their toolkit is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;LGPL&lt;/span&gt; and all, but still think that it would have been simpler if they hadn't been so monolithic. Now, I _am_ just grumbling. the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;Smartclient&lt;/span&gt; DIE was &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_29"&gt;absolutely&lt;/span&gt; wonderful with tons of smart components and a clean separation o f concern between the client being created and the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_30"&gt;services&lt;/span&gt; it consumes. Very good.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;UPDATE: &lt;/span&gt; As @ckendrik points out in the comments below, when the first versions of Smartclient were created, no toolkits were available (2001), which explains both the long list of features and the reason for a homegrown solution. I'm not at all suggesting that Smartclient is fracturing the framework space. It is actually very uncommon for companies with similar products to actually leverage an existing framework; Appcelerator, TIBCO, et.c. have their own frameworks as well.   This is very much alleviated by the fact that many companies are starting to provide bridges to other frameworks;  Smartclient have extension for GWT interaction, for example.&lt;br /&gt;&lt;br /&gt;Coming up: " &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;jMaki&lt;/span&gt; - buried treasure", "WaveMakers upcoming massive cloud gambit", "Lessons learned around Mars" and finally "SSJS - the only way forward".&lt;br /&gt;&lt;br /&gt;Your trusted uncle in San José,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1509677023761861580?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1509677023761861580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1509677023761861580' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1509677023761861580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1509677023761861580'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/ajaxworld-2008-impressions-i.html' title='AjaxWorld 2008 impressions I'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4480407940765547321</id><published>2008-10-15T07:13:00.000-07:00</published><updated>2008-10-15T07:16:14.606-07:00</updated><title type='text'>Codebits in Portugal</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://codebits.sapo.pt/imgs/logo_site.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://codebits.sapo.pt/imgs/logo_site.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My presentation for Codebits in Lissabon, Portugal just came up. I hope not too many people go to both AjaxWorld and Codebits this year :)&lt;br /&gt;&lt;a href="http://codebits.sapo.pt/intra/s/speaker/10"&gt;http://codebits.sapo.pt/intra/s/speaker/10&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks 1.0E6 for Mário Valente for recommending me as a speaker. I haven't been in Portugal for over ten years!&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4480407940765547321?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4480407940765547321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4480407940765547321' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4480407940765547321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4480407940765547321'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/codebits-in-portugal.html' title='Codebits in Portugal'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-2731973589782856587</id><published>2008-10-15T06:11:00.000-07:00</published><updated>2008-10-15T06:39:43.637-07:00</updated><title type='text'>Academic exercises</title><content type='html'>A couple of weeks ago I was invited to speak for &lt;a href="http://www.bth.se/"&gt;Bleking Tekniska Högskola (BTH)&lt;/a&gt; here in Sweden on the subject of Thin Server Architecture, which was something I just couldn't turn down, even though I'm in deep in several other things at the moment.&lt;br /&gt;&lt;br /&gt;At my suggestion, I also made a couple of slides with exercises for the students in basic Dojo widgetry. Then I rememberd how confused I had been when I began to learn Dojo and the peculiarities of JavaScript like closures and Object Literals and such things, so I had to do some quick slides on those as well.&lt;br /&gt;&lt;br /&gt;A lot o thanks goes out also to Stuart Langridge, whose presentation&lt;a href="http://www.kryogenix.org/code/browser/secrets-of-javascript-closures/"&gt; "secret of javascript closures"&lt;/a&gt; I was able to use, instead of writing my own :) It saved a lot of time.&lt;br /&gt;&lt;br /&gt;All in all I was surprised in how many of the students that understood what I said, that was able to (or wanted to) follow the exercises and came up with good questions, and also had already seen the crockford vids on 'advanced javascript'. These guys were really up to speed! OK, they had only worked with jQuery/Mootools concatenation style toolkits before, so the relatively 'classic' coding style of Dojo was something new.&lt;br /&gt;&lt;br /&gt;What I also realized is how truly huge Dojo is, when I tried to do a quick feature rundown. The 2D cross-browser Gfx, the charting support, fx and easings. Especially the animations was fun to show, as they're really completely generic and can be used to morph from one CSS class to another, or to change color, or to move an element on the page, according to the easing rules which determine how fast or slow to change the values over time. That's really slick.&lt;br /&gt;&lt;br /&gt;Thanks to all the students (and teacher) for having me, and having tried this out I can say that I'm now officially prepared to teach at other places as well :)&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-2731973589782856587?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/2731973589782856587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=2731973589782856587' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2731973589782856587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2731973589782856587'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/academic-exercises.html' title='Academic exercises'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1050417069412109620</id><published>2008-10-07T10:50:00.000-07:00</published><updated>2008-10-07T11:18:16.432-07:00</updated><title type='text'>Conferences come in groups</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SOunoXsbI8I/AAAAAAAAAPc/N5jd_7yGF4o/s1600-h/wmchart.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SOunoXsbI8I/AAAAAAAAAPc/N5jd_7yGF4o/s320/wmchart.png" alt="" id="BLOGGER_PHOTO_ID_5254477702254764994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I'm trying to find time each day to finish my presentation for AjaxWorld, which I'll present the 20th this month in San José. I've got permission from Kris Zyp from Sitepen and Ganesh Prasad of SOFEA fame to loan their pictures for various slides, so there's hope that I'll have something more than text in it!&lt;br /&gt;&lt;br /&gt;The title of the presentation is "Practical Thin Server Architecture with Dojo" and I hope to live up to the title, even though I won't be doing more than talk and dance.&lt;br /&gt;&lt;br /&gt;I spoke to Leslie hawthorn at Google when I visited the Open Source Offices (and got a spanking nice T-shirt :) this summer about doing a tech talk (apparently called 'Google MTV' internally) on the subject of Thin Server Architecture, which I just got confirmed. It's the 24th October in the middle of the raging Summer of Code unconference (which I'll also hopefully attend).&lt;br /&gt;&lt;br /&gt;That's two talks of the same kind the same week, which is OK. But what happened two weeks ago was that I got a mail from Mattias Schertell at Blekinge Tekniska Högskola (A technical unversity in Southern Sweden) which wondered if I could do a day of workshops and talks around the subjects (TSA and Dojo), which I accepted, and I'll fly there Tuesday next week. I have to remake a couple of exercises I've been writing a while ago this weekend, to get them up to Dojo 1.2 speed. Mental not to self and all that.&lt;br /&gt;&lt;br /&gt;Then a friend asked if I couldn't speak at a Swedish conference (on Ajax, et.c.) also next week, the 16th, which I could, so that's another engagement right there. There's another conference by the same organization in early 2009 as well, so...&lt;br /&gt;&lt;br /&gt;Anyway, completely unconnected comes an email from Pedro,  a Portuguese organizer for the codebits 2008 conference in November this year which also invites me to speak, and how can I say no to that!&lt;br /&gt;&lt;br /&gt;So all in all it seems that my future is filled with glaring lights, repetitions and pointed questions :)&lt;br /&gt;&lt;br /&gt;On the plus side, my next chapter to be rewritten in response to proofreading for the book is due as far out as October 19, which feel really far off at the moment. I've managed to do some coding on World Change Network, but still hope to get the new menu working properly and to have the CRUD tables skinned to spec.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;While evaluating WaveMaker 4 for my client, I tried to create a custom component that wrapped dojox.charting which I managed (with some help from WM personell - thx!) to accept complex json objects as data series input and switch both chart type and color theme on the fly. Pretty neat actually, and not so hard as I thought. It's open source as well, so mail me if you want it!&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1050417069412109620?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1050417069412109620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1050417069412109620' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1050417069412109620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1050417069412109620'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/10/conferences-come-in-groups.html' title='Conferences come in groups'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rRWdAFxWBEM/SOunoXsbI8I/AAAAAAAAAPc/N5jd_7yGF4o/s72-c/wmchart.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1768680518298690396</id><published>2008-09-20T01:27:00.000-07:00</published><updated>2008-09-20T02:04:13.039-07:00</updated><title type='text'>Return of the WaveMaker</title><content type='html'>I had reason to pick up WaveMaker again recently for a customer project. I knew that a version 4 had been released and had been meaning to check it out for a while, but I had a lot of other things calling my attention all the time.&lt;br /&gt;&lt;br /&gt;As you might remember WaveMaker is a web-based IDE which let you drag and drop a nice UI and connect tables, trees and other things to backend services, like databases, web services and even POJO Java classes. And this in itself is nice, but the big deal is that everything is done with very few clicks in the IDE, it's all running from your own local machine (if you want, you might have a separate development machine for this, but it's in your control, is what I mean) and it produces a stand-alone WAR file that you can drop into JBoss or Tomcat or whatever to get your stuff up and running.&lt;br /&gt;&lt;br /&gt;I really like RAD, when it works. WaveMaker had some problems in the 3.x release in making connections between UI components and backend services easy to understand, and this has thankfully become much better in the 4.x release.&lt;br /&gt;&lt;br /&gt;Still, WaveMaker has two major drabacks, for me;&lt;br /&gt;&lt;br /&gt;1) It has no cloud. OK, this is wildly unfair, I know. But I'm comparing against GAE, and possible Jaxer all the time. What hapens if I manage to build something that has to support millions of request? Do I have to wrestle AWS again? Argh!&lt;br /&gt;&lt;br /&gt;2) It requires Java to runt the backend. Custom logic can thankfully be done in any language, as long as it exposed as any (almost) kind of web service, WSDL, RESTish, et.c, but the server is done in Java, and require a container. What would be very nice is if you could separate the excellent front-end IDE from the services it depends on from the backend, and build alternate backends. Maybe a python backend? ??  ?? :)&lt;br /&gt;&lt;br /&gt;I've been looking at ways to use WaveMaker with SSJS (Server-Side JavaScript) the last days, on my off time, and it is definitely doable. I donwloaded the Rhino jar from Mozilla, which is the standard Java-based JavaScript engine (&lt;a href="http://www.mozilla.org/rhino/download.html"&gt;http://www.mozilla.org/rhino/download.html&lt;/a&gt;), and put it in the lib directory in my WaveMaker project folder. Then I copied and pasted one of the examples which comes along with Rhino that shows how to evaluate a Java String as JavaScript, into the WaveMaker Wizard which help you create new services from a simple POJO. And it compiled and smiled, just like that :)&lt;br /&gt;&lt;br /&gt;The next step is to make it do something useful, and to tie the output of the service to an UI component, maybe a textfield, to see that it works. And what we have then is a DIY SSJS in conjunction with WaveMaker's excellent frontend. Since WM has a well defined server-side Java ASPI as well, exposing those objects to JavaScript should be fairly easy, since you'd probably want to interact with it at some point.&lt;br /&gt;&lt;br /&gt;Then I got thinking about possible backend alternatives again, and noticed that Kris Zyp's SSJS persevere framework has been accepted into the Dojo foundation. Persevere is really cool, but has no IDE as such, and depend on the developer knowing well how to consume RESTish webs ervices from a JavaScript(Ajax client, very close to TSA/SOFEA ideals :)&lt;br /&gt;&lt;br /&gt;What it has in spades is database rubberification and exposal through REST services. It can connect to a number of different databases, and present all actions (even schema modifications and table management) in the same kind of REST metaphor as you would present adding a new row or modfying a column.&lt;br /&gt;&lt;br /&gt;Persevere has a lot of feature overlap with WaveMakers backend, but that's really very positive, since there's not so much more to add (I hope :). Unfortunately, Persevere also require a Java backend, running on Rhino itself, but it could still be a nice addition.&lt;br /&gt;&lt;br /&gt;Possibly, WaveMaker could also add a SMD (Simple Method Descripton) web service generation to the list of existing services it can consume, which would make Persevere melt right in.&lt;br /&gt;&lt;br /&gt;What I would really want is a SSJS cloud which is toolkit agnostic, with the WaveMaker IDE as ... well, IDE and management console.  The current contenders for the SSJS cloud throne are mostly (10gen, for example) forcing their own platform, and making it impossible to import JavaScript from other sources (Say, Dojo). Or if not, they force you to whip out your credit-card before getting any access (Jaxer).&lt;br /&gt;&lt;br /&gt;I think it's really sad that Jaxer does not provide a free entry-level poking-around alternative for their cloud. Google App Engine (OK, quite some more resources) and others can do it, and it really feels like a bad slice of an otherwise gorgeous apple pie.&lt;br /&gt;&lt;br /&gt;I began with praising WaveMaker, then being unreasonable with them, then yammered at the state of SSJS in general. Coherent? Certainly not! :) Also, I really like Jaxer as well, but I think that they really should not push away customers like that. Everything else point in the other direction(I.e. really cool and very interesting), so not giving people the opportunity to check out the wares before ponying up (The amount is insignificant, actually, from this point of view) feels wrong.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1768680518298690396?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1768680518298690396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1768680518298690396' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1768680518298690396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1768680518298690396'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/09/return-of-wavemaker.html' title='Return of the WaveMaker'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4233946635172853164</id><published>2008-08-26T04:55:00.000-07:00</published><updated>2008-08-26T05:31:08.505-07:00</updated><title type='text'>Strange summer and other things</title><content type='html'>What did you do on your summer vacation? Mine was kind of hectic. I came in contact with a group of people who was in the process of creating a startup and was searching for a front-end lead. The idea sounded strange but I was wowed by the talent that sat at the table. We were people from all around the world; Sweden (obviously :), Pakistan, France, Canada and USA.&lt;br /&gt;&lt;br /&gt;I had a complete blast with designing the front-end stuff and interacting and brainstorm with all the other guys and girls on the team. Wives were involved (under NDA's naturally) and ideas spawned at any hour of the days - dinner tables, while jogging - you name it.&lt;br /&gt;&lt;br /&gt;Unfortunately I got more and more restless with what I felt was something that would not solve itself automatically; the end-user proposition, especially in light of similar services and/or services filling similar purposes. I might be wrong, but I feel that the end-user experience and value proposition must be central to a service, and by definition that includes its relation to its context (i.e. similarity neighborhood). I was so at odds with the rest of the team that I finally decided to quit rather than get into debates all the time.&lt;br /&gt;&lt;br /&gt;This was not an easy decision, but in retrospect I still feel, the best one. It feels very sad to become part of a dynamic supersmart group fro a month and then willingly close the door on it, but that's what I did. OK, I'm still involved in some side-projects that are indirectly needed, but I'm not 'in' any longer.&lt;br /&gt;&lt;br /&gt;So, that was quite a ride, and I'm still reeling from it. The positive side is that I now have more time on my hands (i.e. almost none) than before, so that &lt;a href="http://www.packtpub.com/tutorial-for-building-interactive-interfaces-with-dojo/book"&gt;finishing my book&lt;/a&gt; at least become a possibility. That is a good thing.&lt;br /&gt;&lt;br /&gt;I'm also working on two things that is on my conscience;&lt;br /&gt;&lt;br /&gt;1) Get back to finishing  the fine editor for JavaScript as a Dojo component, so that I can finish my Bunkai editor so I can deliver it this decade to the Sling project (and any other project needing a rowser-based source code editor with pluggable resource managers.&lt;br /&gt;&lt;br /&gt;2) Finish the simple Dojo / App Engine mockup for World Change Network before taking the family to dinner with the founder this Friday :) Might be a priority, really.&lt;br /&gt;&lt;br /&gt;Other than that Dojo 1.2 is creeping ominously closer to being released (no thanks to me, I might add), and if you haven't checked out the truly cool new features, just look at the following;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gruppler.dojotoolkit.org/"&gt;Just-what-you-always-wanted DOM text effects; explosiong, slicings, you name it!&lt;/a&gt;&lt;br /&gt;&lt;a href="http://genericwitticism.com/dojo-1.2/dojox/widget/tests/test_RollingList.html"&gt;&lt;br /&gt;A eclipse/Croquet-sqeuak object browser / drill-down list. MIGHTILY useful&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://genericwitticism.com/dojo-1.2/dojox/charting/tests/test_event2d.html"&gt;Insanely cool dynamic 2D charts with events, sliding pies and onmousovers with quivering data points. Mmmm..&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And of course a lot more, but these are my personal favorites. The last two come from my personal stash, a cross-domain built svn 1.2, reasonably updated. Feel free to use it  if you want to play with 1.2 but don't want to wait for AOL or Dojo to put up a build. Use same instructions as for AOL.&lt;br /&gt;&lt;br /&gt;Continuing the Dojo trend, make sure to take a look at &lt;a href="http://www.keeneview.com/2008/08/wavemaker-4-introduces-point-and-click.html"&gt;WaveMaker's latest release &lt;/a&gt;(with surfing board and everything :). As you all know WaveMaker is an open-source web-based IDE that let you create Ajaxified applications point-and-click style, with a WAR-file as result. Simple component bindings to SQL tables and/or Web Services as well.&lt;br /&gt;&lt;br /&gt;Really cool, actually. If you're into Java, that is. I wonder what would happen if they took that front-end and put it on rails or App engine?? Hmm...&lt;br /&gt;&lt;br /&gt;And I'm also gearing up for talking at AjaxWorld this October. I really hope that Red (at the Google Open Source programs office) will find a spot to do a tech talk that week, since it's going to be a summer of code party then as well.&lt;br /&gt;&lt;br /&gt;Anyway, if you're in San José in October 20-25, please ping me for a beer ot two :)&lt;br /&gt;&lt;br /&gt;Oh! And don't miss Kris Zyp's&lt;a href="http://www.sitepen.com/blog/2008/07/18/clientserver-model-on-the-web/"&gt; devastatingly spot-on article&lt;/a&gt; on client / server programming on the web.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4233946635172853164?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4233946635172853164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4233946635172853164' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4233946635172853164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4233946635172853164'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/08/strange-summer-and-other-things.html' title='Strange summer and other things'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1842050225065658469</id><published>2008-06-23T12:43:00.000-07:00</published><updated>2008-12-10T01:53:31.137-08:00</updated><title type='text'>Twitter and Gears</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SF_-2k4X3XI/AAAAAAAAAOk/SWeWlV19cyc/s1600-h/bmn1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SF_-2k4X3XI/AAAAAAAAAOk/SWeWlV19cyc/s320/bmn1.jpg" alt="" id="BLOGGER_PHOTO_ID_5215167107084836210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;OK, this is probably tangential to the book I should be writing on right now (20 pages to go until Sunday. Argh!), but it _is_ Dojo.&lt;br /&gt;&lt;br /&gt;Twitter is more like a kind of weather than a service. It goes well at times, and at times it does not. Many times I wish I just could search through old tweets, or sort them quickly in some ways not intended by twitter.&lt;br /&gt;&lt;br /&gt;I've actually thought; why not use Gears to store all twits and then just use a Dojo Grid to show them. Separating download and presentation in a perceivable way could actually be a feature of a twitter client.&lt;br /&gt;&lt;br /&gt;Most probably someone has already done this and much better than I, but anyway, I've actually made it work .. sort of :)&lt;br /&gt;&lt;br /&gt;So if anyone know if this has already been done, please mail me or comment here. Once the stuff is in the google gears store I thought I'd add a MIT Simile timeline to splunk it up a bit as well.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1842050225065658469?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1842050225065658469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1842050225065658469' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1842050225065658469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1842050225065658469'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/06/twitter-and-gears.html' title='Twitter and Gears'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SF_-2k4X3XI/AAAAAAAAAOk/SWeWlV19cyc/s72-c/bmn1.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-7234539884690671759</id><published>2008-06-03T03:20:00.000-07:00</published><updated>2008-12-10T01:53:32.845-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='IO2008'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>From Google with Love</title><content type='html'>After a grueling 17 hour flight from Stockholm, bouncing once in Chicago, we (me and my family) arrived at SFO and shortly after, Hotel Triton at Grant Avenue and Bush. The kids started hopping around between the beds like grasshoppers while the poor parents attempted some sort of controlled landing. The room was very nice, if a bit on the small side.&lt;br /&gt;&lt;br /&gt;After a couple of obligatory days of spending on the obvious tourist activities (having a great time all the same, especially the kids. I really recommend SF as a place to go for vacation) I went to the Dojo Dinner that was arranged the day before Google I/O.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It was really cool to meet people I've only had e-mail contact with before, like Alex Russel and Dylan Schieman, among others. We had a great Vietnamese dinner which sort of turned into a vehicle for party-crashing the Wordpress release party a few blocks away. At the Dinner were also three really nice Dojo specialists all the way from Bògota (Sorry, I have to type this in at lunch and don't remember everyones names atm).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUgGVDuHRI/AAAAAAAAANc/45dbdqMp7nk/s1600-h/20080528086.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUgGVDuHRI/AAAAAAAAANc/45dbdqMp7nk/s320/20080528086.jpg" alt="" id="BLOGGER_PHOTO_ID_5207603837227900178" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUgQ1t0NXI/AAAAAAAAANk/6oKShJRtcFY/s1600-h/20080528087.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUgQ1t0NXI/AAAAAAAAANk/6oKShJRtcFY/s320/20080528087.jpg" alt="" id="BLOGGER_PHOTO_ID_5207604017793086834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUdNTUmnRI/AAAAAAAAANU/ohNUC6v2sTI/s1600-h/CIMG3115.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUdNTUmnRI/AAAAAAAAANU/ohNUC6v2sTI/s320/CIMG3115.JPG" alt="" id="BLOGGER_PHOTO_ID_5207600658486041874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Nice room (The Pókemon pillow was ours).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SEUg0aOEoDI/AAAAAAAAANs/3IBL5yW_ALg/s1600-h/20080526054.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SEUg0aOEoDI/AAAAAAAAANs/3IBL5yW_ALg/s320/20080526054.jpg" alt="" id="BLOGGER_PHOTO_ID_5207604628887478322" border="0" /&gt;&lt;/a&gt;Kids grasshoppering.&lt;br /&gt;&lt;br /&gt;Having acquired the secret password for the WordPress bar left me in a lot of interesting conversations, listening in on the FLickr guy, the Wordpress guy and also Rohit Khare who had something new up his sleeve, more of which probably later.&lt;br /&gt;&lt;br /&gt;Next morning it was time to get to the Moscone center for some serious Googling. I was at the right place sort of) with twenty minutes to spare. This was Moscone center;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SEUhvbPbw8I/AAAAAAAAAN0/y3AFD_1Hkdc/s1600-h/20080528090.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SEUhvbPbw8I/AAAAAAAAAN0/y3AFD_1Hkdc/s320/20080528090.jpg" alt="" id="BLOGGER_PHOTO_ID_5207605642773906370" border="0" /&gt;&lt;/a&gt;Hmm. No Google logos there, eh? OK, this was a really _big_ affair. The entrance might just as well be on the other side, right? I started to walk around the center, keeping a brisk pace, looking out for sign of any convention, Google or no.&lt;br /&gt;&lt;br /&gt;As it turned out, the next side of the building was clearly a 'side' with no real official entrances, turning up the hopes for the 'other end', as it were.&lt;br /&gt;&lt;br /&gt;Much to my chagrin, the other side was just that, leaving me in an even worse spot. Each side of the building was perhaps 400-500 meters, and the only thing I could do now was to go back to the side where I started. There again I noticed that the building _way_ over the other side of the street also had "Moscone" signs. After managing the street, I finally got hold of a person who directed me to yet another building, Moscone "West", which was barely visible from where we were standing. It was pure luck Google had not set up shop in Moscone South, Egypt.&lt;br /&gt;&lt;br /&gt;I was not alone in attending Google I/O;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rRWdAFxWBEM/SEUjPz--VtI/AAAAAAAAAN8/eeBoKeGCFGU/s1600-h/20080528092.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_rRWdAFxWBEM/SEUjPz--VtI/AAAAAAAAAN8/eeBoKeGCFGU/s320/20080528092.jpg" alt="" id="BLOGGER_PHOTO_ID_5207607298683197138" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The &lt;a href="http://www.youtube.com/watch?v=vk1HvP7NO5w"&gt;keynote was good,&lt;/a&gt; except for the GWT guys trying to bash on JavaScript and only managing an empty clapping sound.  It's about 55 minutes in. I have liked GWT a bit on general principles before and I still think it is a great solution. Unfortunately it is a solution to a problem the doesn't exist.&lt;br /&gt;&lt;br /&gt;Then I went to get an introduction to Python by Guide himself! Is that cool or what? He's like me European, well built (...), humorous and wonderfully opinionated.  Most things I've read up on before, but he got in a lot of history, examples, et.c. between the lines so it was really great.&lt;br /&gt;&lt;br /&gt;Also, I managed to meet up with Kirk Wilson, CEO of World Change Network, to plan the next release of the system. The general idea is to create a reputation-based project store and exchange, focusing on solving problems for people in developing countries. The reason for this is that there might in many cases exist tried-out processes for certain problems (donating blood, managing around corrupt officials, seeking legal help, et.c.) that the people in need of them are not aware about.&lt;br /&gt;&lt;br /&gt;Also, the system will contain basic project management, supporting coaching and helping from all of over the world. I think of it as aid by donating project management rather than money. I'm sure Kirk can put it more eloquently, but that's a fair summary from my point of view, I suppose :)&lt;br /&gt;&lt;br /&gt;The party was a smash hit of Olympic proportions. Dozens of linked arcade games, chocolate fountains, Googlers somersaulting in dragged together heaps of bean bags, beer, wine and ale of exotic brands (and Steam ale, yes :), Sushi, pastas, mashed potatoes and gravy.. and the flight of the Concords. I didn't think I would find them funny, but they were. They were also very good musicians.&lt;br /&gt;&lt;br /&gt;I think I went to an English pub after that, with some people in the real-estate business (those cards left at home again, sorry!) with Swedish ancestries.&lt;br /&gt;&lt;br /&gt;The next day went by in a blur, finally coalescing into the acquisition of a Google Gears Beta T-shirt! Yay!  And also the devastating wit and vehemence of Steve Yegge.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rRWdAFxWBEM/SEUn7gY-IMI/AAAAAAAAAOM/Cq7fmXyYCEE/s1600-h/20080529107.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_rRWdAFxWBEM/SEUn7gY-IMI/AAAAAAAAAOM/Cq7fmXyYCEE/s320/20080529107.jpg" alt="" id="BLOGGER_PHOTO_ID_5207612447384281282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;He gave a good rundown on his server-side (SSJS) JavaScript work at Google, and on his plans to release the &lt;a href="http://www.youtube.com/watch?v=1QD9XQm_Jd4"&gt;Ruby on Rails in JavaScript framework Rhino's Not Ruby (RnR)&lt;/a&gt; Real Soon Now. For all those present who still hasn't got it, he gave ample  examples and conjecture for why dynamic beats static when it comes to choosing language, and why late binding and JIT's beats the living daylight out of static compiling. In all a wonderful talk, if too short.&lt;br /&gt;&lt;br /&gt;If you read this, Steve, remember that you've _almost_ promised to come to Stockholm and give a (longer) speech later this year :) Just so you don't forget.&lt;br /&gt;&lt;br /&gt;After Google I/O wound down, Kirk was the perfect host, giving us a truly great tour of San Francisco; the Golden gate, the Yacht club, the park, height-ashbury, et.c. After we very deposited, light as feathers in the restaurant Viva!, recommended by Mats Henricsson, devouring the Pescatore pasta and then enjoying a quiet walk home to the hotel through Chinatown.&lt;br /&gt;&lt;br /&gt;Being a mentor for Dojo in the Google Summer of Code 2008 program, I was invited to a lunch at the googleplex by the indefatigable  Leslie Hawthorn, of Google Open Source Programs Office. I must really thank her for being able to acquiesce to my request to bring the whole family.  They actually had T-shirts in the kids sizes.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rRWdAFxWBEM/SEUrO0IzKrI/AAAAAAAAAOU/a844KBpCypw/s1600-h/CIMG3269.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_rRWdAFxWBEM/SEUrO0IzKrI/AAAAAAAAAOU/a844KBpCypw/s320/CIMG3269.JPG" alt="" id="BLOGGER_PHOTO_ID_5207616077637561010" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;When we got home to Sweden again, we found out that our daughter had been collecting gravel from the path outside building 43 and put in the jacket pocket of my wife, so now we have four very precious Google Stones at home, possibly with the same effects upon basic charateristics as AD&amp;amp;D&lt;a href="http://en.wikipedia.org/wiki/Ioun_stones"&gt; IOUN stones&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUuM5t8t8I/AAAAAAAAAOc/at0yA5CJaGs/s1600-h/20080601121.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUuM5t8t8I/AAAAAAAAAOc/at0yA5CJaGs/s320/20080601121.jpg" alt="" id="BLOGGER_PHOTO_ID_5207619343310698434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Also, the food was indeed great, and Leslie had this great T-shirt in commemoration of the day when they had the author of xkcd on a Tech Talk. They had baked him a cake the shape of the internet! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-7234539884690671759?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/7234539884690671759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=7234539884690671759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7234539884690671759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7234539884690671759'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/06/from-google-with-love.html' title='From Google with Love'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rRWdAFxWBEM/SEUgGVDuHRI/AAAAAAAAANc/45dbdqMp7nk/s72-c/20080528086.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-7283432485305662627</id><published>2008-05-22T05:27:00.000-07:00</published><updated>2008-05-22T06:06:02.897-07:00</updated><title type='text'>Going to San Francisco</title><content type='html'>So, this Saturday me and the rest of the family (sans cats) will blast off from Arlanda airport, Stockholm, bounce at O'Hare in Chicago and land 17 hours later in San Francisco.&lt;br /&gt;&lt;br /&gt;The reason for this extravagance is Google I/O, which I'll be attending. I haven't made up my mind yet what sessions I'll be going to. All seems to be a hard option :)&lt;br /&gt;&lt;br /&gt;Anyway. It was almost ten years since I last was in SF; so it'll be great to be back again. If you know of any really nice kid-friendly restaurants (apart from the Pier and McD!) and/or know of any geek-friendly activities in the neighborhood, please comment or mail me directly (see address in the sidebar).&lt;br /&gt;&lt;br /&gt;The main problem is to find another Hotel where we can buy admission to use the pool, since ours don't have any. The reason for that is that it's hard to explain to a six-year old girl why there's no pool in the Hotel, that's why :) I've bought Naruto's for her brother, so he'll be OK.&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-7283432485305662627?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/7283432485305662627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=7283432485305662627' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7283432485305662627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/7283432485305662627'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/05/going-to-san-francisco.html' title='Going to San Francisco'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-1416877453998466975</id><published>2008-05-15T00:52:00.000-07:00</published><updated>2008-05-15T00:55:33.956-07:00</updated><title type='text'>The elusive Dojo Treetable</title><content type='html'>I just got a mail from David Silvestre, who asked me about how to go about building a Dojo Treetable. You know, the sortable table thingy where you can expand and collapse each level just like a tree, but it still retain all columns for everything it shows?&lt;br /&gt;Anyway, I had do one of those last winter, for  a project, and spent a large amount of time trying make Dojo's existing Grid and/or Tree usable to do what I wanted, and ultimately failed.&lt;br /&gt;&lt;br /&gt;Here's my short notes on how (to the best of my recollectionary faculties) I did it;&lt;br /&gt;&lt;br /&gt;I found a couple existing treetables, especially one for jQuery, but in the end I had to make one myself to understand what I was doing. I recommend you to do the same.&lt;br /&gt;&lt;br /&gt;Overview;&lt;br /&gt;&lt;br /&gt;1) Create a simple custom widget (see my ultra-light tutorial here;  http://docs.google.com/Presentation?id=dfxgjqrf_78fr7h6sd7&lt;br /&gt;2) Create a table (remember to use &lt;thead&gt;, et.c. otherwise IE will barf :) in the template for it&lt;br /&gt;3) You have a hierarchy of data (an xml document, no doubt).&lt;br /&gt;4) Use dojox.xml.DomParser to get a traversable object (still horrible but hey) of the XML. (I have some examples on how to use it if you need)&lt;br /&gt;5) Create an array of object trees out of the xml object. I mad an array indexed on 'name', where I created an 'artist' object and stuck it there, and under that I stuck and 'album', followed by 'song' object. You get the picture.&lt;br /&gt;6) When the array is done, you parse it (could possible by done in one step, I guess) and create an image and a subtable, and add that to the single td of the overall table&lt;br /&gt;7) I recurse the object tree for each array object, and create a new image and table, which gets tucked inside the single td of the parent table, until there are no more object levels.&lt;br /&gt;8) I now have a table with a table in in with a table in it, et.c.&lt;br /&gt;9) The image (+ or -) beside the table has an onclick handler which shows or hides the table it is handling. Thus you can get smooth animations and hide/show all or some things that you already have open, according to which level you click the image on.&lt;br /&gt;&lt;br /&gt;Now that I've written it out, it does sound a bit harder than it felt, but the hard part is realy to parse the xml data and create a usable structure. After that it's (just) a recursive table making function. Sort of :)&lt;br /&gt;&lt;br /&gt;Actually, I think I'll post this to my blog, since it's at least a rough sketch for someone else in your position.&lt;br /&gt;&lt;br /&gt;Hmm.. Maybe this could be a real Dojo component. Maybe.. err.. in autumn :)&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;PS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-1416877453998466975?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/1416877453998466975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=1416877453998466975' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1416877453998466975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/1416877453998466975'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/05/elusive-dojo-treetable.html' title='The elusive Dojo Treetable'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-2759457180482988215</id><published>2008-05-12T00:07:00.000-07:00</published><updated>2008-05-12T00:43:29.103-07:00</updated><title type='text'>Teaching === Learning</title><content type='html'>I spent most of the 90's teaching various networking technologies to people (Novell's NDS, Microsoft's passive directory, TPC/IP, et.c). And if there's one thing I learned from that experience(except what a challenge some students can be :) is that you just think you know something until you've tried to teach it.&lt;br /&gt;&lt;br /&gt;And conversely, after having survived a dozen courses you can finally say that you've mastered the subject (for the level you're teaching, naturally). It's not enough to read the books over and over, and it's not even enough to work with it day in and out (though it's even better). If you're not forced to take one step back and actually formulate a personal theory about how things work, you'll never truly grasp a subject.&lt;br /&gt;&lt;br /&gt;There's no magic here, only a specific level of effort and - maybe - will. One always strive to do the least in any given situation. I would classify this as a property tied not to Swedes in general or even humans in general, but to all life, period.&lt;br /&gt;&lt;br /&gt;So the trick is to put oneself in a situation where above an beyond call of duty become the least possible effort. That way is to write a book :)&lt;br /&gt;&lt;br /&gt;I thought I knew a bit or two about Dojo before i began, but that's nothing compared to what I know now. Unfortunately that's still meager catch compared to what I now see available. Well, I won't die bored, that's for sure.&lt;br /&gt;&lt;br /&gt;This weekend I finished chapter three of "Learning Dojo", which would be an overview of how Dijits (Dojo's widgets) work. What struck me was that I found a lot of things that I've been looking for, but have had to hack brute force the last year.&lt;br /&gt;&lt;br /&gt;For instance, if you're creating a custom widget (and, let's face it, that's the way you work) you often want to access the DOM nodes in the template for various reasons, from you widget class. I had resorted to misuse the basic template variable substitution in Dojo, which lets you use ${} syntax in the HTML template of a widget to directly insert 'this' level variables. My templates looked a bit like this;&lt;br /&gt;&lt;br /&gt;div id="${id}_dialog" dojotype="dijit.Dialog"\&gt;div id="${id}_dialog" dojoType="dijit.Dialog"\&gt;...\/div&lt;br /&gt;&lt;br /&gt;This will lead Dojo to automatically insert the id property of the widget into the variable, so that if the id we had given our custom widget was 'foo', this node now had an id of 'foo_dialog', which modularized stuff in a good manner, so as to not collide with other instances of the same custom widget in the page, et.c.&lt;br /&gt;&lt;br /&gt;When I started writing about attach points, I realized I was very unsure about how they worked. I re-read the online documentation and couldn't really make heads or tails of it. Finally I started testing ideas of how attach points might work in a small test widget.&lt;br /&gt;&lt;br /&gt;What I did was the following;&lt;br /&gt;&lt;br /&gt;div dojoAttachPoint="dialog"  dojoType="dijit.Dialog"\&gt;...\/div&lt;br /&gt;&lt;br /&gt;And then I suddenly had a new property in my widget class called 'dialog', or 'this.dialog'. Strange huh? :) As it turned out attach points was what I had been doing all along, only slicker and truly integrated. They work for ordinary DOM nodes in the templates as well, the property just is a reference to the DOM node instead of the widget.&lt;br /&gt;&lt;br /&gt;I learned a lot more things during the course of writing the chapter, but I'll get to them in another post. The attach point conundrum has been bugging me or quite a while, so I just wanted to blog about it for some for chap who like me, really needs it but doesn't grok the online dox :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-2759457180482988215?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/2759457180482988215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=2759457180482988215' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2759457180482988215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/2759457180482988215'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/05/teaching-learning.html' title='Teaching === Learning'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.mashupstation.com/pics/petersgmailbild.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7919361321436933137.post-4177457017148761059</id><published>2008-05-06T00:15:00.000-07:00</published><updated>2008-05-06T00:49:28.791-07:00</updated><title type='text'>Cutting my Karma some slack</title><content type='html'>It seems like everybody goes into crunch-mode this time of year, almost like migratory birds or something. Naturally, so did my client.&lt;br /&gt;&lt;br /&gt;This led to a lot of positive things, most of all the smart timeseries hack which I hope to build something out of as soon as I've gone through the latest changes the Eugene has made to Dojo's stellar charting engine. But also a deeper understanding of Dojo in general. Every week I'm able to crank out one or two Dijit's for some custom need, that make the client happy without disturbing the server guys (since we're using &lt;a href="http://www.thinserverarchitecture.com"&gt;TSA/SOFEA&lt;/a&gt; architecture here, hello?)&lt;br /&gt;&lt;br /&gt;On the down side, my work with getting the  Bunkai architecture finished all but stalled. Let's see why this happened:&lt;br /&gt;&lt;br /&gt;1. The first Bunkai verison was a (very) quick hack with no respect for extendability whatsoever. I did maybe a dozen things large and small, that I've never done before.&lt;br /&gt;2. The revamp was fairly ambitious, using a pluggable message bus for both editors and resource loaders, so that you can have any amount of loaders (Sling, GData Google documents, static examples, et.c.) open at any one time, which lets you browse the resources as trees. You can have the same resource open more than once and you can close and open it again, et.c. This works now. (although only Sling and static).&lt;br /&gt;3. The editors are also (as said) pluggable, which in theory can let you have the same resource up in two different (or same) editors, which communicate changes between each other (the message bus again, natch! :) This only works partiall at the moment., due to..&lt;br /&gt;4. Some weird Dojo behavior, when adding Tabs dynamically.  I've tried this with a number of components, and they all react the same way; When I create a tab and add (and editor) to it, the editor component gets rendered inside the upper part of the tab where you click to switch between tabs. When I add another tab, both gets rendered correctly. Yes, I've tried refresh, Yes I've tried doing it backwards, using containers and calling layout, what have you. This is odd.&lt;br /&gt;&lt;br /&gt;Anyway, what I did have did work inside the Sling repository, so now I've mailed it to Lars (Trieloff) to pick apart and throw it back at me hard, but for the moment I feel I've at least moved the boulder forward.&lt;br /&gt;&lt;br /&gt;Then there's the book, which should have had a finished chapter 3 (Introduction to Dojo Widgets) done weeks ago. My only defence here is that I haven't been procrastinating any more, I've been dead busy!  But still..  I managed to find a couple of hours last night and push it up to ten pages (out of an estimated 32), so at least it's moving forward.&lt;br /&gt;&lt;br /&gt;Also, my game-writing depravities has luckily been put on hold while some of the fruits of that effort have been used in writing a tentative Google Application Engine db.Model object -&gt; dojox.data JSON converter. Actually I began to write it as a SMD file exporter for db.Model objects, so that it created a full SMD (simple Method Description) json file, to be consumer by Dojo rpc objects, and create client function endpoints to call server-side objects directly.&lt;br /&gt;&lt;br /&gt;But then I realized that it was silly, and that each object would only have four calls anyway (CRUD- Create, Read Update, Delete). So now I'm just exporting object properties.&lt;br /&gt;&lt;br /&gt;The upside of this is that I'm able to continue doing the dojo Grid integration for the World Change Network. I'm nearly there, so expect some news this week. What's nice is that I now have a model for GAE which let you have any db.Model object inside GAE and get a Dojo tree and/or Grid together with a create/update Dialog. That means that you can just create some mobjects and get an admin-interface in a can - using two pages of python code and just Dojo. Schweet :)  Roberto Saccon is working on something similar, so we're going to integrate our stuff soon.&lt;br /&gt;&lt;br /&gt;And speaking of ROverto, I remember promising him that I'd port Christophe Dolivet's exellent EditArea source code editor as a Dojo Widget. I've actually started on that, as I'd like to streamline the loading process for Bunkai, anyway, but as always, everything takes time. Just my good fortune I don't try to do any of this in Java huh? :)&lt;br /&gt;&lt;br /&gt;And speaking of source code editor widgets, I've *still* not checked out Marijn Haverbeke's _also_ truly excellent JavaScript source code editor (which as well as EditArea support html, php, js, and a lot of other syntax). But since Christophe made me co-developer for EditArea I suppose I have to go through with that first.&lt;br /&gt;&lt;br /&gt;And I'm looking forward to coming to SF in just under three weeks, for the Google I/O event. This will totally rock, I'm telling you!&lt;br /&gt;&lt;br /&gt;So, back to client coding..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7919361321436933137-4177457017148761059?l=unclescript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://unclescript.blogspot.com/feeds/4177457017148761059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7919361321436933137&amp;postID=4177457017148761059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4177457017148761059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7919361321436933137/posts/default/4177457017148761059'/><link rel='alternate' type='text/html' href='http://unclescript.blogspot.com/2008/05/cutting-my-karma-some-slack.html' title='Cutting my Karma some slack'/><author><name>Peter Svensson</name><uri>http://www.blogger.com/profile/16751089093335901438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google
