The musician and his worst enemies

Following up on a discussion that was started a few days ago on a group dedicated to Allan Holdsworth on The Book Of Faces, here are some things that cross my mind. The text below is largely speculative, and serves as a basis for discussion rather than as canon. 😉

MUSICIANS CAN BE THEIR OWN WORST ENEMY

We know how much Allan Holdsworth sucks at self-promotion… but he’s not alone. Quite a few non-mainstream musicians would rather just follow their heart and make music without having to bother with filling in forms, actively promote themselves, or seeking for ways to enhance their exposure in a changing media landscape. Quite a few artists are actually shy, and not very willing (or capable) to engage socially. In that respect, I recognize a trait that they share with engineers: they just want to do their thing. My guess is that, for many artists, actively communicating with their fan base is a chore, rather than something they aspire. Some deal with this better than others, and some seem to actually like it (or at least put up a good show of liking it), but that’s not a universal trait.

Yet, it seems as if, in the changing media landscape, that would seem to be just what the doctor ordered for non-mainstream musicians. Why?

CONSUMERS CAN BE EVERYONE’S WORST ENEMY, INCLUDING THEIR OWN

The average consumer is not interested in supporting an artist. This goes way further than I thought – I know a guy who plays guitar himself, but admits without shame that he will only listen to Youtube playlists, and hasn’t bought any music since dust was invented. Yes, that came as a shock to me too.

I think people like him may well turn out to be their own worst enemy, for if that attitude would persist, he would, within decades, be listening to a mix of Katy Perry, Taylor Swift, Nicki Minaj and Pharrel Williams.
So, that’s not the type of consumer the average Richard Hallebeek would be aiming at – nothing to see here, please move along.

There is, however, a small base of people who realise that there is good karma to be gained from supporting your favorite artists. The question for the artist is: how do we find them and get their money?
Seriously: this group has 2.726 members. I don’t think there are as many Pledgers as there are group members.

One thing the Unreal Allan Holdsworth group thrives on is the opportunity of meeting people who are just as mad as you yourself are. But let’s admit it – most of us really like it that Louise​ has joined us, and occasionally serves as a link between us, the hysterically-screaming horde of fans, and The Master Himself. Being just a bit closed to the Object Of Our Admiration is quite satisfying.

This brings us back to my earlier question:
Why should the musician reach out to his fan base?
Well, the record company surely isn’t doing it anymore – mainly because, for many independent artists, there is no such thing. In a way, this seems like a Good Thing(TM), because that’s one less party that can screw the musician. We’ve all heard the stories.
But on the other hand, when John Coltrane was under contract with Atlantic, Ahmet Ertegün was apparently a Good Guy, and Atlantic made sure that John got sufficient exposure. With the demise of the traditional distribution model, that’s gone down the drain.

As the traditional distribution model crumbles, new opportunities arise. Bandcamp is a good example for the indie artist. They charge a marginal fee, so most of the money does indeed go to the artist – and in fact it goes into the artist’s pocket rather rapidly.
However, just putting your album on Bandcamp and then sit back and wait isn’t going to do you much good – you will still have to drag people in. Either you do that yourself, or you find someone who will do that for you.

The question remains: where, and how, do you find your audience? It appears that I, as a consumer, have been a bit too optimistic about that. I recently made some noise about a few albums from . While this attracted quite a few likes, it did not result in any sales on Bandcamp. And yes, you do not have to have artist access to see the sales numbers on Bandcamp…
So, it seems as if liking something, and even commenting on something with great enthusiasm, does not always equal actually putting your money where your mouth is. Okay, that sounds a bit harsh, I admit. Winking smile

But to the musician, the net result is the same.

So… how do you musicians think you are going to get my money? Let’s throw some ideas around.

Yet Another Alternative for The Blue F

A week or so ago, I stumbled over tsū (don’t worry, you can spell it tsu), which is, much like Ello, an alternative to The Book Of Faces, or the Big Blue F-word.

It’s not the same as Ello, though. It’s less pretentious, and, more importantly, it works like a charm, in a browser as well as with the Android app.
Also, the Android App doesn’t come with four (FOUR) pages of permissions it will claim (like the Blue F does).

But also, tsū claims that, if your posts create ad revenue, they are actually going to reimburse you for it! There have already been (unverified by yours truly) reports of people cashing in on this, but these seem exaggerated. I don’t think you can retire on it.
For me, that is utterly unimportant – my rants won’t generate much traffic. But it would mean that, if you are, say, an artist, and you attract sufficient views, you can actually make some money off this.
Update: don’t expect much off this. It sure as hell won’t cover your retirement.

Funny thing: it seems to attract quite some attention. Mainly photographers, graphic artists, the odd musician.
Anyway: I’ll have to do some more digging around.

The really funny part is: Facebook seems to be really, really worried about these guys. Try posting a link to www.tsu.co in a Facebook post and see what happens:

If Facebook wants to make itself unpopular with the geek community, this is the sort of crap that will make them succeed.

I’m hoping that this doesn’t go the same route as Ello. But since tsū is less pretentious (and therefore less intimidating), and it actually works very well, this might have a decent chance.
Currently, they only accept new members by invitation.
If you read this, and you know me, consider yourself invited (click).

Why I don’t use the Facebook app on my phone…

I admit, it is (believe me) very nice to ONLY get Facebook notifications when you want them. I have also, for that very specific reason, switched off email alerts for Facebook events – if I want to know what’s happening in Facebook, I will open their web interface.

But, first of all, because the list of things Facebook reserves the right to access and even modify on my phone is so insane, there is not a word to describe it.

Facebook wants to read all my SMS/MMS messages, it wants to call phone numbers AND it wants to be capable of read and even write my call log (thereby potentially removing calls it made itself from my call log… think about it), it wants to read and modify my calendar items and send emails to guests without my knowledge, and it wants to be capable of using my camera and microphone whenever it pleases.

It also wants to read, modify and delete the contents of my internal and even USB storage, it wants to be capable of reading and modifying my contacts, it wants full network access and change my network connectivity, and it wants me to allow it to set my wallpaper (full-screen ads, anyone?). It also wants to be able to create accounts and set passwords.

Oh, and it says that updates may automatically add additional capabilities.

Seriously. Selling your soul to the devil is probably a better idea than agreeing with this.

“Your privacy and security are important to us, and we want you to feel confident that you can use the application freely.” Sure… that’s what I’d say too, because, otherwise, how would I get you to allow me to give you access to all this data?

I wouldn’t be amazed if running this app alongside your mobile banking app would violate the terms of service. And if it doesn’t, it bloody well should.

Maybe it’s about time we get the opportunity to deploy folder level security on our smartphones…

Coincidentally, just today I discovered Yet Another Alternative for the Book of Faces, but that is material for another writeup.

Redneck sushi

Benodigdheden:

  • Sushi-mat
  • Oven of grill

Ingredienten

  • Bacon (100g)
  • Gehakt (250g)
  • Emmenthaler of cheddar (1 reepje)
  • Gefruite uitjes.
  • Barbecue rub (ca 4 tl)

OK, ik hoor je hier je wenkbrauwen fronsen. Deed ik ook.

Barbecue Rub bestaat uit: basterdsuiker, zout, paprikapoeder, zwarte peper, knoflookpoeder, uienpoeder en cayennepeper. Dat is nogal wat specerijen en geen kruiden… als je de basterdsuiker eraf laat en je voegt er oregano en tijm aan toe, dan heb je cajunkruiden. Daar  heb ik altijd een voorraadje van staan. Op twee en een halve theelepel cajunkruiden voeg ik dan anderhalve theelepel bruine basterdsuiker toe, en klaar is Peter.

Hieronder het recept van cajunkruiden:

  • 2 theelepels zout
  • 2 1/2 theelepel paprikapoeder
  • 2 theelepels knoflookpoeder
  • 1 theelepel gedroogde oregano
  • 1 theelepel cayennepeper
  • 1 theelepel zwarte peper
  • 1 theelepel uienpoeder
  • 1 theelepel gedroogde tijm

Meng alle ingredienten en bewaar ze in een luchtdichte bak. Het blijft jaren goed.

OK, let’s get this show on the road.

Verwarm de oven voor op 180°C. Als je ze op de BBQ doet, ga je ze indirect verhitten.

Werk de BBQ rub door het gehakt.

Leg de repen bacon op de sushi-mat, in de richting waarin je het handeltje gaat oprollen. Spreid daarop een dunne laag (ca. 7 –10 mm dik) gehakt uit, houd aan de buiten-lengtekant (waar de rol afkomt) een stukje vrij. Leg aan de binnenkant (waar je straks begint met dichtrollen, over de hele breedte een staafje cheddar of emmenthaler, en rol de sushi-rol dicht.

Leg de rollen in de oven of op de grill – op 180°C in totaal 40 minuten*. Na een half uurtje de rollen coaten met je favoriete rode BBQ saus, en dan een minuut of vijf later nog een keer.

*) NB: Your Mileage May Vary. Al je rol wat dunner is, bijvoorbeeld, kan die 40 minuten best te lang uitpakken. De truc is dat je een kerntemperatuur van rond de 70 graden bereikt, dan weet je dat rundergehakt voldoende gegaard is. Ik doe dat met een kerntemperatuurmeter die Ikea verkoopt voor 9 luizige euros. Het is mogelijk om een slechtere investering te doen als je je vleesbereiding serieus neemt.
Ik stel de temperatuur in op 60 graden, en daarna breng ik een coating BBQ saus aan, wacht dan nog 5 minuten, en breng dan de tweede laag aan… en vijf minuten daarna verklaar ik het ding voor gaar. Winking smile

Bedek de rol met gefruite uitjes, snijd in sushi-porties, en dien op met barbecue-saus en iets lekkers zoetzuurs, of met een Griekse salade.

You’ll never unlearn cycling. Badminton, on the other hand…

It’s been like 20 or so years ago when I last played badminton competitively. It was over 30 years ago when I accompanied my then-girlfriend to a badminton club she was joining. It was her first time, and she didn’t want to go all by herself, so I joined her, just to give her some company.

The next day, I lined up at Van Dijk Racketsports in The Hague to buy myself badminton gear.
BadmintonI knew badminton as a camping activity, but what I saw here hooked me. The club she joined had a team that played at the highest national level, and they were playing men’s doubles. By Jove, this is a fast sport… if you think squash is fast, watch this.

I ended up playing on a fairly decent level for a couple years. Three evenings of training, and the matches in the weekends – I couldn’t get enough. I always liked men’s doubles most. In singles matches, I could sort of get by because I never gave up, but men’s doubles called on my reflexes, which gave me the greatest thrill.

Then I moved to another town, and played a few years at another club, somewhere around 1994.

Then I moved again (to Cothen), and played for half a year there, until an injury stopped me. I then turned to air rifle shooting, and then to grandparenting.

So, last week I read an article in a local rag about an invitation tournament organised by BBS, a badminton club in Bodegraven (10 minutes from where we now live).
So, I went there yesterday.

This is what I learnt:

  1. You DO unlearn badminton. I still got da moves, but da timing is completely, totally, utterly shot. If I would’ve counted the number of times my impressive smash move created a nice whooshing sound, leaving the shuttlecock to limply drop on the ground next to my feet, I would’ve needed depression medication.
  2. My physical condition is laughable.
  3. My promise to myself that I would ‘take it easy’ went out the window… I ended up giving it all I had. Which wasn’t enough.
    Thus, we advance to…
  4. To get to my desk at work, I have to negotiate three stairs. I have never been more acutely aware of this than I was today. I am being slowly killed by muscular pain – and it’s not even the second (worst) day yet. There are also too many stairways in our home. I can’t even sit down on the loo without pain.
  5. I still like this game a lot, so yes, this is going to be a weekly recurring activity.

In all fairness, I did better than I expected – I played 5 short matches in quick succession (all in all about 90 minutes) and I didn’t die. After recovering for 15 minutes, I even managed to get another recreational game in. Not that I won anything, but I had huge fun!

So… BBS Bodegraven, here I come.

Best money I’ve ever spent

Today, my pneumatic hammer drill ceased to be. Dead as the proverbial Norwegian parrot.

It is important at this stage to realise that I bought the thing in 1991. I had moved into an apartment building made out of industrial-quality concrete. My little hammer drill, bought at a flea market, did nothing beyond damaging the wall paper… the concrete wall behind it was utterly unimpressed.

bdSo I went to the local DYI store and asked for help. They advised me to buy a pneumatic drill hammer. Since I wasn’t expected to use it often, they suggested a cheap Black & Decker. It went into the concrete wall like a hot knife into butter.

This machine has seen a lot of abuse. I do not want to count the number of drills it wore out, and it has been dropped several times. It has been borrowed by many people, it was indispensible in building at least two extensions, a number of workshops, and God knows what else. It’s saved the day for a commercial KPN engineer who got his SDS drill stuck in a wall and couldn’t get it back out – the measly Black&Decker made light work of it. Everyone who had used it, sung its praise, and quite a few B&D pneumatic drills were bought because the buyer had borrowed mine first.

But today, when hanging the rails for our new curtains, it choked. At the last hole. For me, it was like seeing an old friend suffer.
With what we thought was its terminal breath, it finished drilling the last hole. And then it was quiet, and we thought… okay, after 24 years, for what is not supposed to be (and wasn’t priced as) a professional tool, that’s to be expected.

Or had I spoken to soon? Was it merely pining for the fjords?

I really felt sorry to have to part with it… I’d much rather have this one than a shiny new one. We were a drilling team, that drill and I.
So in the tradition of nothing ventured, nothing gained, I opened it up, to bd-opendiscover that it had accumulated a lot of crud in the “dry section” (the pistol-like bit at the bottom of the picture, where the engine and the electronics live). I cleaned that out with the help of a compressor and a brush, hooked it up to the mains… and joy! it was alive!

Since I had it open anyway, I inspected the bearings (there is one at the back of the motor, and the other one is in the “greasy” front assembly. Both bearings were smooth and without any free play. I don’t know where the manufacturer sourced these bearings back in the late eighties or early nineties, but I’ve seen worse bearings in more expensive machinery.
I haven’t done anything to the greasy side; I’ll have to ask for advice. I may even mail the manufacturer for that.

One new mains plug later (essentially because, with abundant display of carelessness, I set fire to the old one), and it was as good as new. It still sinks into the concrete of the house we live in now as if it’s a loaf of bread. Surely this is the power tool equivalent of a Toyota Hi-Lux.
I’m not entirely sure what caused it to stop working, but I am very happy that it’s back to life again. I’ve sort of grown attached to it. It’s by far the oldest power tool I have, and the one that’s seen the most use, and quite possibly the best.

I swear, if it would’ve been dead, I would have created a little pedestal to mount this on in the workshop, as a tribute to power tool excellence.

Transym OCR & Peter–Proof Of Concept completed and approved

This week’s work comprised of readying the DnlCore-Shared.OCR classes, the DnlCore-Shared.ImageViewer control… and then build the Indexing Client Proof of Concept on top of that.

I wanted to prove that I could create a Win32 form with the following:

  • a custom PictureBox-like control that would allow
    • scrolling, and (more importantly)
    • zooming in the scrolled-out image representation, while preserving the image itself at its original resolution
    • selecting an area and returning the contents of the selection rectangle (from the preserved image to retain full scan resolution) as a bitmap
  • the facility to OCR the result of selected areas and use these to populate a selected field
  • the facility to load image files from a TWAIN scanner or from disk.

<echo>This has now been accomplished. </echo>

It goes like so:
The client (with the scanned image loaded at the right):
image

We start out at a zoom level of 33%, which is perfectly readable on a screen that was cutting-edge 10 years ago.

We doubleclick the Sender field (which makes it go powder blue) and select the name of the sender:
image

and then we choose Selection/OCR (or we hit Alt-O because we are lazy), and lo and behold:
image

We double-click the Reference field, draw an area around the 5928 bit, Alt-O, and hey look here:image

The main work went into creating the image viewer control (read: stealing the image control from the sample viewer application that comes with Transym OCR, and poking it in the eye until it does what I want). It inherits from the PictureBox control and now (after some eye-poking) adds the functionality mentioned in the requirements above.

A fair bit of work went into isolating the API code of TOCR and the creating the .NET wrapper around it.

The actual logic in this POC amounts to only 208 lines of generously formatted C#. I reckon I could compress that to something like 150 lines, but that would be at the expense of code readability and not add a bit to performance or ease of maintenance.
Of course, as PoC’s come, it contains very little exception handling, so it’ll probably grow – but still… impressive!

(“Jeez, I’m good!”) Winking smile

The indexing client logic all 202 lines of it:

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DnlCore.Shared;
using DnlCore.Shared.OCR;

namespace pocIndexing
{
    public partial class Form1 : Form
    {
        private Bitmap[] bitmaps;
        private bool haveSelection = false;
        private Rectangle selection;
        private string currentFile;
        private System.Windows.Forms.TextBox selectedControl = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void LoadFromFileButton_Click(object sender, EventArgs e)
        {
            if (LoadFromFileDialog.ShowDialog() == DialogResult.OK)
            {
                currentFile = LoadFromFileDialog.FileName;
                loadImage(currentFile);
                setZoomRate(33);
            }
        }

        private void loadImage(string filePath)
        {
            editableImage1.Image = new Bitmap(filePath);
            setZoomRate(33);
        }

        private void ScanButton_Click(object sender, EventArgs e)
        {
            loadFromScanner();
        }

        private void loadFromScanner()
        {
            IEngine engine = new Engine();
            bitmaps = engine.GetDocumentFromScanner();
            editableImage1.Image = bitmaps[0];
        }

        private void setZoomRate(float rate)
        {
            editableImage1.Zoom = rate;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            editableImage1.Dispose();
        }

        private void page_SelectionChanged(Rectangle rect)
        {
            if (rect.Width != 0)
            {
                imageToolStripMenuItem.Text = "&Selection";
                selection = rect;
                haveSelection = true;
            }
            else
            {
                imageToolStripMenuItem.Text = "&Image";
                haveSelection = false;
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (LoadFromFileDialog.ShowDialog() == DialogResult.OK)
            {
                loadImage(LoadFromFileDialog.FileName);
            }
        }

        private void scanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            loadFromScanner();
        }

        private void zoom20MenuItem_Click(object sender, EventArgs e)
        {
            setZoomRate(20);
        }

        private void zoom33MenuItem_Click(object sender, EventArgs e)
        {
            setZoomRate(33);
        }

        private void zoom50MenuItem_Click(object sender, EventArgs e)
        {
            setZoomRate(50);
        }

        private void zoom75MenuItem_Click(object sender, EventArgs e)
        {
            setZoomRate(75);
        }

        private void zoom100MenuItem_Click(object sender, EventArgs e)
        {
            setZoomRate(100);
        }

        private string getOcrResult()
        {
            string result = string.Empty;
            IEngine ocrEngine = new Engine();
            Bitmap bitmapToOcr = null;
            if (!haveSelection)
            {
                bitmapToOcr = editableImage1.Image;
            }
            else
            {
                bitmapToOcr = editableImage1.SelectionImage;
            }
            result = ocrEngine.GetOcrFromBitmap(bitmapToOcr);

            return result;
        }

        private string detectFileType(string filePath)
        {
            string result = string.Empty;
            // Magic numbers embedded in files - these are mutually exclusive
            const short BMP_ID = 0x4D42;                // bitmap fileheader file type
            const short TIF_BO_LE = 0x4949;             //TIFF byte order little endian
            const short TIF_BO_BE = 0x4d4d;             // TIFF byte order big endian
            const short TIF_ID_LE = 0x2a;               // TIFF version little endian
            const short TIF_ID_BE = 0x2a00;             // TIFF version big endian
            const short GIF_ID1 = 0x4947;               // GIF 1st short
            const short GIF_ID2 = 0x3846;               // GIF 2nd short

            short value;

            using (System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.Open(filePath, System.IO.FileMode.Open)))
            {
                value = reader.ReadInt16();
                switch (value)
                {
                    case BMP_ID:
                        result = "BMP";
                        break;
                    case TIF_BO_LE:
                    case TIF_BO_BE:
                    case TIF_ID_BE:
                    case TIF_ID_LE:
                        result = "TIF";
                        break;
                    case GIF_ID1:
                    case GIF_ID2:
                        result = "GIF";
                        break;
                    default:
                        result = "";
                        break;
                }
                reader.Close();
            }

            return result;
        }

        private void oCRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            selectedControl.Text = getOcrResult();
            selectedControl.BackColor = Color.White;
        }

        private void textBox_DoubleClick(object sender, EventArgs e)
        {
            selectedControl = (TextBox)sender;
            selectedControl.BackColor = Color.PowderBlue;
            foreach (var t in this.Controls)
            {
                if (t.GetType() == typeof(TextBox) && t != sender)
                {
                    TextBox tb = (TextBox)t;
                    tb.BackColor = Color.White;
                }
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            TextBox t = (TextBox)sender;
            t.BackColor = Color.White;
        }

    }
}

Peter + Transym OCR versus The World: For The Win!

Oh yes. Ooh yes. Oooooh yessss. This is what I wanted to be capable of doing: getting a scan result in a viewer, selecting an area in the scan result, and then OCR that area, to get the result in the selected text box control. <*fist pump*>

image

Concept proven; mission accomplished.

Please note that Transym OCR is still confused about the lower case l (L for Lima) embedded in a bunch of characters that are digits being a lower case l, not a 1. I can’t blame it – I have yet to come across an OCR engine south of 5000 euros that can sort this out reliably.

Jeez, I’m good!*
On to the next hurdle. There are quite a few that need to be taken – the most important one is that the PictureBox control doesn’t let you zoom. Google is usually my friend, but all solutions it comes up with imply resizing the original bitmap to a size to fit the picture box – which will NOT help OCR one bit!

But: I have now proven that Transym OCR does everything I want it to do for my application! I have now got it to the point where it covers all must-haves. There are quite a few nice-to-haves that were not available to me when I was using Microsoft MODI, such as confidence (a property of the OCR result that indicates how sure the engine is that it’s got it right), which I could use to colour-code automatically-indexed fields. But first, I am going to concentrate on replicating the functionality that I had.

*) every programmer has to say this to himself or herself every now and then. The rest of the world has no idea what you’re doing, and how hard it is. Winking smile

Peter versus Transym OCR: 2-0

As of today, the DnlCore.Shared library contains an OCR namespace.
There is not much that is exposed to the outside world yet. It contains one method: ScanAndOcrDocument. It will fire up the TWAIN interface to a TWAIN scanner  and ask for a stack of paper to be scanned (note how this supports an automatic sheet feeder to scan multiple pages),
image

and when it’s done doing that, it will return a string containing the OCR result of the entire document.

image

It (using the DnlCore.Shared.OCR.Engine library) doesn’t get any harder than this. Of course, now we will need to be able to create scans of selected regions from the document. The only challenge there is to get a selected area in a viewer to be available as a System.Drawing.Bitmap… which won’t be rocket science.
I am definitely on to something very, very good with this Transym OCR engine! Open-mouthed smile

Today’s partial solar eclipse–proof that it happened! ;-)

Right then. Today, we were supposed to see a partial solar eclipse. We were told yesterday that it would most likely be clear skies, so we would be lucky. Zonsverd.... dikkie!
Here’s what we did get to see: various shades of gray (yes… I know. Spare me the pun. Life has become hard enough for us black&white photographers as it is).
The red arrow points to where approximately the sun would have been visible. So, that was a letdown.

I did, however, get some evidence. We have a little weather station on our roof, that measures solar input as well. Here’s the graph for this morning:

Eclipse 20-03-2015

The pink line shows the solar input as it would have been on a perfectly clear morning. The yellow line shows the actual input.
See the dip starting at 09:40, and reaching the bottom at 10:35-ish? There you have it! Proof of today’s solar eclipse! Remember: you read it here first. Winking smile

Funny detail: the solar input in watts per square meter plummets dramatically, from more than 100 to approximately 20. But we did not perceive it as such – I thought it did get noticeably darker, but not 80% darker! The graph shows how much our senses fool us: in fact, at around 10:35, it was about as dark as it was three hours earlier!

It would be interesting to see if that would also show up in the outside temperature. Let’s have a look:
solar-eclipse-temp

And there it is. With about half an hour’s delay, as you’d expect.
In this graph, it looks a bit more dramatic than it is, due to the graph resolution on the Y-axis, but it’s still there.
So… if you missed it like we did here in Waarder, just take a look at these two graphs to relive the moment.
It’s debatable whether it’s worth it to save this for posterity, though. Smile