finished js version