re-implemented client-side code