This is so terrible I'm ashamed to put it up on github but I just can't do any more tonight