Ported to AngularJS, lots of changes.