code: function debounced(func, tmin, tmax) {
    let id = 0;
    let t = tmin;
    function wrappedFunc() {
      let start = Date.now();
      id = 0;
      func();
      t = tmin + Date.now() - start; // tmin + [func's execution time]
      t = t < tmax ? t : tmax;
    }
    function debouncedFunc() {
      clearTimeout(id);
      id = setTimeout(wrappedFunc, t);
    }
    // id is nonzero only when a debounced function is pending.
    debouncedFunc.delay = () => { id && debouncedFunc(); }
    return debouncedFunc;
  }
docs: debounce time = min(tmin + [func's execution time], tmax).
  
  @param {Function} func
  @param {number} tmin Minimum debounce time
  @param {number} tmax Maximum debounce time
  @return {Function} A debounced version of func with an attached "delay"
  function. "delay" will delay any pending debounced function by the
  current debounce time. If there are none pending, it is a no-op.