Strength levels added to your log profile

A new feature is being incubated! On your log profile (or under Stats/Scores on your mobile app), you will now see your Big 3 strength exercises being rated. More to come on how they are calculated but here are the key things to know

  • Barbell squat, bench press and deadlifts are the key exercises to measure your strength
  • Increasing your rep maxes will increase your level and points
  • The scoring is scaled 10 levels, ranging from the rank beginner to an elite lifter.
  • Just like various RPG games out there, the levels get exponentially harder to achieve
  • It takes into account your body weight (so make sure this is recorded!) and how many reps you do in your exercise
  • It will eventually take into account gender and maybe age
  • It doesn’t take into account how height, body physique, training methods etc. but does otherwise provide a fair score of comparison with your fellow lifting buddies, so invite them along to compare scores!

The formula may otherwise get refined but the levels should be pretty accurate as they are.

And this is me as of the time of writing

Analysis on EXRX and Rippetoe’s Strength Standards – Part 1 is a popular website to figure out how “advanced” a lifter you are in various categories. It’s also referred to in Rippetoe’s excellent book Starting Strength – a copy of the standards at

People often refer to this table as gospel but instead miss this key tidbit of information:

In other words, they sort of made it up, albeit from the best possible sources:

To see if I can do better I am going to run some regression analysis and use accumulated performance data to figure out both what we can learn from the experience of these Starting Strength authors, see if the standards can be improved and ultimately get a better measure of strength.

The only regression study I’m aware of is what has become the Wilks Coefficient. Is anyone else aware of similar analyses? If not, I will rely solely on Wilks, exrx and some basic maths.

Before that, I can draw some inferrences from Starting Strength tables alone. All else being equal (i.e. ignoring height, genetics etc. etc.) the Exrx table indicates male atheletes from intermediate onwards split their totals as follows

  • 35% Squat
  • 25% Bench Press
  • 40% Deadlift

Or to interpret it another way, a typical deadlift is 14% higher than the typical squat and benchpress is 71% of the squat. That’s kind of interesting – it’s an FAQ on what typical Squat/Bench/Deadlift ratios are, so here you go. Furthermore, the ratios don’t change across different bodyweights! (Height probably matters though)

For the newer athlete, squat/deadlift take a lower ratio, whilst bench press takes a higher ratio. I pay less interest to this because it may be the typical untrained athelete has actually tried to bench before whereas squat is a foreign exercise. Or perhaps it is interesting because it shows how the Squat can proportionally improve as the fastest exercise when you are first starting out.

Announce: Gainstrack mobile app betas!

Maintain a training log has been one of the keys to my personal success – in terms of accountability and the support you get from others. You get measurable progress in seeing how you progress with your strength goals.

When I heard my old community, SLIC, was getting shut down, I was spurred into action. I thought it unacceptable that hundreds of training logs -  long term diaries of progress could be lost forever. Furthermore, the logging there was never quite as good as it could be.

So since the SLIC shutdown, I’ve been working on making my perfect training log software to track my gains. Perfection will take time but it is now in a state I am happy to log my workouts on my phone for myself and to start sharing the capability with others who want the same things from logging like me.

So who is me then?

I’m a lifting techie. I care about stats, progress. I want to know all the analysis from my training log so I can learn what I’m doing, what to target and how to do better. Rep maxes, graphs, plate calculators etc.!

I believe in open standards and am against vendor lock-in. Never again should a training log be at risk as when the site closes down. Logs should be transferable within sites. You can get your log entries in and out of Gainstrack and I’ll make it as easy as I’m allowed to integrate with sites like CrazyStrength.

I believe in open platforms. Whether you are on your desktop, on your Android or iPhone mobile or offline in the gym, your training log and training tools should be available for you to use. Hence a mobile app.

Desktop version is at

Android users can pick up it up from the Play store now soon. In the mean time, you can download the APK from

iPhone users follow instructions at

I welcome feedback, suggestions, feature requests, bug reports and any general commentary!

iPhone bug with window.alert in web apps

I thought I had a crazy bug. My iPhone tester reported that after closing a pop-up alert, the app would force close. This got me really worried since I don’t think I could cause a browser to crash even if I tried!

It turns out various flavours of iOS have a bug whereby alert/confirm in an event handler would cause the browser to shutdown. C’mon apple! It’s bugs like these that cause developers to have to create crazy workarounds to make things work across browser. The workaround in this case for AngularJS is to delay the alert

$timeout(function(){window.alert('My alert');});

CSRF protection with AngularJS and Mojolicious

Gainstrack is a single page application based on AngularJS that makes Javascript calls to a Mojolicious backend. In the modern age, one just protect against CSRF attacks that change user state triggered by malicious code in a pages on a 3rd party website.

A good first line of defence is to ensure that all requests that may change state are restricted to POST requests. This is as simple as ensuring your route accepts nothing but post

$r->post('/command/doStuff') # Not $r->any

This protects against many attacks caused from sites with XSS vulnerabilities allowing hackers to place carefully crafted IMG tags on such vulnerable sites. However, it doesn’t stop carefully crafted iframes+javascript from executing a POST attack as this Stackoverflow question demonstrates.

For further protection, we should generate a server side token that the client side passes back only via Javascript. This provides protection against CSRF because the Javascript that can process the token is protected by same origin policy. There are various intricacies in implementing CSRF token properly. Fortunately, both AngularJS and Mojolicious have in-built help for CSRF protection – it is just a matter of gluing things together!

Angular $http documentation describes how it has in-built support to use a XSRF-TOKEN cookie to subsequently add the token back via a X-XSRF-TOKEN header. So we just need to support this protocol on the Mojolicious side. Fortunately, Mojolicious already has token generation support. Thus all you need on one your app entry points is to have

$c->cookie('XSRF-TOKEN' => $c->csrf_token, {path => '/'});

Angular will handle this automatically. To perform CSRF validation, simply compare the header

my $csrf = $c->req->headers->header('X-XSRF-TOKEN') // '';
($csrf eq $c->csrf_token) or die("CSRF attack was foiled");

And with no further change on the client side, you have CSRF protection! Not bad for 3 lines of code.

Note that the above doesn’t seem to work of the site is deployed via Cordova/PhoneGap application. I had to do a workaround for that… details available upon request.

The lessons of HCI and User Testing

So one of my side projects is producing a mobile app for logging workouts into Gainstrack. The prototype has been under development for the past couple of months and reached a stage where I was very comfortable dogfooding it for logging my own workouts on my phone.

Before unleashing it to a wider audience, HCI training kicked in and thought I’d run a user test where I set a user some tasks to accomplish on the mobile app, never having used the app before, while I quietly watched and took notes.

The participant in this case is my fiance… a largely non-technical user who is a regular user of Android/iPhone apps who is familiar with some strength training. Her tasks were to

  • Attempt to log a typical workout
  • Attempt to make amendments to a workout
  • Register her details with the app

I already took these tasks for granted but I got a plethora of useful feedback from this single participant.

  • The first menu item under the Home menu item was the Plate Calculator. She immediately started playing with that rather than doing a workout
    • Lesson: Make Log Workout the first menu item
  • She understood “Enter the barbell weight” as the loaded weight
    • Lesson: Make the text “Enter the empty barbell weight”
  • Back to logging, she said that Account should therefore be the top item because surely you need to register before logging.
    •  Actually, my site supports starting a log without registering but that fact she takes registration for granted, maybe that could be highlighted sooner
  • Adding an exercise was non-obvious. The layout of exercise/add/quick didn’t make sense for her. She couldn’t figure out how to add a typed exercise (press the add button!). So the layout is changing

  • She can’t add her Running exercises… weights only for now. Looks like I can’t convert her yet!
  • The keyboard jumps around a lot when adding new sets. Actually, this bugs me too, it’s a real problem that needs fixing
  • Pressing Add when no exercise is typed does nothing. This is double confusing when she didn’t know what Add was supposed to do anyway
  • Cancel button cleared the screen rather than cancelling
  • The “More Options” and Delete workout were oddly placed, according to her. It’s going to move

As with many HCI user tests, the feedback was both surprising and usefully constructive. Lots of minor interface improvements are on the way! A good learning exercise all around.

Oh, and I submitted my first workout from my mobile app proper… coming very soon.

Crazystrength Log Export

I now have bookmarklet support for exporting a gainstrack log entry to Crazy Strength in just a few clicks. For this to work, you need to be a logged in and fully registered member of Gainstrack for this to work.

Then drag this bookmarklet to your bookmarks toolbar (or right click and Bookmark)

Gainstrack Import

Now you are set! To import an entry to Crazy Strength:

  • Go to Crazy Strength’s Log Workout page
  • Select the date of your workout on that page
  • Click the Gainstrack Import bookmark you saved

If it all works, your workout will be automatically filled into the page!

AngularJS html5mode with links back to server

Having enabled successfully enabled html5mode on my web application, I accidentally broke a browser link to download some JSON from the server, since Angular now interprets it as a route.

Thanks to for posting an explaining a full answer.

Adding target=”_self” to the link fixes it but here are the options from the Angular docs

In cases like the following, links are not rewritten; instead, the browser will perform a full page reload to the original link.

  • Links that contain target element
    Example: <a href="/ext/link?a=b" target="_self">link</a>
  • Absolute links that go to a different domain
    Example: <a href="">link</a>
  • Links starting with ‘/’ that lead to a different base path
    Example: <a href="/not-my-base/link">link</a>

RepMax badges in your log!

Following a suggestion from someone earlier today, the logic that already generates the rep max tables in the training logs now also marks itself within your training logs with these little badges so you know your lifts are improving!

Here was my boxing day deadlift where I achieved a 2RM that was surprisingly close to my 1RM of 130kg. Hence it’s my best estimated 1RM too.