@heydon Caveat: answers might make use of JS frameworks.