function characterFromEvent(e) {
  // for keypress events we should return the character as is
  if (e.type == 'keypress') {
      var character = String.fromCharCode(e.which);

      // if the shift key is not pressed then it is safe to assume
      // that we want the character to be lowercase.  this means if
      // you accidentally have caps lock on then your key bindings
      // will continue to work
      //
      // the only side effect that might not be desired is if you
      // bind something like 'A' cause you want to trigger an
      // event when capital A is pressed caps lock will no longer
      // trigger the event.  shift+a will though.
      if (!e.shiftKey) {
          character = character.toLowerCase();
      }

      return character;
  }

  // for non keypress events the special maps are needed
  if (_MAP[e.which]) {
      return _MAP[e.which];
  }

  if (_KEYCODE_MAP[`${e.which}`]) {
      return _KEYCODE_MAP[`${e.which}`];
  }

  // if it is not in the special map

  // with keydown and keyup events the character seems to always
  // come in as an uppercase character whether you are pressing shift
  // or not.  we should make sure it is always lowercase for comparisons
  return String.fromCharCode(e.which).toLowerCase();
}
loop through to map numbers on the numeric keypad