Whether to make money with software

February 3rd, 2008 Open Source, Safe For Seneca

By Andrew Smith

For many years I have been asking free software fanatics – how will you make money if your software will be taken (legaly) for free by your competitors? Sadly the best answer I ever got was “you’ll make money from support and other services”. Which is good when you can get it; but you can sell support and services for proprietary software just as well – so by open sourcing your software you, as a business, don’t have anything to gain and have somethiing (perhaps a lot) to lose. (There are a handful of exceptions, but I’m talking about the majority in the market today.)

Earlier I finished watching Steal This Film II. It was actually a lot better than I expected. I expected a bunch of propaganda about how the MPAA is suing 12-year-old girls. It’s far from being balanced, they don’t even bother talking about how today’s industry is supposed to deal with it but they kept hammering on this point – it is the way it is, you can’t do a damned thing about it.

Now, I am not well known for this, but I do pay attention when someone has something worthwhile to say. And it suddenly dawned on me: if people don’t pay for music, movies, or software these days, a discussion about whether it’s moral, ethical, or legal belongs in academia. It doesn’t really matter whether copying software for free on a large scale is the right thing to do. What matters is that there is no demand in the market for software priced so that the creator gets a return on investment.

This is rather ground-shattering for me. I always believed that in capitalism one who makes a good product deserves (both morally and legally) to get a reward. As opposed to communism, where one does as much as he can and gets as much as he needs.

Though my understanding of capitalism hasn’t changed, I realised that there is a strong factor affecting the marketability of software that isn’t written in any book I’ve read and isn’t talked about very much. That is – if people can steal it without getting caught, they will.

What conclusion to draw from this? I could do many. But since I’m a pessimist, I will temporarily give up on writing general-purpose applications. Things may change in the long run and maybe not. But for now, for better or worse, it’s not financially feasible. Luckily for me, I still have options in my career.

How is it different?

January 28th, 2008 Open Source, Safe For Seneca

By Andrew Smith

Are you one of those people who think all software should be free? I don’t like you. But that’s besides the point, I’m going to look at how your views might apply to other very similar products and maybe that will be interesting.

In the paragraphs below – when I say positively ethical I mean progressively ethical, that’s as in more than just ok.

Book authors
A writer sat locked up in his house for a year, and wrote a book. He then took that book to a publisher, who thought it would sell, and got an agreement to receive royaltees off book sales for his writing.

Is it positively ethical for you (another publisher) to buy one copy of the book, print a few thousand copies, and sell them at half price paying no royaltees to the author who spent a year on it?

Car designers
I don’t know what they’re called – the people who actually draw the shape of a car. You are a designer working for Porsche, and you drew up the 911 (those photos don’t do it justice). You wasted a tonne (literally, a tonne) of paper going through contless revisions, to make it perfect. Porsche made it happen, and sold one to Ford Motor Company.

Is it positively ethical for Ford to copy the car’s design, make fifty thousand Ford 912s, and sell them half price, without paying a dime to Porsche?

Fashion designers
You are Calvin Klein. You work for a year coming up with the definition of style for the next few months. You sell one set of clothes a fashion junkie, who is actually working for a chinese sweat shop.

Is it positively ethical for the chinese sweat shop to make ten thousand copies in a few days and start selling them in stores at 5% of your price before you even get your stuff in stores?

Electrical and Electronic Engineers
Say you’re AMD. You designed the Tauron 25GHz processor. You sell one to Intel.

Is it positively ethical for Intel to use their magic 1-minute reverse engineering tool (say there was such a thing) to copy your design, make five hundred million Pentium XXV processors, and sell them at a discount, since they didn’t spend any money on design?

If you answered yes to any of the above – you’re a sad, pathetic human being. You have no marketable creativity, and maybe you’re not very bright. You just aren’t capable of understanding the value of talent, and the ammount of effort it takes to put an abstract set of ideas into a less abstract (but still not physical) design. You should be ashamed of yourself.

If you answered no to all of the above, then tell me – how is software any different? I’m all for hobbyists giving away their work if they please (I do it myself quite a lot), but what gives you the right to say that anyone who isn’t willing should work for free?

GPL Quicker Fucker Upper

January 14th, 2008 Open Source

By Andrew Smith

This is a vague idea I got recently and will try to work through as I’m writing this post. I got the idea in the first place is because I’ve been severely dissapointed by open source in the last few months (I’m ok now); and as the GPL fanatics are the worse of the open source crowd – I concentrated my anger on them. That’ll teach them not to piss me off again.

There are 2 flavours of GPL – the GPL and the LGPL. Each can be applied to libraries.

One is allowed to link to an LGPLed library and not release his own source code. One is not allowed to do that with GPLed libraries. If you link your program to a GPLed library you have to make your program open source. This is really annoying sometimes. For example if you use the free version of the QT widget toolkit your program must be GPLed. Not just open-sourced, mind you, but licenced under the same GPL version as the library you’re using.

I think I found a way around that. Let’s look at the original scenario first. Your program wants to use function doSomethingUseful() from UsefulLibrary. You include UsefulLibrary.h in SecretProgram.c to get the prototypes of the functions. So far the GPL probably has no effect, the header files are usually not covered by the GPL, but it doesn’t matter.

Because in the next step you link your program (cc SecretProgram.o UsefulLibrary.o -o SecretProgram) to the library. And this is where the GPL forces you to make your program open source. Even though you haven’t modified the GPLed code.

how the gpl works

But fear not! Andrew to the rescue! I will solve your problem with the mesed up interpretation of the licence as applying to software that isn’t already under that licence.

I give you a program (the binary is called gqfu). You tell it what functions you want to use from what library, and run it. GQFU will:

  1. Parse the header file and figure out what type of parameters the functions take and what the return type is.
  2. Automatically generate a main() that will take parameters from STDIN, convert them to the proper type, and call the appropriate function in UsefulLibrary.o
  3. For each function X() create a function gqfuX(), taking the same parameters and giving the same return type.
  4. Automatically generate (using some easy built-in logic) code for each gqfuX() function. This code will convert the parameters into an ASCII format, run the gqfuUsefulLibrary program, pipe some STDIN to it and get the result via STDOUT.
  5. Put all the gqfu*() implementations in gqfuUsefulLibrary.h

Once all that is done you build the generated gqfuUsefulLibrary.c and link it to UsefulLibrary. This will create a standalone binary application. The application will act something like a web services provider, except working via STDIO and no bloody XML.

The other half of the generated code (this will sit, for the sake of argument, in gqfuUsefulLibrary.h) will be included in, and built with SecretProgram.c. This part is like a web services requester.

how gqfu works

And guess what? You compile and link your SecretProgram.c without touching anything in UsefulLibrary – not even the header file. If you’re really paranoid, you don’t even have to use UsefulLibrary.h for automatically generating gqfuUsefulLibrary.h. You can just give the desired function prototypes to the gqfu program.

So there you go. Using a quick and easy tool you will avoid ridiculous GPL requirements that would otherwise force you to licence your program under the GPL.

Feel free to steal this idea and implement gqfu. You should even be able to make a business out of it. I bet there are lots of useful libraries that businesses would like to use if only not for the GPL. They would pay good money to avoid rewriting the functionality in those libraries.

I would do it myself, but it doesn’t look like I’m going to have any energy to spare for another project in the near future.

Open source projects competing for manpower

December 23rd, 2007 Open Source, Safe For Seneca

By Andrew Smith

It’s that time of the year when people who have a life go live it fully, and people like me are left bored to death, cause their work is not as interesting :) So I looked over my to do when you’re bored to death list and found this idea – research, or at least articulate what I believe about how a limited number of volunteers can handle an ever growing number of open source projects.

The premise is simple – there is a limited number of people in the world who are capable, interested, and willing to dedicate their time to helping out open source projects.

I’ll expand on that a little. Here are the factors that affect this number:

  1. The total number of people on the planet.
  2. The skills required to do anything remotely useful for an open source project.
  3. The time and will to volunteer for an open source project.

I was going to put that into a formula, but I don’t have the patience.

Anyway, my point is that either we already surpassed this number, or we’ll get there really soon, and either way there is already tremendous competition for manpower in open source.

Projects ranging in scope from wordpress to the Linux kernel wouldn’t be worth my time thinking about if it wasn’t for the volunteers. Often it’s a small group doing the coding, sometimes there is a small group of artists and/or usability experts, a larger group of testers, and an even larger group of bug reporters and evangelists. Get rid of either of these groups and the resulting project will be either not working at all, or unusable, or very buggy, or with such a low rating on Google that you’ll never find it.

So to get an open source project you need volunteers. How does one make a project more interesting to volunteers than the competing project? It’s a science, you can be sure. I’ll put together a list of things I can think of right now, but it is highly unlikely to be complete, or even useful. Just food for thought.

Easiest first – choose a popular domain

What I mean is make your project useful for a large number of people, i.e. potentially everyone would use it – doing a job everyone needs done, working on all the platforms, with features rivaling the proprietary (expensive) software, and cheap (or even better if it’s free).

A project with millions of users will have self-sustaining communities of bug reporters and evangelists, that’s the really great part. Basically you don’t need to worry about this, unless you’re really serious – then you can have a marketing department arranging all sorts of competitions and other events for the fans.

Harder – a good social environment for sociopaths

One of the things your project needs that I mentioned is serious testing. Very few normal people will use alpha/beta/rc versions of software if they don’t have to. Some will, and depending on the popularity of your project you will get a few or a few more volunteers to do this testing, but never enough.

An obvious solution to this is to do what some projects do and have no releases, at all – have the users or the distributors get the software straight out of the version control repository. You don’t want to do this. Unless you have no competition at all your users won’t stick around to put up with your broken-forever software.

What you really want to do is create the infrastructure where the geeks (the abnormal people who will use alphas) will get to communicate with other geeks, brag about their accomplishments, complain violently (but about things that won’t offend anyone in the group), etc.

Basically you want to give the geeks a life. And in return all you ask is that they keep using pre-release versions of your software and file bugs.

The tools to build this infrastructure are well known – IRC, forums, newsgroups. But it’s not as simple as build it, they will come. They would come, but also would a bunch of trolls who would make the imaginary life a worse ordeal than the real life. You need serious moderation, you need to identify and single out the unproductive trolls, and exterminate them with big bangs.

To do this properly you need a person working full-time on this part of the project, and it’s unlikely a volunteer will be willing to constantly do the dirty work.

Hardest – you get what you pay for

One may argue about how critical the testers, bug reporters, and evangelists are. But one must be out of his mind to argue that the programmers developing the core of a product are anything but priceless.

You will never form the groups of people to support, promote, and grow your program if the program isn’t there to begin with, or if you can’t fix critical issues quickly, or if the code is so foreign to all working on it that new bugs get added quicker than the old ones are fixed.

You absolutely need programmers working full time on your program. If it’s small enough and you have the ability to sustain your lifestyle by other means, you can do this job yourself (assuming you’re a programmer). But the larger and more complex the program gets, the more coders you need to take care of it.

Sadly most companies go with hiring rock stars, but I already complained about that, and the fact is – it works. The point is, you need one or a team of capable coders to work full-time on supporting the core of your product. You may allow some features to be done by volunteers, but only because you can do just as well without them.

So you need to hire exceptional minds and offer them whatever remuneration they will find most valuable. It may be interesting work, fame, a great team, but one thing is needed for sure – money. So no volunteers.

Now I realise I’m getting too far from what I started to write about, but I’m too tired to make corrections. So I’ll just add a couple of points.

It is physically impossible for all open source projects to be fully staffed, there aren’t enough qualified people on the planet who have the time. Open source projects compete for the volunteers, and the ones most successful at this get more of everything – more quality, more promotion, even more features. The ones who do it worst die quickly, or stay afloat on the maintainer’s back until a competing project takes over the scene.

Naturally this doesn’t apply to all projects – there are plenty of programs like ‘ls’ which don’t have, nor do they need, volunteers, they are so small and so low-maintenance that a part-time maintainer will keep it in tip-top shape for a long time. So don’t worry if you have a tiny open source project – I wasn’t talking about you. Except of course.. just you wait till you have enough bills to pay :)

Branches are hard

November 9th, 2007 Open Source, Safe For Seneca

By Andrew Smith

Branches always freaked me out. From the day when I read the subversion manual I knew they are hard to deal with and the benifits are dubious.

If you ever had to deal with maintaining a fork, or a project that was forked – the technical challenges are exactly the same.

I imagine it’s reasonably easy to deal with if your commits to the version control system are atomic (e.g. one-liners to fix a bug). In that case you can just make a list of revisions with changes from one branch that you want in the other, and write a script to automate the merging for you. Do this for both branches and you’re fine. But life is not that simple.

There are two rules-of-thumb with version control that are relevant to this post:

  1. Only commit working code.
  2. One commit – one bugfix, or one feature.

The problem is these two are sometimes in conflict. For example: I change 5 files to add a feature and while doing that I run into a bug that’s in my way, I have to fix that bug or else my patch won’t do what it’s supposed to. So I end up with a patch that adds a feature and fixes a bug.

Yes, I could in theory somehow manage to not include the bugfix in my feature patch, but realistically that’s not doable most of the time – it’s just too much work.

Now I need to have a second branch for one of my projects, but I’m afraid to do it. I don’t have the time to go through svn logs, read all the patches, and merge the changes, sometimes manually. So the less profitable branch would end up out of date pretty soon. Which would be a shame, cause I’m rather fond of it.

Someone ought to extend subversion to be able to add flags to patches. So in my example above I could mark the bugfix lines as ‘BUGFIXP1′ and later tell subversion to give me all the patches marked so since some date in the past. Of course a change to a diff viewer would also be needed, so I can do the marking when I’m ready to commit.

I’ll put it on my list of interesting projects to work on but I don’t see the day when I’m going to have time to implement it. Oh well, maybe I’m just overly pessimistic about this.

How evil I have become

November 8th, 2007 Open Source, Safe For Seneca

by Andrew Smith

The Windows port of ISO Master is almost ready. That’s not a programmer’s amost, it really is. All the existing ISO Master functions work, I added a drive selector (that wasn’t needed on Linux), the nag screen works, and I set up a page on the website to accept payments via a credit card or a PayPal account. Take a look:

ISO Master on windows with nag scren

Once I decided to use GTK (rather than rewrite the GUI for win32) the porting went very smoothly. The part that’s left to do is the reason for the title of this post – the key generator.

Once upon a time I was a student, an idealistic person with no need to reconcile my beliefs with the economic reality. No longer. These days I demand to be payed for work that’s not a hobby or a favour. And writing software for windows is neither of those, I assure you.

So I’ll be doing my best to make sure using an unlicenced copy of ISO Master on windows is as painful as possible. For now I only decided on two measures: a nag screen that won’t go away for a few seconds, and a few files on the saved ISOs of the ‘Created with ISO Master demo.txt’ type.

I realise that the more annoying I make it the more likely it is that someone will be pissed enough to fork the project and leave me in the dust. So I’m taking measures to make that difficult too. Which I won’t go into, I have to keep them secret or else there’s no point in having them :)

Back to the key generator. As a minimum I need something to generate a pool of valid keys in a format that allows a much larger pool of invalid keys. A quick search suggests there is no open soruce licence management system of any caliber. Not really surprising.

So I’d have to either pay for one or make my own. I found a simple key generator online for 7$ or so, and that would be a reasonable choice for me if all I wanted was a measure to prevent cats walking on the keyboard from typing in a valid key, but I can do so much more…

I have an idea that would make key generators (the pirate’s kind) impossible. I have more ideas about how to integrate my generator with billing systems, incremental upgrades, and online validation. Hell why not – through some DRM and software patents in there too. And I have the skills to do all of these things.

So I cought myself seriously considering building a grand (but modular) licence management system that would work for any business from a one-man operation to a large enterprise. When I realised what I was thinking I didn’t know whether I should laugh or cry. How quickly I went from a strong believer on open source to proponent of solutions for squeezing money out of users :)

What’s wrong with this picture?

October 20th, 2007 Open Source, Safe For Seneca

By Andrew Smith

ISO Master linux

Well, there’s nothing seriously wrong with that screenshot – I’m talking about the picture of me working on a reasonably popular open source app for Linux (ISO Master). What’s wrong with writing open source apps for Linux? Nothing, unless you need to make money to pay your bills :)

Linux users are so used to getting applications like this for free that they’ll never even consider paying for it. I thought of supporting open source by paying for it once but then I realised I use a couple of dozen programs regularily and there’s no way I can pay for them all so I just payed for the distribution I use (distribution being the entire collection of software).

Having said that – it’s not that one can’t make a living from donations – it’s that one can’t make a living from donations for a Linux app. But Linux is not all there is.

I sometimes get requests for a Windows port of ISO Master. After discussing it with a few people I have a plan in mind:

  1. Port my ISO read/write library to use the Win32 system calls (right now it’s using POSIX)
  2. Write a GUI for Windows. This is harder – since the GTK and Win32 GUI toolkits are so different a port won’t work, a complete rewrite is needed
  3. Keep it open source and free, but make it come up with a nag screen asking for donations
  4. Sell a code to get rid of the nag screen for as much as they’re willing to pay, from 5 to 25 dollars
  5. Force the other ISO Editors to either innovate (be better than ISO Master) or go out of business

Hopefully there are enough users alltogether that there’d be enough of them willing to pay that I’ll recover the expense of making the Windows port. A shot-in-the-dark estimate for how long it will take me to finish it is 3 months part time, so if I make a few thousand dollars that will pay for my time, and anything more will be profit.

One concern I had is that, ISO Master being open source, anyone can take my source code, get rid of the nag screen, and release a rebranded copy. After thinking about it I decided it’s highly unlikely. Since the program is free already it’s pretty hard to compete with, so anyone attempting it will fail.

Another concern is that my competitors may steal my code and use it in their programs. Though technically this is illegal (the GPL licence I use doesn’t allow it) I would never catch them myself, so they may be able to get away with it. But then I decided my competitors’ programs can already do everything ISO Master does, so my competitors won’t get an advantage.

There are some advantages to free software. The biggest one being free promotion. When someone wants to recommend a solution for fixing an ISO, the free program will be at the top of the ‘recommended’ list, since it doesn’t require payment or looking for a crack. Also there’s half a million directories of shareware/freeware out there that will happily list ISO Master.

In the end – this is a small business venture, and (as it is with all startups) I have to put up with the possibillity that I won’t get a return on my investment. In the worst case I will have lost some of my time, and I can live with that risk.

I would like some comments and criticism about this idea, there may be problems and solutions I didn’t think of.

If it works – Barb and Mary will be proud (ISO Master started as a systems project at Seneca).

More on fanboys

October 8th, 2007 Open Source, Safe For Seneca

By Andrew Smith

Oh man, I have quite forgotten how much time I spend around really intelligent people. My decision to solicit feedback from the masses about the Executable Shell idea reminded me just how how lucky I am.

In almost every place I brought it up the response was something like (actual quote):

One good thing about it is that it would make it easier for me to become famous as a 1337 HaX0r. I could write the first really successful virus to infect Linux. Seriously, BAAAAAAD idea.

I expected this sort of response. What I didn’t expect is a huge number of such comments. Sadly there are people who won’t listen to reason in every corner of the world – open source included. I will leave my explanation of why esh will not help anyone become any more a 1337 HaX0r than they could already today; and will instead ponder the role of these excessively protective fanboys in the open source communities.

First – a description for those who managed to avoid them. In most places they are called trolls. They argue for the sake of arguing. They love to shout, insult, and generally do anything to get attention – and since doing something useful isn’t an easy way to get attention, they don’t do much of that. Nonsense, you say? Consider this scenario – on one side of the street a young man helps an old lady cross; on the other side of the street another young man beats the crap out of another old lady. Which side of the street are you paying attention to? :)

I have to admit back in my youth I could have been considered to be a troll. Actually without a doubt I sometimes was. I’m not any longer – probably because I now have better things to do. If I am persistently arguing about something it’s because I truly believe it and not because it makes me feel better. But I’ve never been a fanboy troll, meaning I was never trolling with the pretense of protecting someone else’s interests. Which is what fanboy trolls in open source communities do.

I became aware of them when I posted about the Freedom Toaster to a newsgroup (the group’s name suggested it was a good place to promote the project). One of the replies was:

This is real advocacy! And you managed it without slagging off imagined faults in Windows even once. Well done. COLA needs more like you.

In fact I’ve never even considered mentioning faults in Windows, I assumed everyone already knows about them. So I skimmed some of the other threads in the newsgroup, and my oh my – trolls starting threads and trolls replying; posters with legitimate, stupid, and pointless questions alike were bashed into the dirt without discrimination – total chaos. The group was called comp.os.linux.advocacy.

These people aren’t evil, they’re not consciously trying to get into anybody’s way. They’re just socializing. It so happens that they’re ignorant of the issues brought up by outsiders coming in for help, and when that fact is pointed out they rationalize their behaviour with reasons like “i’m just doing what I can to help”. And they may be. One of the nastiest trolling fanboys on a forum I visit a lot ended up contributing to one of my open source projects – turns out he knew how to make packages for a certain distribution, and was happy to help out.

Do their motives justify the means? It’s a hard question that I don’t have an answer to. Clearly they turn newbies off, but at the same time: a community of trolls is still a community, and if the community’s raison d’ĂȘtre is using open source software – I have to admit it’s a successful way to promote open source.

Well that’s enough for now. Just one more interesting thing I’d like to share: you know those obnoxious politicians who, when confronted, answer every question with an irrelevant sound byte prepared by their campaign manager? I’m learning that isn’t just because they’re too stupid to come up with a good answer. In my encounters with fanboy trolls during the last few days I exercised a lot of self-control. When a troll would try to take the discussion in a different direction (more colourful, less productive) by asking a pointy question that any self-respecting human being would have to defend against – I would simply state their question is irrelevant and restate what’s good about my proposal. It worked :) In all but a couple of places everyone seemed to accept that at least what I propose isn’t the devil’s snare, and some of the worst complainers even cheered me on for trying to improve usability, hopeless though my attempt may be. Maybe those lame-ass politicians are actually pretty bright and simply dealing with trolls in politics?

Who would have thought you can learn about such things just by using open source :)

esh

October 6th, 2007 Open Source, Safe For Seneca

By Andrew Smith

After getting a lot of feedback from a lot of people about on last post I decided this is too important an issue to let be. I am now convinced more than ever that the inability to run downloaded programs is the result of stubborness (very common in open source communities), and I have to do what I am able to fix it.

I got a couple of good ideas from the feedback – one especially important: the esh program should display a warning before executing the shell script. So I made a prototype implementation, here’s a screenshot:

esh GUI

Also I realised that it makes no sense to have a new file extension (.esh) because many file managers determine the file type using the file’s mime type and not the extension, and since there’s no reason why it shouldn’t work with all shell scripts that’s fine.

I associated shell scripts with the esh program I wrote, and what you see in the screenshot is the dialog that came up after I double-clicked on testshellprogram.sh (which doesn’t have execute permissions).

It does, of course, execute the file if I press ‘I trust this program’.

I started a webpage for the project, to keep all my best ideas on there.

Execute a download

October 5th, 2007 Open Source, Safe For Seneca

By Andrew Smith

Some Windows and Mac users will be surprised at this, some will laugh – and well they should. On Linux it’s not possible to just download a program and run it, not even if it’s a program for the right platform. How stupid is that?

The problem is that (probably for no-longer-relevant security reasons) any file you download using a web browser (over HTTP or FTP) will have read and write permissions for the user, and read (or nothing) for group and others – in other words -rw-r–r–, or 644. A double-click on the file in a file manager (or on the desktop) will get the system to think that it’s a data file that needs to be opened in another program, and usually a dialog will come up asking you what program you want to open this file (program) in. Arrrgh!

I’m asking around for a solution, but I suspect there is none. If that’s the case maybe I’ll try to fix it myself – the solution is a couple of lines in C.

Some background: it is possible to have a shell script (let’s call it program.sh) that has more than just shell commands. For example the Loki games installer is a shell script but it has a GUI and a few hundred binary files (possibly in an archive), all this in program.sh. There are other examples of this.

So let’s say we make a new file extension – .esh, for executable .sh, and these will actually be shell scripts, following all the rules of sh/bash. When one double-clicks on such a file in a file manager, the file manager will either:

  • Execute the file if it has +x permissions, in which case it will act like a shell script, or
  • Treat the file as a data file and will open it in the associated program – this will be my program which I will call esh

The program will be something like this:

/* esh.c */
int main(int argc,char** argv)
{
if(argc != 2) return -1;
exec("/bin/bash", "bash", argv[1], NULL);
}
/* thank you Wordpress for deleting spaces at the beginning of a line. grrr */

So if the file manager runs ‘esh program.esh’ it will just execute /bin/bash program.esh, which is exactly what I want – it will give the illusion of a file being executed even if it doesn’t have execute permissions.

Of course then there is the matter of getting distributions to ship with esh installed by default – but maybe I’m not the only one who thinks this is a major misfeature in Linux, and it will get done quickly.

If I don’t find a different solution in a couple of weeks, I will probably go ahead and start pimping this one.