Okay, so it wasn't really a three-person job, but I did make an interesting observation about teamwork. The best thing about working together is that if you have trouble doing something, it's either because you missed something hard, in which case other people are confused too and you don't feel dumb, or you missed something obvious, in which case someone can step in and do it and you aren't stuck on something stupid. This is another magical facet of the mutual motivation technique I've been talking about lately.
Yesterday I updated Schedulator to work with Google Code's issue tracker, which I started using for a few projects lately. The new plugin is only 184 lines of C# awesomeness, suggesting that my plugin model is actually pretty good.
Looks like I'll be going to Spain for about 30 days in April.August 28, 2017 04:19
Goodbye NVS, hello Versabox!
What have I been up to lately? Well, lots of things, but one of my current favourites is Versabox, a redone Nitix Virtual Server that uses a modern Linux distribution, allows you to install more than one guest system at a time, makes it really easy to generate application-specific images that are "diffs" against a basic image, and (someday) should be portable to host operating systems other than Nitix.
As part of this project, I have discovered and documented the long-lost instructions for downloading a free Nitix trial CD without involving salespeople or waiting for an email. This is great in case you want to try out Versabox in an also-free VMware Server session.
You can join the Versabox discussion forums if you're interested in lurking or contributing.August 28, 2017 04:19
"Today" I modified my copy of NitLog to not post entries that are dated in the future. You might have noticed that sometimes I cluster unrelated things into a single post, and sometimes I don't post for several days at a time. Usually this is because I have more than one thing on my mind at any given time, and when I write, I tend to write about it all at once. Then I don't write anything at all for a while (mostly because I don't have time, not because my mind is blank). Furthermore, sometimes I post twice in one day, but NitLog only allows one entry to be "tagged" for each day, so I just date it tomorrow and hope I'm not too inspired tomorrow, etc. That's all fine for me, but what of you, the gentle reader?
Here's my theory. Writers are bursty; readers want their daily fix. NitLog's feature for only allowing one post per day is actually not too bad; after all, if you're writing more than one post a day, you're probably going to overwhelm your readers and they'll start to skim. But I don't average more than one post a day; I simply do it sometimes when I'm bursty.
So I added some simple magic. Now, when I write the 200703/10 entry on March 9, it doesn't appear until March 10. So if I feel particularly prolific on a particular day, I can just enqueue articles and they'll slowly feed out to you at a rate you won't find overwhelming. As a bonus, even when I'm having a dry period, you won't, as long as I keep the queue sufficiently full.
I got the general sense of this idea from Raymond Chen at The Old New Thing, who is reputed to post entries ahead of time and schedule them to appear automagically, one a day, while he's on vacation.March 09, 2007 02:43
Installing Windows XP Embedded in a VMware Session
It's incredibly difficult to find concise, reliable steps for doing this anywhere on the Internet. There are bad instructions, long instructions, and misleading instructions, but nothing that pulls it all together in one place. To my stunned amazement, most people doing Windows XP Embedded seem to do it by actually installing it on their own workstation and rebooting over and over. Honestly!
Seeing as that's completely insane, here are the most concise steps I can come up with for installing it in VMware instead.
- Install the XP Embedded SDK on your non-virtual workstation as usual so it runs at maximum speed (which isn't very fast). Alternatively, do it in a VMware session, and you can skip the following step.
- Install Windows XP (the normal one) in a VMware session as usual.
- Shut down the XP VMware session.
- Create a new VMware disk image that you'll use for your XPEmbedded disk. Add it as the second disk of the XP system you created above.
- Boot the Windows XP session.
- While you're here, run the XPEmbedded SDK's TAP.EXE tool (not TA.EXE!!) and grab a copy of the generated devices.pmq file. You'll need this for building VMware-compatible appliances with the SDK.
- In Start | Control Panel | Admin Tools | Computer Management | Storage | Disk Management, you'll find the super-secret disk management tool that replaces old, reliable fdisk and format. Open it.
- Initialize and format your new disk. It must have an "MBR" format partition table. You probably just want one big partition in NTFS format.
- DEAR GOD, DON'T FORGET TO MAKE THE PARTITION ACTIVE! Sorry for screaming, but I just wasted about four hours on that because the Windows MBR, in all its cleverness, just says nothing and tells the BIOS to boot from elsewhere if you don't do it right. Trivia: at this step, Windows writes an MBR to the partition table sector, and a boot sector to the partition you created. The boot sector is designed to load ntldr, which handles the rest of the boot process.
- Shut down the XP VMware session. You now have a blank disk image with a valid boot sector. Reconfigure VMware to stop talking to that disk image, then move the disk image out of the way. (Don't do it the other way around! If you do, VMware tends to freak out and get hard to fix.)
- Make a copy of that virtual disk and keep it off to the side. You can use it over and over again as a source of new bootable virtual disks, without having to annoyingly format them by hand in Windows each time. It should be highly compressible at this point, so feel free to check it into Subversion and use it as part of your automated build process.
- Download VDK, the unofficial but handy VMware virtual disk loopback driver for Windows. It's a bit buggy (which is why you can't do the above steps without VMware itself), but it works well with disks that are already formatted. Note: vdk.exe doesn't work in a Cygwin shell for some reason. You have to run it from plain cmd.exe.
- Assuming your disk image is called XPEmbedded.vmdk, run these
vdk install vdk open 0 XPEmbedded.vmdk /rw /l:mThis mounts your virtual disk as drive m: on your real workstation. BEWARE: if you have an XPEmbedded.vmdk in the current directory, vdk will use it even if you give the full path to a different XPEmbedded.vmdk. So even though it's good to keep the a copy of the empty one around, it's safest to use a completely different filename for it, not just a different directory. I wasted a couple of hours on this problem too.
- Generate an XP Embedded image in c:\Windows Embedded Images using the SDK and Target Designer, as usual.
- Using Windows Explorer or whatever, xcopy the files from that directory to m:\.
- Close all windows referring to m:, then unmount the disk with
vdk close 0Because Windows enforces exclusive file locks (grrrr...) you can't use the disk image in VMware until you unmount it.
- Create and boot a new VMware image with XPEmbedded.vmdk as the primary disk.
- Congratulations! If you got this far, you have a brand new XPEmbedded system running in VMware!
- Install UniConf for Windows to configure your virtual Windows sytem from its host machine. Oops, did I say that out loud?
Organizing the world's information
It's kind of ironic that while Google's mission is to "organize the world's information," I don't really need to organize my own information anymore. I just dump my notes into this journal, call it a blog, and use Google to look it up later in case I need it. Perhaps the overall global level of information sanity is a constant?August 28, 2017 04:19
The best ideas are non-obvious
- Don't worry about people stealing your ideas. If your ideas are any
good, you'll have to ram them down people's throats.
-- Howard Aiken, via Y Combinator News
I first heard the above quote when I was taking an Entrepreneurship class (GEN E 452, if you must know) in university. It's absolutely true. I'm the sort of guy who has lots of ideas, some good and some bad, and universally, the best ideas turn out to be the ones I had to "ram down people's throats." (Politely whenever possible, of course.) But the weird ideas I have that people like instantly are the ones that make me the most nervous: if it's such a good idea, and so easy to understand, why aren't we already doing it that way? There's probably an excellent reason, if you look for it.
And that ties in to a problem the world is having right now with what I call "stupid entrepreneurship." It's not to say that entrepreneurship is stupid, it's just that most entrepreneurs are just starting stupid companies because they really don't know any better, and worse, they're worried that someone will steal their idea, so they don't tell anyone about it - and telling people about your idea is the best way to find out your idea is stupid, if you're willing to pay attention.
Now, I'm a little bit secretive about what my new company is doing, mostly for potential patent-related reasons. But I've talked to various people individually about it, and given some good clues, even if I haven't exactly been posting the source code in my journal. And I've gotten good feedback, and updated my idea, and I know for sure that it's not obvious, and I also know that people can understand it if I learn to explain it well enough. That's the interesting challenge when you've got a new idea: it has to be non-obvious and yet explainable so that people can, in fact, understand.
But non-obvious doesn't make it good
I've been following some entrepreneurship-related forums lately, and they've been depressing me, because even the least depressing conversations go like this: "I have this idea, but everyone thinks it's dumb. Is it?" "Don't listen to everyone else. The best ideas aren't obvious and you'll have to ram them down people's throats."
This is faulty logic. Just because you have to ram it down people's throats doesn't mean it's good! More often than not, it means it's a terrible idea! Please, dear God, do listen to everyone else! And if you really listen, and your idea really hasn't been blown apart, then maybe it's a good idea. Stubbornness is a virtue - sometimes.
I realize people will have some trouble applying the above general advice, so let me be extra clear.
The world doesn't need another video or photo sharing site, especially a thematically-restricted one. Or another way to meet people. Or another way to do online advertising. Or another search engine, particularly one with geographic/local/regional/topical focus. Or more metadata. Or a search engine for metadata. Or another collaborative encyclodictionary. Or another operating system. Or another music player applet. Or another programming language. Or another web-based calendar application. Or another RSS aggregator. Or another shopping cart application. Or another tool for building web sites.
It's not that any of those ideas are bad. In fact, they're great ideas. Everybody knows they want one of each of those things. You know, one of them. And there's already more than one, including the best one. Trust me, you're not the person who's going to make the best one, because it's already been made, and it's good enough, and the people who made them are all really smart and have more money than you. There are all sorts of things I want that nobody makes right now, because I don't even know I want them and even if you know, you're not making them either. Please, please, please, just make me some of those.August 28, 2017 04:19
What's in a company name?
I've been reading lots of articles about choosing a company name lately. Basically nobody agrees on most of the rules, but at least it's been entertaining to see what they disagree about.
Here are my own rules:
It has to be unique enough that a Google search will find it in the top few links. My last company called itself Net Integration Technologies Inc. (NITI), and to my stunned amazement, it is now the top Google hit for Net Integration. This took years and comes after way too much effort, including lots of press and chrisk's excellent Search Engine Optimization efforts (all clean and ethical, of course). This name was a bad idea. Don't do that.
Despite what people will tell you, the actual domain name is irrelevant. Nobody actually types domain names into the URL bar anymore, because 99% of the time they get spam or domain squatters. For years, NITI was at "net-itech.com", quite possibly the world's most horrible domain name, and none of our customers seemed to care.
Don't pick a long name whose acronym sounds like the British word for "infested with bedbugs." Or, if you do, be sure to make the joke before anyone else does. Trust me on this.
Don't use names that are completely meaningless outside of their expected context. sfllaw eventually came up with our product name, Nitix, which actually follows this rule perfectly: if you call the company NITI, then it's obviously a NITI product, and if you know anything about Unix, the "ix" makes perfect sense. But word to the wise! Random two-syllable words from other languages that end in "a" are not automatically meaningful to people in your target market!
Don't use names that people actually have to modify their punctuation-stripping search engine algorithms in order to query. (I'm talking to you, .NET and C#!)
Don't use acronyms. People can't remember acronyms. Sure, there are plenty of famous companies (IBM) whose names are acronyms; but they were famous before everyone started using the acronym. (I discovered this rule, with great examples, in an excellent book on market segmentation from the 1980's whose name I've unfortunately forgotten.) Also interestingly, note that IBM is three syllables (annoying to pronounce), Nitix, which looks longer, is only two. Pronounceable acronyms are sort of okay, but don't be surprised if people stop treating them as acronyms (ie. the NITI in Nitix isn't capitalized anymore).
Don't use someone else's name and just change a letter or two to make yourself "unique". If you're just avoiding some stupid domain name squatter, then okay, because they'll never be a good Google hit like you with your real company. But if real companies already exist with similar names, avoid them, even if you can legally get the trademark. Trademarks are kind of worthless. Google hits are valuable. We considered calling our new company Banksoft or Bankware (because we make banking software! Pure genius!). But there are already zillions of such companies, including Bancsoft, Banqsoft, Bancware, etc. Who wants to compete with that? And don't even talk to me about World Vision.
Use a name that people can spell. It's not Intergration, it's Integration, darn it! But they never learn. You should.
Don't use a "temporary" name "just for incorporating for now" that you plan to fix later. You won't, because the original name will always be "good enough," and as time goes on, it gets harder and harder to change your name. I've fallen for this trick at least twice. If you need a temporary name just for incorporating, just use a government-assigned unique ID number company. Trust me, it's worth it.
Where Versabanq came from
So while we're here, where did the name Versabanq come from? Did we follow the above rules? And what's with that Q?
Like I said above, we actually thought about keeping it really simple, ie. Banksoft or Bankware or something, but that had been done to death. We tried making up words, but that made them hard to remember and they didn't sound at all banking-related or give you any idea at all what we did. If your name gives people a clue, it can get you past the blank stare and into an interesting conversation.
So we really wanted to have "bank" in the name. But we couldn't spell it "bank," because we're a subsidiary of a real bank which is heavily regulated by, uh, the banking regulator dudes, and you can't legally call something "bank" unless it's a licensed "bank." We make banking software, we don't do actual banking, so no dice. (Yes, there is a banksoft.com and a bankware.com. But they're not subsidiaries of banks. This is sort of like how you can call yourself a "sanitation engineer" on your business card, even though "engineer" is a legally protected term, because the regulators are happily ignoring you anyway. They're not ignoring us.)
So, banq with a Q. It works in French too. Don't ask me what the French regulators think about that idea. Oh, and the q looks pleasantly like an upside-down b in a sans-serif font. That's why we don't capitalize the b.
And "versa" is a very underused prefix. In fact, a search for Versa shows no interesting hits. (There are presently 56 million uninteresting ones, however :)) So there's definite growth potential here.August 28, 2017 04:19
WvStreams in LinuxFromScratch
That's funny: it seems that Detailed WvStreams build instructions have recently materialized as part of a project at linuxfromscratch.org. I wonder what they're up to?March 14, 2007 13:57
Programming jobs suck?
Apparently an article has been making the rounds lately called Why a career in programming sucks.
Basically, it explains what's wrong with programming as a career and why you shouldn't do it. It's well written, and kind of right, and kind of misguided. It's also annoyingly racist and protectionist, which misses the point completely. Don't you just love people who blame immigrants for all their problems? But nevertheless, he makes a few interesting points. I'll start by agreeing with him and then explain the part he missed.
Here's the bad news: most programming jobs do suck. And worse, if you're one of the programmers with the sucky jobs, those foreign workers will be taking it away from you, probably sooner than you think. Why? Because they're willing to do the same work, sufficiently well or equally well or better, for cheaper. Because foreigners are evil? No, just because there are lots of them, and they're just as smart as you (or smarter), and they really really need the job, and they'll do anything to get it. Welcome to the global economy. Watch your back.
More bad news: it's true! Programming really isn't prestigious! Doctors and lawyers do make more money than the average programmer! And yes, they're more popular and they do get all the girls! (*) Why? Because people who go into law and medicine just plain aren't as geeky as people who go into programming. If you're doing it for the prestige, then please, please, for your own good, take this guy's advice and avoid programming like the plague. In fact, the plague is a really good analogy for how popular and famous programming will make you.
And a direct hit: the "knowledge capital" thing. Yup, all that stuff you learned about programming languages and syntax and tools? Useless almost before you learned it. Programming technique never gets easier. You'll have to be learning new stuff your whole life. Ick! But that's the way it is. If you hate learning, go do something else. Like he says, accounting is a great choice.
Unless you're doing it right
And yet, here I am, a programmer, and I love it, and I also get paid pretty well, and while not exactly prestigious, at least I'm not a total social outcast. Also, I'm not an immigrant (insofar as any Canadian is "not an immigrant" in any realistic sense) yet I don't fear for my job. So while the above arguments are all logical enough, apparently they don't hold true in every case. What's the deal?
The deal is that Canada and the U.S. are positioned as (**) leaders in business and technology. If you're the leader, you get paid more, no matter what you do. But to be a leader, you have to do the work better than everyone else. If immigrants/foreign workers are doing the same work as you, just as well or sufficiently well or better, for cheaper, you're doomed; Larry Smith's laws of economics are against you. I don't have very good advice for you in that case, except to see above and find a "prestigious" or "lasting" profession that isn't so doomed. You're the reason I don't disagree with the article.
But chances are, if you've read this far, you're not actually in that category. Something makes you different from everyone else. Maybe you have a good idea, or you're faster, or you produce fewer bugs, or you think more flexibly than a mass-produced Windows administrator or Java programmer. Maybe you understand the fundamentals of programming and can apply it to other things. In that case, you're unique. Uniqueness is worth money and prestige. Lots of it. And there's not even a limit to uniqueness. The more knowledge there is in the world - and there's more every day - the more interesting problems there are to solve, and the more unique solutions we'll need to solve them.
So that's my advice. Don't just be a programmer. Be a unique programmer. Find your niche, and be the best at it. Then your job will stop sucking, you can stop worrying, and you can just get back to the programming that you were supposed to be doing for fun in the first place.
(*) In related news, doctors and lawyers who are women presumably get all
the guys. Or maybe not. Guys can be scared away by smart, successful
women. On the other hand, geek girls are immensely popular, in the rare
cases where they actually exist. Anyway, I forgot my point.
(**) "Are positioned as" is not the same as "actually are" or "are
agreed to be." Please don't shoot me.
Stupid entrepreneurship, revisited
Hey, I know! Google organizes the world's information using all kinds of clever algorithms that automate the selection and prioritization of information from giant data stores like the Internet, in ways and at a scale that never would have been possible to do by hand.
That means the standard, market-leading way of organizing the world's information is now to automate it using clever algorithms.
Hmmm... how to compete with such a thing? Well, we can't beat them at their own game; they're way too far ahead. We have to completely change the rules of the game. What do all the search engines like Google have in common? I know! Algorithms! They're all sorting the information automatically using algorithms! What if I made a search engine where people had to painstakingly generate all the search results by hand? Nobody else does that! I'd be in a class by myself! Except for those other idiots who are also doing it! It would be pure genius!March 13, 2007 18:41
The Donkeymaster Gets Robbed
"Stop right there. Don't turn around or you'll get a bullet in the back of your head. Okay... well, I guess it'll be the front of your head if you turn around, or maybe the side if I'm really fast. I guess what I'm saying is, I'm pointing a gun at the back of your head. Don't turn around."March 15, 2007 22:31
As I mentioned before, I'm going to Spain for the month of April. I've seen a few other people offer to send postcards from their travel destinations, and Spain is a pretty neat destination, and it looks like I'll have plenty of time for filling postcards with long, contemplative rants about deserts, and my inability to speak Spanish, and man am I ever tired and thirsty and irritable, and so on, so why not?
If you want a postcard from me in Spain, send me an email, with a subject line something like "POSTCARD!!!" containing your current physical mailing address and I'll see what I can do.
Er, priority goes to requests from people I actually know. But I'm not really all that picky, I guess. We can always get to know each other by sending postcards back and forth.March 19, 2007 17:49
Maximally dumb window management
So everybody knows by now that MDI (Windows' traditional multi-document interface) is bad and you shouldn't use it, even in Windows. Okay, sure. But what instead?
The problem MDI was created to solve is simply the "too many windows" problem. If you're working in an application, say a graphics editor, with a lot of open windows attached to it, how do you keep track of them all? In Windows, the traditional way to do this was with MDI, where you'd switch to the application (using the taskbar, say) and then "inside" that application's main window you'd find a bunch of sub-windows for its documents. This led to everyone always running all their apps maximized, because you had to fit all your smaller windows inside the outer window, and that was completely unusable if the outer window wasn't as big as possible. So it was a big mess, but it accomplished its main goal: your taskbar wasn't crowded with a million little subwindows. Just one big taskbar button for your application.
MacOS deals with the problem in a different fashion. It has core UI concepts of "applications" and "windows", so that you alt-tab between applications, but inside an application, you can switch between individual windows. In MacOS 9, when you brought an application to the top, it would pull all of that application's windows to the top. Frequently that was actually exactly what you wanted: for example, if you had 20 images open in Photoshop but wanted to check your email for a second, then go back, it was nice to be able to just click on any Photoshop window and have all the Photoshop windows back in view at once. Otherwise you'd be digging around trying to find all 20 of them, all buried under your full-screen email window.
Unfortunately, the pain with that was if you ever wanted to have, say, a web browser in one window and Photoshop in a window next to it, but only one of your Photoshop windows because you're (say) trying to compare a web site's look with its Photoshop mockup, you couldn't do it. There was just no way to have your web browser under some Photoshop windows and on top of others. They fixed this in MacOS X: as far as I can tell, you can click on any window to raise it to the surface, but alt-tabbing to an application or clicking an application on the dock will raise all of its windows. So you sort of get the best of both worlds.
As a digression, I really like ion, which makes it so easy to arrange and organize your windows into multiple workspaces that these problems largely disappear. Of course, it creates other problems, so it only works for me, not everyone else.
But back in the world of Windows, as I mentioned, MDI is deprecated. You're not supposed to use it anymore. Instead, we have two awful alternatives: the "combine similar taskbar items" option for the taskbar, and tabs, eg. tabbed browsing in Firefox. Both are better than nothing (for example, web browsers done the SDI way just resulted in a million taskbar buttons, one per window, which was why they made the "combine similar taskbar items" option in Windows XP in the first place). But both also fail the user pretty badly. "Combine similar taskbar items" is a huge copout, because you lose your sense of spacial memory the taskbar normally gives you. When you minimize a window or switch to a window, you see a little animation of where it went on the taskbar. When you combine similar taskbar items, they're all stuck in a little submenu on the one button, so when you want to switch back, you have to read the little titles to find the right one; your spacial sense is wasted. Never mind the fact that you now have to click twice instead of once to switch windows.
Tabbed browsing is better, but not quite right either. Really, it's just a slightly less annoying version of MDI. Less annoying because you can use your spacial memory (with MDI, you usually had to use the Window menu, ie. the annoying part of the "group similar taskbar items" option). But also less flexible, because there's no way to display two documents side-by-side. Imagine if Photoshop used tabbing between images: useless! (In fairness, the hybrid model used in Firefox, where you can open a new window or a new tab, is a really good balance. I just wish there was an easy way to "convert this tab into a window" or vice versa.)
But worst of all, and I can't believe I'm saying this because it's newer than all the others, is the amazing feature I've found in Microsoft Office 2003 and which has now been cloned in Adobe Acrobat Reader. In a fit of brilliant engineering, they've managed to combine the worst features of all of the above. It works like this: actually Excel and Reader are MDI applications, but they try to hide it. When you open a new document, it appears as a separate taskbar button. But when you switch documents using the taskbar, it replaces the visible document window with the new document. So it's impossible to see two documents side by side, but it also crowds the taskbar with extra buttons! As a bonus, when you click the X button to close the window, it assumes you want to close the whole application - which I can live with in Excel, because it asks "do you want to lose all your changes to 5 documents?" but in Reader it's supremely annoying because it notices I haven't modified anything (that's why they call it "Reader") and just closes them all. And for added bonus confusion, in both apps, if I close all my documents but don't close the application, the last document window morphs into an empty application window (with a different icon and everything!). When I then open a document, it morphs back. But if I open a second document, well, that's totally different - it creates a new taskbar button in that case, of course. And never mind the fact that Reader is completely worthless without a document loaded. In Excel, it makes sense, because I can do File|New and start a new one; but you can't do that in Reader. I'll have to File|Open, which is no less work than just opening the file in Explorer.
Ahem. In other news, "group similar taskbar items" is actually done right in an excellent free Windows utility called Taskbar Shuffle. Among other things, it allows you to drag around your taskbar buttons to put particular windows where you want them (eg. Outlook is always on the far left), taking extra advantage of your spacial memory. It also has a great option for "keep windows of the same time side-by-side" - no, not grouped as a single button, but merely spacially close to each other. This makes it much easier to find related windows, especially if you're like me and tend to open a lot of terminals simultaneously. If you use Windows, I highly recommend it.March 21, 2007 19:54
Pacific and Western / Versabanq Interview
- I don't think the market really understands us - they probably
perceive us as just a small Schedule I bank when actually we're a software
company that has a bank license.
-- David Taylor, Pacific & Western Bank of Canada
Wall Street Reporter has an audio interview with David R. Taylor, the illustrious president of at least two companies, one or the other of which now employs me (depending who you ask). He talks about what the bank does and how our software fits in from a business (as opposed to technology) point of view, and the amazing profitability per man-hour of his bank. Free registration required.August 28, 2017 04:19
Gets Stuff Done
Netflix has unlimited paid vacation days for employees - and they don't trade salary in exchange for it, as we tried to do with dial-a-vacation. They just judge people on the quality of the work they get done, not when/how they do it.
It's brave, and very interesting. What prevents people from abusing the system? Ethics?August 28, 2017 04:19
ExchangeIt isn't so bad
Other programs, which earn their developers lots and lots of money, appear to do much worse even after years and years of effort.
Disclaimer: Okay, ExchangeIt 1.0 was kind of bad, but it was a 1.0. And okay, I'm still not sure why we decided to write a high-performance, high-reliability network server application in perl. But we actually made it work in the end. I'm kind of impressed.March 28, 2007 18:03