Looking for my RSS feed? Here it is!

March 2008 Web Technology Update

Wednesday, March 5, 2008

Recently a bunch of technologies have been released and/or updated and I would like to mention a few of them briefly.

First and foremost, Silverlight 2 Beta 1 has finally been released and you may download it immediately.  There is also an accompanying SDK.  You can find a nice development tutorial series on Scott Guthrie's blog.  If you are already familiar with WPF, you can just skim this entire series in less than 5 minutes.  Given that this technology isn't the same as the full WPF and given that it's designed for the web, there will obviously be differences.  It's important to remember that Silverlight 2 isn't simply WPF for the web.  I would call WPF 3.5's XBAP support for IE/Firefox "WPF for the web".  No, this is possibly the biggest web technology improvement since the release of Firefox 1.0, which in turn was the biggest technology release since the printing press.  Alight, alight... since .NET 1.1.  It's support for the dynamic language runtime is going to completely revolutionize our web development.

When reading through Scott's tutorial series (serious, at least skim it), it's interesting to note that Silverlight 2 allows cross-domain communication.  It does this by reusing the Flash communication policy files.  This is really awesome as it means that you can start accessing resources that Flash has been using for a while.  Being able to dynamically access resources from different domains is critical to the success of web architecture in the future.

Speaking of cross-domain communication, John Resig and I received a very depressing e-mail the other day telling us horrible news: cross-domain communication will probably be removed from Firefox 3 before it's official release.  Apparently a bunch of paranoid anti-architects were complaining about the dreaded evils of being able to access resources from different domains.  Um ok.  Fortunately, however, Firefox 3 has a feature called postMessage that allows you to get around this.  Malte Ubl has produced a library called xssinterface to demonstrate just this concept.  You could, of course, get around this completely with some iframe hacks or some other scripting magic.

Speaking of web browsers, I would like to bring people's attention to a technology that I've been following for some time now: Apple WebKit.  This is basically the brains inside Safari.  I absolutely love the Safari web browser.  It's by far and away the easiest web browser to use.  It also has the same keyboard short-cuts as Firefox, which is how I'm able to use it.  It's also incredibly fast, but I should mention that it uses even more memory than Firefox.  My last instance passed 500MB.  Given it's lack of an extension or configuration (i.e. about:config) system, it's obviously no where near the same caliber as Firefox though.  It is, however, my primary web browser as has been since October '07.

The reason I mention WebKit is because as very few people know, this is an open source project and has nightly binaries released on their webkit.org web site.  One of the most interesting thing about nightlies that you can actually watch the progress of development as time goes on.  About every month or so I like to get the latest Firefox nightly.  It's always interesting to see the major experiments that the developers try about 2 months after a major release of Firefox.  There's always some really awesome "teaser" feature in there that later grows into a fully grown technology.  The same can be said for WebKit.

None of that is, however, my primary reason for mentioning WebKit.  As, most web developers know, the Acid2 test has been the standard for checking a web browsers compatibility with the CSS standard.  I've been pushing this test for a long time, but I've never pushed it as the only test.  There are many things that a web browser must do and many features a web browser must have before it can be considered appropriate for use.  Merely focusing on CSS, while completely ignoring DOM support, JavaScript, and general user usability can lead a browser to be as impossible to use as Opera 9.

As I've said time and time again, I'm not a CSS specialist.  Part of the definition of being a professional web develop is that I have a solid understand of the inner workings of CSS including specificity, the various selectors, and how to merge absolute, floating, and relative position on the same elements, tasks "coders" see as nearly impossible to learn.  However, my focus is on AJAX interaction as seen from the JavaScript and DOM worlds.  Therefore, we need to have a test for browsers that goes beyond the simple Acid 2 test for CSS.  I'm not the only one thinking this way, because recently the Acid3 test was published and it tests CSS, JavaScript and DOM support.  This is the new standard for web browsers.

So far no web browser has even gotten close, with the lowest score from a web browser being 39% in Safari to the best score being 50% in Firefox 2.0.0.12.  However, in terms of non-released software, Firefox 3.0b3 has a score between 59% and 61%, depending on its mood (update: b4 is steady at 67%) and the latest WebKit nighty has a score is 90% (watch WebKit progress on Acid 3 at http://bugs.webkit.org/show_bug.cgi?id=17064).  That's phenomenal!  The newly released Internet Explorer 8 beta 1 has a score of 17%.  Those of you who have naively praising the IE team for being YEARS late on getting near the Acid 2 test need to wake up and realize this is 2008.  Time moves-- keep up.  Firefox has been close for the longest time and has always had the next-gen's next-gen JavaScript and DOM support, but has only recently completely passed the finish line of the Acid 2 test.  So, they are finally off my watch list there, but I will not stop bugging them until they pass the Acid 3 test.

For more information on the Acid 3 test, see John Resig's most entitled "Acid 3 tackes EMCAScript".  He's about as passionate as I am for web standards and Firefox and his blog is an invaluable resource for all things JavaScript.  His work is so good that I would like to take the time to plug his book he is currently writing: Secrets of the JavaScript Ninja.  I absolutely guarantee you that this book will redefine the entire world of JavaScript and will raise the bar incredibly out of the reach of "coders". To all of you coders who think you know JavaScript, do a view-source on the Acid 3 source code (you may want to bring a change of underwear with you).

Lastly, it's not necessarily a "new" technology, but it's so incredibly phenomenal that I need to mention it: Prototype 1.6.  It's amazing to me that people actually go out of their way to use ASP.NET AJAX 3.5 (I still find the ICallbackEventHandler interface more productive).  ASP.NET AJAX 3.5 is not nearly as bad as extremists think, but the design is still flawed.  Prototype on the other hand is absolutely incredible.  I've written about Prototype before, but this version 1.6 is even more powerful.  There a A LOT of changes from Prototype 1.5.  It's so good that I no longer call it "prototype/script.aculo.us".  Script.aculo.us is a great animation system, but, honestly, the main reason I used it was for the DOM abstraction in the Builder object.  Prototype now has an Element object to help create DOM objects, thus allowing me to remove Script.aculo.us from most of my projects (it's not as complete as the Builder object, but it allows object chaining-- which greatly increases code readability, conciseness and understanding!).  The Template object is also amazing as it gives you the ability to go far beyond simple String.Format formatting.  The new Class object for OOP is also great.  It's so much easier to use than Prototype 1.5.  Also, being able to hide all elements with a particular CSS pattern with one shot is very useful! (for example, $$('div span .cell-block').invoke('hide')).  It even allows you to use CSS 3 selectors on the most dead of web browsers.  It really makes developing for Internet Explorer 6 and 7 bearable!  Even if I have to use ASP.NET AJAX 3.5, I'll still including prototype.js.  If you do anything with JavaScript, you need Prototype!

 

Links

(0 comments)

Silverlight 1.0 Released

Wednesday, September 5, 2007

In case you haven't found out yet, Silverlight 1.0 has officially been released.  Being a JavaScript developer and having been trained in Game Development I find that to be really awesome because Silverlight 1.0 does an amazing job with graphics and video.  However, you probably shouldn't get too excited as this isn't actually the REAL Silverlight we are all waiting for.  The Silverlight that will make people jump for joy is Silverlight 1.1 (I highly expect this to be renamed to Silverlight 1.5 or Silverlight 2.0 before it's released), which should be released sometime in the next year.  Why Silverlight 1.0 is released in such a castrated form is beyond me.  I'm hearing all kinds of Flash experts slam it left and right and every million or so insults they actually get one that's right.  I'm not sure why Microsoft's marketing did it this way, but I'm sure they have an awesome plan for it (the marketing team isn't stupid-- there is a reason it's a multi-billion dollar corporation).  I'm very anxious to see how this marketing tactic works.

As I just mentioned I've been hearing Flash "experts" say all kinds of things about Silverlight and rarely, rarely, rarely are they ever true.  For instance, two days ago I actually heard someone say "...then you have Microsoft's Silverlight and what a piece of junk.  I mean... come on... it doesn't even do video!  How can you expect to compete with Flash when you don't even support video!"  Of course, when you say something with a smile and the right tone, you immediately get people to agree with you.  In reality, however, not only will Silverlight 1.1 support video, Silverlight 1.0 supports video (in all kinds of awesome ways).  Furthermore, video is one of the core features of Silverlight!  In fact, Scott Guthrie over at Microsoft has an awesome blog entry published last night discussing some of the great media intensive features Silverlight brings (he also shows clients actually using Silverlight!)  So, I'm not sure were people get their information (an Adobe forum??) but it's clearly a product of propaganda, not of truth.  Perhaps people should watch demos of a technology and ask a Silverlight expert about the technology before listening to the anti-Microsoft Flash advocate's explanation of their competition.  It's just a thought.  Actually, that idea could go into every area of life.

In one sense Silverlight isn't going to touch Flash.  That is, in the Silverlight 1.0 sense.  This version of Silverlight doesn't do anything but video and graphics.  If you want to do more, you're going to be building your components by creating them from using graphics components.  However, in another sense there is no competition between Silverlight and Flash because of a simple DOA: Flash is Dead On the Arrival of the next Silverlight.  Period.  If you want to do comparisons, then it may be better to compare Silverlight with Adobe Flex.  You can't have a fair comparison between Silverlight and Flash.  That's like comparing Firefox to Internet Explorer.  Firefox is a development integration and web suite where as Internet Explorer is a COM component thrown into a shell application.  Flash does all kinds of awesome animations and graphics, but is slower than even Java (and that's slow!) when it comes to applications whereas Silverlight is WPF for the Web backed by the power and depth of the .NET framework and by CLS languages.  Flash requires that you cough up hundreds of dollars to use an extremely non-intuitive timeline based system whereas Silverlight allows you to use anything from notepad to Visual Studio and follows a much more intuitive event based model (Flash can do events and SilverLight can do timelines, but I'm talking in general).  Furthermore, Silverlight is designed after the XHTML/CSS and WPF model of design and development separation that allows developers to do what they do best and designers to do what they do best at the same time in the same project with no conflicts.  Where as in the XHTML/CSS model, developers create raw XML and designers create CSS designs and in WPF/Silverlight developers breath the life of logic into a solution while the designers are breathing the life of beauty in to it.  One is using Visual Studio and the other is using Expression Blend.  Or one is using Visual Studio Express and the other is using... um... Visual Studio Express.  You don't need expensive tools.

Something I don't think people realize that Silverlight isn't all that new.  It's basically "WPF for the Web".  Personally, I think the naming is kind of weird.  I mean, it seems completely backwards.  WPF/E was the project codename and Silverlight is the product name.  That sounds like the opposite of what Microsoft's naming people usually do.  You would think that Silverlight would be the project codename and that WPF/E or "WPF Web Edition" or something would be the final product name.  It's with the name of Silverlight that people get the idea that Silverlight is a completely new Microsoft technology, when in reality it's simply "WPF for the Web".  You need to learn WPF before you get near Silverlight (unless you just want to be a hacking coder, not a professional) and you really need to learn .NET development before you learn WPF.  It's an incredibly powerful technology that seamlessly fits in with the many other .NET technologies.  If you try to jump into Silverlight without learning WPF you won't have a clue what's going on.  You will be completely confused why the technology even exists and probably go off telling people that Microsoft made a new useless technology simply to take over a new market.  I expect that to be exactly what the Flash people will be doing.  Also, if you try to learn WPF (or ASP.NET or WCF or any other .NET technology) without understanding the fundamentals and paradigms of .NET, you will probably hate those technologies and complain about how hard .NET is to learn or use.  I've seen this before and it's always based on ignorance of .NET or confusion of .NET.  So, if you go to hit up Silverlight, make sure you understand WPF and .NET first.  I don't mean you "did some projects" WPF or .NET.  Your experience has nothing to do with your skill.  Did you study the paradigms and philosophies of .NET and WPF?  Do you understand dependency propertiesRouted eventsXAML? No? Then you need to fulfill the prerequisites first.

Related Links

(0 comments)

Silverlight 1.0 Release Candidate Finally Out

Friday, July 27, 2007

For those of you who don't know, Silverlight 1.0 Release Candidate has been released.  If you haven't tried Silverlight out yet, this would be a good time to do so.  Be warned though: you need to know the fundamentals of Modern JavaScript to work with it.

In an effort to help educate the community on these topics, if you re not familiar with Modern JavaScript (i.e. multicast events, closures, anonymous functions, Ajax, prototype orientation, namespaces, etc...) please send me an e-mail and I will advise you.  Having said that... in almost every case I'll probably tell you to go buy Pro JavaScript Techniques by John Resig.  Oh any btw... being able to do validation or form processing in no way means you know JavaScript :)

(0 comments)

Extremely Misunderstood Software

Friday, July 27, 2007

Today I was thinking about some of the misunderstandings going around about software. Actually my life revolves around misunderstandings in every area of my life (not just my life in technology!) and I'm usually thinking about it in some respect. I can recall back to early 2004 when I was the black sheep in both the Microsoft AND Mozilla communities for promoting .NET *and* web standards. The Mozilla-ish (open-source) guys would mock the severe inefficiencies and painful security flaws of .NET (though they never ACTUALLY used .NET!) and the Microsoft-ish (.NET) guys would mock call me personally unrepeatable names for even suggesting that web developers should learn the foundational principles of JavaScript, CSS, and XHTML before they starting asking a load of "how do I..." questions. Now while the open-source community has wised up a bit, I still get extremely vile insults from the git-r-done areas .NET community where even mentioning proper development or training will get you killed. In any case, this is my life and like I say... not just in technology. Basically, everyone hates me :)

So, here's my concise (yeah like I'm capable of that) list of software that is EXTREMELY misunderstood. I'm not going to go into any detail except put a single line by the item which should give you a hint as to what the software really is. This is important: if you understand one of the confusions, that confusion is analogous to each of the others. For example, if you know how insane it is to compare SQL Server 2005 to MySQL then, guess what... you now understand why it's insane to compare Firefox to IE or LLBLGen Pro to .netTiers or NHibernate. You just can't do it! Yet, people all day long give me unjustifiable grief about this stuff and I am forced to spend literally 70% of my time in marketing instead of programming!

I'll shut up now... here's the list:

List of Extremely Misunderstood Software

(0 comments)

Moonlight: Mono's Silverlight

Monday, June 25, 2007

Here's something rather interesting... the developers on the Mono team "hacked" Silverlight and it only took them 21 days to do it. They are calling their own product "Moonlight", which I have to admit is a much cooler product name than Silverlight.

Project details as well as some internal information including a bit of information about Silverlight internals are are the link below. Even if you care nothing about Mono or Moonlight, if you have any interest in Silverlight at all you should check it out simply for that.

This is actually really cool as it should seriously help promote Silverlight as a de facto standard worldwide, but I doubt anyone will be making a documentary called "21 Days" any time soon.

(0 comments)

Silverlight's Adoption as Public De-Facto Standard

Wednesday, June 20, 2007

Recently there have been comments floating around the internet and around conferences that Microsoft's Silverlight needlessly uses XAML as its mark up language where it should have used SVG (Scalable Vector Graphics). The argument here is based on the idea that since SVG is a vector technology accepted in all web browsers except IE, Microsoft should have used it instead of XAML and then simply added support for SVG to IE. While this seams to some to be a valid criticism and a good point to some of the web standards world, it is absolutely groundless and carries no weight.

Silverlight can be viewed as a web extension of the Windows Presentation Foundation (WPF), a .NET 3.0 technology and not simply as a new web technology. As such, it makes sense that Silverlight uses XAML, not SVG. If Silverlight were based on SVG, then there would be a chasm between Silverlight and the .NET Framework, but as it stands Silverlight's use of XAML makes it part of the .NET family. In fact, it’s important to note that elements in XAML usually represent objects in the .NET Framework; this would simply not be possible in SVG. Therefore, by choosing to use XAML over SVG, Microsoft kept SVG pure by not add proprietary technology to it.

Furthermore, SVG is "Scalable Vector Graphics" and as the name suggests it for vector graphics. If Microsoft were to start out with SVG as their base technology they would quick to add UI controls to it thereby altering it making it a Microsoft dialect of SVG, which would not be SVG at all. This would take the entire web world back to the same disasters that were seen in proprietary HTML elements, proprietary CSS selectors and rules, and proprietary JavaScript dynamics (i.e. "DHTML behaviors"). Aside from the architects and developers on the Internet Explorer team, the world, including Microsoft as a whole, thankfully has a lot more respect for specifications and standards than this.

Standards advocates should be very satisfied with Microsoft's decision to start from scratch on this one. Standards, as they are normally referred to as, deal with standardization and thereby allow everyone to talk about the same technology without proprietary terminology or technology. If Microsoft sets an explicit syntax on a well-defined language, publicly states the specification for the language, and makes it a multi-platform language, then the world has basically the same result that a standard would have (this point will be hit again in a moment.) While it's true that "popular" doesn't make things right (something most people learn early in high school) and that statements about "most people" do not mean a single thing, having a well-defined technology set with a set specification does make it a first class technology.

We can see this in the ECMA-334 (C#) specification. Microsoft could have taken JavaScript and forced it to obey the Common Language Specification (CLS) and pawned it off as the primary .NET Language, but they instead chose to create something entirely new and then publicly displayed the specification for it. So when .NET guides are written the samples usually have code for C# and VB, instead of JScript and VB. Those who criticize Microsoft for not using SVG as their client-side technology probably applaud Microsoft for creating a new programming language.

Lastly, it should be noted that one of the primary purposes of using the web as a platform is to make something more accessible. People should be able to use any sufficiently advanced web browser to access a web page or web application anywhere on the entire Internet. Truly, even if an application is created in a corporate environment, if the technologies used are proprietary to any one specific web browser, the primary purpose of using a web browser is defeated and using a smart client would probably give a much richer experience and result. So, while it is true then that the use of proprietary technology, such IE specific content, defeats the entire purpose of using the web as a platform, if a technology is spread enough, is on enough platforms, and allows integration into their current environment (i.e. Firefox, Safari, Opera), it doesn't need to be a standard because it would achieve the same result as a standard. Flash is probably the best example of this.

In conclusion, there should not be much fuss about Microsoft's new "Flash-killer" using what some would view as private corporate technology. As long as there is support for Silverlight in Firefox, Opera, Safari on Windows, Mac OS X, and Linux and a seamless installer experience, there shouldn't be any problem with a rapid world wide adoption of this new technology. Hopefully Silverlight's adoption into the web as a de-facto standard will silence many forms of critisism about it and help prompt developers to do a better job of creating intranet and Internet solutions for muliple platforms and multiple web browsers.

(0 comments)

Reflecting Graph Video Demo

Sunday, May 13, 2007

For those of your who have not installed Silverlight, below is a link to a video of the demo. As you will see it works perfectly in Firefox and IE.

Links

(0 comments)

Reflecting Graph Silverlight Demo

Friday, May 11, 2007

In one of my Ajax applications I wanted a REALLY cool interface for some of my data modeling. I was a bit stuck until I heard that Microsoft published a beta of Silverlight 1.0 (an actually working one too!) This of course opened up an entirely new planet of new design possibilities.

The design that I came up with was a tree model where each element was a node in a mesh like structure where the user can move the elements as well as the entire structure in one smooth motion and where the user can zoom in and out with their mouse scroller... something that was incredibly simple to build in Silverlight.

To demonstrate what I built, I would like to use toned-down version of the same thing to show a simple type reflector with a Silverlight interface. In this demo, simply select an assembly and select a type. The type will show up as a graph with branches for reflected members, organized by methods, properties, and events.

The mechanics of this is actually really simple. First, define a few canvases so that an inner canvas can scale and translate to give the effect of a zoom and canvas movement. Second, have a method that accepts a JSON structure containing the model for your tree. In the iteration plot the ball element, the text as as well as a line that goes from itself to its parent. The trick in this step is to get the math right to know where exactly to plot the element. I'll discuss this in a bit. Lastly, watch for mousedown, mouseup, and mousemove events on the elements and the on canvas as well as mouse scrolling events on the canvas.

Placing the elements on the screen is really just basic geometry. We know that the first element can go anywhere and that its sole purpose is to set a positioning basis for all other elements. Plotting the children is just about as easy. For perfectly symmetrical elements, you just have to plot them at equal points from each other around a 360 degree radius. For mathematical details on this, see the essential mathematics page below.

Having symmetrical elements is all well and good, but it's ugly and nasty. [See image 1] So, to take it a bit further, I played with the angle a bit. If the element was the first child, I just plotted it normally via symmetry. If not, make the angle an increment of 45. This will just make the children the same length from each other regardless of how many there are. [See image 2] After this, I scaled down the separation of the elements by how many elements there were. [See image 3]

Next, I wanted to make sure the children were pointing in the same general direction their their parents pointed in. So I subtracted the angle of the parent (minus 90) to make it go in the same general area. Remember that all the elements are grouped together, so now we are moving groups of elements, not just a single element. [See image 4]

At this point it doesn't look too bad, but the child groups don't really line up with their parents. For them to line up I needed to add 45 degrees plus half the radius of the entire child set (another 45 degrees scaled by how many children there are). [See image 5]

Now we have something that looks like it it could grow nicely... however, it would be nice if it didn't look like a robot built it. To give it a more organic feel I added a random angle to every element. No, it's not the most sophisticated method for creating a more natural look, but it does work rather nicely. [See image 6]

As far as the events are concerned. If you get a mousedown on an element, you are in dragging mode and when you get a mousemove, adjust the element, text, and line accordingly. Silverlight will automatically redraw the line based on the new X, Y endpoint of the line. If you get a mouseup, then you are no longer in dragging mode and mousemove, doesn't do anything. If you get a mousedown that's on the canvas, then you simply need to adjust the translation of the canvas. If you get a mouse scroll simply, adjust the scaling of the canvas. It's extremely important to take the scaling into effect when you work with the moveable elements as the coordinate system completely shifts. In the provided demo, I added a few adjustments for this, but it could be much better it a live version.

As a closing note, this demo can also act as an example for an asymmetrical schema Ajax service. The service I wrote here accepts an XML message, but responds with JSON data. It's important to remember that the focus of communication is on receiving, not on transmission. If a person from France and a person from German want to have a conversation and each CAN speak the other's language, but understand their own flawlessly, the one from French may speak German so as to maximize communication and the person from German may speak French to the same end. So in this example, JavaScript speaks XML to .NET, which can easily deserialize it to a usable object and .NET speaks JSON back to JavaScript for easy direct use.

Related Materials

(0 comments)

Converting JSON to XAML

Tuesday, April 17, 2007

For reasons beyond human comprehension, the world felt like making an huge deal about Microsoft "revealing" SilverLight even even though WPF/E has been known about for some time now and even though nothing technical has changed even in the slightest with the simple change of a name. Having said that... it will probably be an awesome technology and I'm sure I'll be marinating many of my future applications in it. Editing XAML in notepad is much more appealing to me than being forced to use the overpriced and overly complicated Flash.

As cool as that is, however, since most of the work I do involves pure Ajax/JavaScript clients with almost all .NET coding at the service level, I definitely find JSON (which IS a JavaScript object) easier to manage than XML (which CAN BE a JavaScript object). So, in one of my applications I have the service that provides graphical information to Silverlight in the form of JSON serialized XAML, which will then be converted into XAML.

Here is an example of something the service would provide:

var jsonElement1 = {
        'Ellipse': {
        'Canvas.Left': '130',
        'Canvas.Top': '130',
        Height: '200',
        Width: '200',
        Stroke: 'Red',
        StrokeThickness: '10',
        Fill: 'SlateBlue'
    }
};

No, it's not human readable like XML is, but it's what JavaScript loves to see and it's what my service creates. Also, no, this is done for for efficiently purposes. This doesn't lower the service "message" size in the slightest, but it does however help to keep a consistence programming model across all my service calls. Furthermore, given that the data was in a database and not in XAML on the server, there's no real overhead. If, however, the data was in XAML on the server it would be a sign of pure stupidity for me to convert that to JSON and then back to XAML.

The parsing for something like this is actually really simple: just iterate through the JSON objects and arrays and creating an XML tree from it. As a reminder or reference, with regard to XML in a web browser, Firefox uses document.implementation.createDocument for XML while IE uses the MSXML2.DOMDocument COM object. Furthermore, Firefox is more strict in its usage of XML than the more familiar COM model that IE uses.

Here is an example of what I mean:

var doc = null;
if(DOM.implementation && DOM.implementation.createDocument) {
    doc = DOM.implementation.createDocument('', '', null);
    Xaml.ScanJSONElements(doc, data, doc);


    var xmlSerializer = new XMLSerializer( );
    return xmlSerializer.serializeToString(doc);
}
else {
    doc = new ActiveXObject("MSXML2.DOMDocument");
    Xaml.ScanJSONElements(doc, data, doc);
    return doc.xml;
}

As you look through the Xaml.js file provided, you will also see that Firefox is very explicit about it's namespaces, while the COM model figured you will take care of them. There's nothing wrong with either approach, it's just something you will want to be aware of if you ever create XML in JavaScript.

Links

(0 comments)

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.

Powered by the Minima Blog Engine, a .NET 3.5/LINQ based blog engine.

Mini-icons are part of the Silk Icons set of icons at famfamfam.com