rewritten everything in typescript