package keyboard

// Keycode is a package-defined bitmap used to encode the value of a given key.
type Keycode uint16

// keycode returns the given Unicode codepoint translated to a Keycode sequence.
// Unicode codepoints greater than U+FFFF are unsupported.
//
//go:inline
func keycode(p uint16) Keycode {
	if p < 0x80 {
		return ascii[p]
	} else if p >= 0xA0 && p < 0x0100 {
		return iso88591[p-0xA0]
	} else if uint16(UNICODE20AC) == p {
		return UNICODE20AC.mask()
	}
	return 0
}

//go:inline
func deadkey(c Keycode) Keycode {
	switch c & deadkeysMask {
	case acuteAccentBits:
		return deadkeyAcuteAccent
	case circumflexBits:
		return deadkeyCircumflex
	case diaeresisBits:
		return deadkeyDiaeresis
	case graveAccentBits:
		return deadkeyGraveAccent
	case tildeBits:
		return deadkeyTilde
	}
	return 0
}

//go:inline
func (c Keycode) mask() Keycode { return c & keycodeMask }

//go:inline
func (c Keycode) key() uint8 { return uint8(c & keyMask) }

//go:inline
func (c Keycode) mod() uint8 {
	var m Keycode
	if 0 != c&shiftMask {
		m |= KeyModifierShift
	}
	if 0 != c&altgrMask {
		m |= KeyModifierRightAlt
	}
	return uint8(m)
}

//go:inline
func (c Keycode) Shift() Keycode { return c | KeyModifierShift }

const (
	hidKeyboardKeyCount = 6 // Max number of simultaneous keypresses
	hidKeyboardSysCount = 3
	hidKeyboardConCount = 4
)

// Keycodes common to all Keyboard layouts
const (
	KeyModifierCtrl       Keycode = 0x01 | 0xE000
	KeyModifierShift      Keycode = 0x02 | 0xE000
	KeyModifierAlt        Keycode = 0x04 | 0xE000
	KeyModifierGUI        Keycode = 0x08 | 0xE000
	KeyModifierLeftCtrl   Keycode = 0x01 | 0xE000
	KeyModifierLeftShift  Keycode = 0x02 | 0xE000
	KeyModifierLeftAlt    Keycode = 0x04 | 0xE000
	KeyModifierLeftGUI    Keycode = 0x08 | 0xE000
	KeyModifierRightCtrl  Keycode = 0x10 | 0xE000
	KeyModifierRightShift Keycode = 0x20 | 0xE000
	KeyModifierRightAlt   Keycode = 0x40 | 0xE000
	KeyModifierRightGUI   Keycode = 0x80 | 0xE000

	// KeySystemXXX is not supported now
	KeySystemPowerDown Keycode = 0x81 | 0xE200
	KeySystemSleep     Keycode = 0x82 | 0xE200
	KeySystemWakeUp    Keycode = 0x83 | 0xE200

	KeyMediaPlay        Keycode = 0xB0 | 0xE400
	KeyMediaPause       Keycode = 0xB1 | 0xE400
	KeyMediaRecord      Keycode = 0xB2 | 0xE400
	KeyMediaFastForward Keycode = 0xB3 | 0xE400
	KeyMediaRewind      Keycode = 0xB4 | 0xE400
	KeyMediaNextTrack   Keycode = 0xB5 | 0xE400
	KeyMediaPrevTrack   Keycode = 0xB6 | 0xE400
	KeyMediaStop        Keycode = 0xB7 | 0xE400
	KeyMediaEject       Keycode = 0xB8 | 0xE400
	KeyMediaRandomPlay  Keycode = 0xB9 | 0xE400
	KeyMediaPlayPause   Keycode = 0xCD | 0xE400
	KeyMediaPlaySkip    Keycode = 0xCE | 0xE400
	KeyMediaMute        Keycode = 0xE2 | 0xE400
	KeyMediaVolumeInc   Keycode = 0xE9 | 0xE400
	KeyMediaVolumeDec   Keycode = 0xEA | 0xE400

	KeyA           Keycode = 4 | 0xF000
	KeyB           Keycode = 5 | 0xF000
	KeyC           Keycode = 6 | 0xF000
	KeyD           Keycode = 7 | 0xF000
	KeyE           Keycode = 8 | 0xF000
	KeyF           Keycode = 9 | 0xF000
	KeyG           Keycode = 10 | 0xF000
	KeyH           Keycode = 11 | 0xF000
	KeyI           Keycode = 12 | 0xF000
	KeyJ           Keycode = 13 | 0xF000
	KeyK           Keycode = 14 | 0xF000
	KeyL           Keycode = 15 | 0xF000
	KeyM           Keycode = 16 | 0xF000
	KeyN           Keycode = 17 | 0xF000
	KeyO           Keycode = 18 | 0xF000
	KeyP           Keycode = 19 | 0xF000
	KeyQ           Keycode = 20 | 0xF000
	KeyR           Keycode = 21 | 0xF000
	KeyS           Keycode = 22 | 0xF000
	KeyT           Keycode = 23 | 0xF000
	KeyU           Keycode = 24 | 0xF000
	KeyV           Keycode = 25 | 0xF000
	KeyW           Keycode = 26 | 0xF000
	KeyX           Keycode = 27 | 0xF000
	KeyY           Keycode = 28 | 0xF000
	KeyZ           Keycode = 29 | 0xF000
	Key1           Keycode = 30 | 0xF000
	Key2           Keycode = 31 | 0xF000
	Key3           Keycode = 32 | 0xF000
	Key4           Keycode = 33 | 0xF000
	Key5           Keycode = 34 | 0xF000
	Key6           Keycode = 35 | 0xF000
	Key7           Keycode = 36 | 0xF000
	Key8           Keycode = 37 | 0xF000
	Key9           Keycode = 38 | 0xF000
	Key0           Keycode = 39 | 0xF000
	KeyEnter       Keycode = 40 | 0xF000
	KeyEsc         Keycode = 41 | 0xF000
	KeyBackspace   Keycode = 42 | 0xF000
	KeyTab         Keycode = 43 | 0xF000
	KeySpace       Keycode = 44 | 0xF000
	KeyMinus       Keycode = 45 | 0xF000
	KeyEqual       Keycode = 46 | 0xF000
	KeyLeftBrace   Keycode = 47 | 0xF000
	KeyRightBrace  Keycode = 48 | 0xF000
	KeyBackslash   Keycode = 49 | 0xF000
	KeyNonUsNum    Keycode = 50 | 0xF000
	KeySemicolon   Keycode = 51 | 0xF000
	KeyQuote       Keycode = 52 | 0xF000
	KeyTilde       Keycode = 53 | 0xF000
	KeyComma       Keycode = 54 | 0xF000
	KeyPeriod      Keycode = 55 | 0xF000
	KeySlash       Keycode = 56 | 0xF000
	KeyCapsLock    Keycode = 57 | 0xF000
	KeyF1          Keycode = 58 | 0xF000
	KeyF2          Keycode = 59 | 0xF000
	KeyF3          Keycode = 60 | 0xF000
	KeyF4          Keycode = 61 | 0xF000
	KeyF5          Keycode = 62 | 0xF000
	KeyF6          Keycode = 63 | 0xF000
	KeyF7          Keycode = 64 | 0xF000
	KeyF8          Keycode = 65 | 0xF000
	KeyF9          Keycode = 66 | 0xF000
	KeyF10         Keycode = 67 | 0xF000
	KeyF11         Keycode = 68 | 0xF000
	KeyF12         Keycode = 69 | 0xF000
	KeyPrintscreen Keycode = 70 | 0xF000
	KeyScrollLock  Keycode = 71 | 0xF000
	KeyPause       Keycode = 72 | 0xF000
	KeyInsert      Keycode = 73 | 0xF000
	KeyHome        Keycode = 74 | 0xF000
	KeyPageUp      Keycode = 75 | 0xF000
	KeyDelete      Keycode = 76 | 0xF000
	KeyEnd         Keycode = 77 | 0xF000
	KeyPageDown    Keycode = 78 | 0xF000
	KeyRight       Keycode = 79 | 0xF000
	KeyLeft        Keycode = 80 | 0xF000
	KeyDown        Keycode = 81 | 0xF000
	KeyUp          Keycode = 82 | 0xF000
	KeyNumLock     Keycode = 83 | 0xF000
	KeypadSlash    Keycode = 84 | 0xF000
	KeypadAsterisk Keycode = 85 | 0xF000
	KeypadMinus    Keycode = 86 | 0xF000
	KeypadPlus     Keycode = 87 | 0xF000
	KeypadEnter    Keycode = 88 | 0xF000
	Keypad1        Keycode = 89 | 0xF000
	Keypad2        Keycode = 90 | 0xF000
	Keypad3        Keycode = 91 | 0xF000
	Keypad4        Keycode = 92 | 0xF000
	Keypad5        Keycode = 93 | 0xF000
	Keypad6        Keycode = 94 | 0xF000
	Keypad7        Keycode = 95 | 0xF000
	Keypad8        Keycode = 96 | 0xF000
	Keypad9        Keycode = 97 | 0xF000
	Keypad0        Keycode = 98 | 0xF000
	KeypadPeriod   Keycode = 99 | 0xF000
	KeyNonUSBS     Keycode = 100 | 0xF000
	KeyMenu        Keycode = 101 | 0xF000
	KeyF13         Keycode = 104 | 0xF000
	KeyF14         Keycode = 105 | 0xF000
	KeyF15         Keycode = 106 | 0xF000
	KeyF16         Keycode = 107 | 0xF000
	KeyF17         Keycode = 108 | 0xF000
	KeyF18         Keycode = 109 | 0xF000
	KeyF19         Keycode = 110 | 0xF000
	KeyF20         Keycode = 111 | 0xF000
	KeyF21         Keycode = 112 | 0xF000
	KeyF22         Keycode = 113 | 0xF000
	KeyF23         Keycode = 114 | 0xF000
	KeyF24         Keycode = 115 | 0xF000

	// International keys for Japanese and other language keyboards
	KeyInternational1 Keycode = 0x87 | 0xF000 // JIS "\" and "_"
	KeyInternational2 Keycode = 0x88 | 0xF000 // JIS Katakana/Hiragana
	KeyInternational3 Keycode = 0x89 | 0xF000 // JIS "¥" and "|"
	KeyInternational4 Keycode = 0x8A | 0xF000 // JIS Henkan
	KeyInternational5 Keycode = 0x8B | 0xF000 // JIS Muhenkan
	KeyInternational6 Keycode = 0x8C | 0xF000 // JIS Numpad ","

	// Language keys for input method switching
	KeyLanguage1 Keycode = 0x90 | 0xF000 // Hangul/English
	KeyLanguage2 Keycode = 0x91 | 0xF000 // Hanja
	KeyLanguage3 Keycode = 0x92 | 0xF000 // JIS Katakana
	KeyLanguage4 Keycode = 0x93 | 0xF000 // JIS Hiragana
	KeyLanguage5 Keycode = 0x94 | 0xF000 // JIS Zenkaku/Hankaku

	KeyUpArrow    Keycode = KeyUp
	KeyDownArrow  Keycode = KeyDown
	KeyLeftArrow  Keycode = KeyLeft
	KeyRightArrow Keycode = KeyRight
	KeyReturn     Keycode = KeyEnter
	KeyLeftCtrl   Keycode = KeyModifierLeftCtrl
	KeyLeftShift  Keycode = KeyModifierLeftShift
	KeyLeftAlt    Keycode = KeyModifierLeftAlt
	KeyLeftGUI    Keycode = KeyModifierLeftGUI
	KeyRightCtrl  Keycode = KeyModifierRightCtrl
	KeyRightShift Keycode = KeyModifierRightShift
	KeyRightAlt   Keycode = KeyModifierRightAlt
	KeyRightGUI   Keycode = KeyModifierRightGUI

	// QMK compatibility aliases for international keys
	KeyInt1 Keycode = KeyInternational1
	KeyInt2 Keycode = KeyInternational2
	KeyInt3 Keycode = KeyInternational3
	KeyInt4 Keycode = KeyInternational4
	KeyInt5 Keycode = KeyInternational5
	KeyInt6 Keycode = KeyInternational6

	// QMK compatibility aliases for language keys
	KeyLng1 Keycode = KeyLanguage1
	KeyLng2 Keycode = KeyLanguage2
	KeyLng3 Keycode = KeyLanguage3
	KeyLng4 Keycode = KeyLanguage4
	KeyLng5 Keycode = KeyLanguage5

	// Common keyboard layout aliases
	KeyRo               Keycode = KeyInternational1 // Japanese "ろ"
	KeyKatakanaHiragana Keycode = KeyInternational2 // Japanese Katakana/Hiragana
	KeyYen              Keycode = KeyInternational3 // Japanese "¥"
	KeyHenkan           Keycode = KeyInternational4 // Japanese Henkan
	KeyMuhenkan         Keycode = KeyInternational5 // Japanese Muhenkan
	KeyKpJpComma        Keycode = KeyInternational6 // Japanese Numpad ","
	KeyHangeul          Keycode = KeyLanguage1      // Korean Hangul/English
	KeyHanja            Keycode = KeyLanguage2      // Korean Hanja
	KeyKatakana         Keycode = KeyLanguage3      // Japanese Katakana
	KeyHiragana         Keycode = KeyLanguage4      // Japanese Hiragana
	KeyZenkakuHankaku   Keycode = KeyLanguage5      // Japanese Zenkaku/Hankaku
)

// Keycodes for layout US English (0x0904)
const (
	keycodeMask Keycode = 0x07FF
	keyMask     Keycode = 0x003F

	shiftMask          Keycode = 0x0040
	altgrMask          Keycode = 0x0080
	deadkeysMask       Keycode = 0x0700
	circumflexBits     Keycode = 0x0100
	acuteAccentBits    Keycode = 0x0200
	graveAccentBits    Keycode = 0x0300
	tildeBits          Keycode = 0x0400
	diaeresisBits      Keycode = 0x0500
	deadkeyCircumflex  Keycode = Key6 | shiftMask
	deadkeyAcuteAccent Keycode = KeyQuote
	deadkeyGraveAccent Keycode = KeyTilde
	deadkeyTilde       Keycode = KeyTilde | shiftMask
	deadkeyDiaeresis   Keycode = KeyQuote | shiftMask

	ASCII00 Keycode = 0            //   0  NUL
	ASCII01 Keycode = 0            //   1  SOH
	ASCII02 Keycode = 0            //   2  STX
	ASCII03 Keycode = 0            //   3  ETX
	ASCII04 Keycode = 0            //   4  EOT
	ASCII05 Keycode = 0            //   5  ENQ
	ASCII06 Keycode = 0            //   6  ACK
	ASCII07 Keycode = 0            //   7  BEL
	ASCII08 Keycode = KeyBackspace //   8  BS
	ASCII09 Keycode = KeyTab       //   9  TAB
	ASCII0A Keycode = KeyEnter     //  10  LF
	ASCII0B Keycode = 0            //  11  VT
	ASCII0C Keycode = 0            //  12  FF
	ASCII0D Keycode = 0            //  13  CR
	ASCII0E Keycode = 0            //  14  SO
	ASCII0F Keycode = 0            //  15  SI
	ASCII10 Keycode = 0            //  16  DEL
	ASCII11 Keycode = 0            //  17  DC1
	ASCII12 Keycode = 0            //  18  DC2
	ASCII13 Keycode = 0            //  19  DC3
	ASCII14 Keycode = 0            //  20  DC4
	ASCII15 Keycode = 0            //  21  NAK
	ASCII16 Keycode = 0            //  22  SYN
	ASCII17 Keycode = 0            //  23  ETB
	ASCII18 Keycode = 0            //  24  CAN
	ASCII19 Keycode = 0            //  25  EM
	ASCII1A Keycode = 0            //  26  SUB
	ASCII1B Keycode = 0            //  27  ESC
	ASCII1C Keycode = 0            //  28  FS
	ASCII1D Keycode = 0            //  29  GS
	ASCII1E Keycode = 0            //  30  RS
	ASCII1F Keycode = 0            //  31  US

	ASCII20     Keycode = KeySpace                             //  32   SPACE
	ASCII21     Keycode = Key1 | shiftMask                     //  33   !
	ASCII22     Keycode = diaeresisBits | KeySpace             //  34   "
	ASCII23     Keycode = Key3 | shiftMask                     //  35   #
	ASCII24     Keycode = Key4 | shiftMask                     //  36   $
	ASCII25     Keycode = Key5 | shiftMask                     //  37   %
	ASCII26     Keycode = Key7 | shiftMask                     //  38   &
	ASCII27     Keycode = acuteAccentBits | KeySpace           //  39   '
	ASCII28     Keycode = Key9 | shiftMask                     //  40   (
	ASCII29     Keycode = Key0 | shiftMask                     //  41   )
	ASCII2A     Keycode = Key8 | shiftMask                     //  42   *
	ASCII2B     Keycode = KeyEqual | shiftMask                 //  43   +
	ASCII2C     Keycode = KeyComma                             //  44   ,
	ASCII2D     Keycode = KeyMinus                             //  45   -
	ASCII2E     Keycode = KeyPeriod                            //  46   .
	ASCII2F     Keycode = KeySlash                             //  47   /
	ASCII30     Keycode = Key0                                 //  48   0
	ASCII31     Keycode = Key1                                 //  49   1
	ASCII32     Keycode = Key2                                 //  50   2
	ASCII33     Keycode = Key3                                 //  51   3
	ASCII34     Keycode = Key4                                 //  52   4
	ASCII35     Keycode = Key5                                 //  53   5
	ASCII36     Keycode = Key6                                 //  54   6
	ASCII37     Keycode = Key7                                 //  55   7
	ASCII38     Keycode = Key8                                 //  55   8
	ASCII39     Keycode = Key9                                 //  57   9
	ASCII3A     Keycode = KeySemicolon | shiftMask             //  58   :
	ASCII3B     Keycode = KeySemicolon                         //  59   ;
	ASCII3C     Keycode = KeyComma | shiftMask                 //  60   <
	ASCII3D     Keycode = KeyEqual                             //  61   =
	ASCII3E     Keycode = KeyPeriod | shiftMask                //  62   >
	ASCII3F     Keycode = KeySlash | shiftMask                 //  63   ?
	ASCII40     Keycode = Key2 | shiftMask                     //  64   @
	ASCII41     Keycode = KeyA | shiftMask                     //  65   A
	ASCII42     Keycode = KeyB | shiftMask                     //  66   B
	ASCII43     Keycode = KeyC | shiftMask                     //  67   C
	ASCII44     Keycode = KeyD | shiftMask                     //  68   D
	ASCII45     Keycode = KeyE | shiftMask                     //  69   E
	ASCII46     Keycode = KeyF | shiftMask                     //  70   F
	ASCII47     Keycode = KeyG | shiftMask                     //  71   G
	ASCII48     Keycode = KeyH | shiftMask                     //  72   H
	ASCII49     Keycode = KeyI | shiftMask                     //  73   I
	ASCII4A     Keycode = KeyJ | shiftMask                     //  74   J
	ASCII4B     Keycode = KeyK | shiftMask                     //  75   K
	ASCII4C     Keycode = KeyL | shiftMask                     //  76   L
	ASCII4D     Keycode = KeyM | shiftMask                     //  77   M
	ASCII4E     Keycode = KeyN | shiftMask                     //  78   N
	ASCII4F     Keycode = KeyO | shiftMask                     //  79   O
	ASCII50     Keycode = KeyP | shiftMask                     //  80   P
	ASCII51     Keycode = KeyQ | shiftMask                     //  81   Q
	ASCII52     Keycode = KeyR | shiftMask                     //  82   R
	ASCII53     Keycode = KeyS | shiftMask                     //  83   S
	ASCII54     Keycode = KeyT | shiftMask                     //  84   T
	ASCII55     Keycode = KeyU | shiftMask                     //  85   U
	ASCII56     Keycode = KeyV | shiftMask                     //  86   V
	ASCII57     Keycode = KeyW | shiftMask                     //  87   W
	ASCII58     Keycode = KeyX | shiftMask                     //  88   X
	ASCII59     Keycode = KeyY | shiftMask                     //  89   Y
	ASCII5A     Keycode = KeyZ | shiftMask                     //  90   Z
	ASCII5B     Keycode = KeyLeftBrace                         //  91   [
	ASCII5C     Keycode = KeyBackslash                         //  92   \
	ASCII5D     Keycode = KeyRightBrace                        //  93   ]
	ASCII5E     Keycode = circumflexBits | KeySpace            //  94   ^
	ASCII5F     Keycode = KeyMinus | shiftMask                 //  95
	ASCII60     Keycode = graveAccentBits | KeySpace           //  96   `
	ASCII61     Keycode = KeyA                                 //  97   a
	ASCII62     Keycode = KeyB                                 //  98   b
	ASCII63     Keycode = KeyC                                 //  99   c
	ASCII64     Keycode = KeyD                                 // 100   d
	ASCII65     Keycode = KeyE                                 // 101   e
	ASCII66     Keycode = KeyF                                 // 102   f
	ASCII67     Keycode = KeyG                                 // 103   g
	ASCII68     Keycode = KeyH                                 // 104   h
	ASCII69     Keycode = KeyI                                 // 105   i
	ASCII6A     Keycode = KeyJ                                 // 106   j
	ASCII6B     Keycode = KeyK                                 // 107   k
	ASCII6C     Keycode = KeyL                                 // 108   l
	ASCII6D     Keycode = KeyM                                 // 109   m
	ASCII6E     Keycode = KeyN                                 // 110   n
	ASCII6F     Keycode = KeyO                                 // 111   o
	ASCII70     Keycode = KeyP                                 // 112   p
	ASCII71     Keycode = KeyQ                                 // 113   q
	ASCII72     Keycode = KeyR                                 // 114   r
	ASCII73     Keycode = KeyS                                 // 115   s
	ASCII74     Keycode = KeyT                                 // 116   t
	ASCII75     Keycode = KeyU                                 // 117   u
	ASCII76     Keycode = KeyV                                 // 118   v
	ASCII77     Keycode = KeyW                                 // 119   w
	ASCII78     Keycode = KeyX                                 // 120   x
	ASCII79     Keycode = KeyY                                 // 121   y
	ASCII7A     Keycode = KeyZ                                 // 122   z
	ASCII7B     Keycode = KeyLeftBrace | shiftMask             // 123   {
	ASCII7C     Keycode = KeyBackslash | shiftMask             // 124   |
	ASCII7D     Keycode = KeyRightBrace | shiftMask            // 125   }
	ASCII7E     Keycode = tildeBits | KeySpace                 // 126   ~
	ASCII7F     Keycode = KeyBackspace                         // 127   DEL
	ISO88591A0  Keycode = KeySpace                             // 160         Nonbreakng Space
	ISO88591A1  Keycode = Key1 | altgrMask                     // 161   ¡     Inverted Exclamation
	ISO88591A2  Keycode = KeyC | altgrMask | shiftMask         // 162   ¢     Cent SIGN
	ISO88591A3  Keycode = Key4 | altgrMask | shiftMask         // 163   £     Pound Sign
	ISO88591A4  Keycode = Key4 | altgrMask                     // 164   ¤     Currency or Euro Sign
	ISO88591A5  Keycode = KeyMinus | altgrMask                 // 165   ¥     YEN SIGN
	ISO88591A6  Keycode = KeyBackslash | altgrMask | shiftMask // 166   ¦     BROKEN BAR			??
	ISO88591A7  Keycode = KeyS | altgrMask | shiftMask         // 167   §     SECTION SIGN
	ISO88591A8  Keycode = KeyQuote | altgrMask | shiftMask     // 168   ¨     DIAERESIS
	ISO88591A9  Keycode = KeyC | altgrMask                     // 169   ©     COPYRIGHT SIGN
	ISO88591AA  Keycode = 0                                    // 170   ª     FEMININE ORDINAL
	ISO88591AB  Keycode = KeyLeftBrace | altgrMask             // 171   «     LEFT DOUBLE ANGLE QUOTE
	ISO88591AC  Keycode = KeyBackslash | altgrMask             // 172   ¬     NOT SIGN			??
	ISO88591AD  Keycode = 0                                    // 173         SOFT HYPHEN
	ISO88591AE  Keycode = KeyR | altgrMask                     // 174   ®     REGISTERED SIGN
	ISO88591AF  Keycode = 0                                    // 175   ¯     MACRON
	ISO88591B0  Keycode = KeySemicolon | altgrMask | shiftMask // 176   °     DEGREE SIGN
	ISO88591B1  Keycode = 0                                    // 177   ±     PLUS-MINUS SIGN
	ISO88591B2  Keycode = Key2 | altgrMask                     // 178   ²     SUPERSCRIPT TWO
	ISO88591B3  Keycode = Key3 | altgrMask                     // 179   ³     SUPERSCRIPT THREE
	ISO88591B4  Keycode = KeyQuote | altgrMask                 // 180   ´     ACUTE ACCENT
	ISO88591B5  Keycode = KeyM | altgrMask                     // 181   µ     MICRO SIGN
	ISO88591B6  Keycode = KeySemicolon | altgrMask             // 182   ¶     PILCROW SIGN
	ISO88591B7  Keycode = 0                                    // 183   ·     MIDDLE DOT
	ISO88591B8  Keycode = 0                                    // 184   ¸     CEDILLA
	ISO88591B9  Keycode = Key1 | altgrMask | shiftMask         // 185   ¹     SUPERSCRIPT ONE
	ISO88591BA  Keycode = 0                                    // 186   º     MASCULINE ORDINAL
	ISO88591BB  Keycode = KeyRightBrace | altgrMask            // 187   »     RIGHT DOUBLE ANGLE QUOTE
	ISO88591BC  Keycode = Key6 | altgrMask                     // 188   ¼     FRACTION ONE QUARTER
	ISO88591BD  Keycode = Key7 | altgrMask                     // 189   ½     FRACTION ONE HALF
	ISO88591BE  Keycode = Key8 | altgrMask                     // 190   ¾     FRACTION THREE QUARTERS
	ISO88591BF  Keycode = KeySlash | altgrMask                 // 191   ¿     INVERTED QUESTION MARK
	ISO88591C0  Keycode = graveAccentBits | KeyA | shiftMask   // 192   À     A GRAVE
	ISO88591C1  Keycode = KeyA | altgrMask | shiftMask         // 193   Á     A ACUTE
	ISO88591C2  Keycode = circumflexBits | KeyA | shiftMask    // 194   Â     A CIRCUMFLEX
	ISO88591C3  Keycode = tildeBits | KeyA | shiftMask         // 195   Ã     A TILDE
	ISO88591C4  Keycode = KeyQ | altgrMask | shiftMask         // 196   Ä     A DIAERESIS
	ISO88591C5  Keycode = KeyW | altgrMask | shiftMask         // 197   Å     A RING ABOVE
	ISO88591C6  Keycode = KeyZ | altgrMask | shiftMask         // 198   Æ     AE
	ISO88591C7  Keycode = KeyComma | altgrMask | shiftMask     // 199   Ç     C CEDILLA
	ISO88591C8  Keycode = graveAccentBits | KeyE | shiftMask   // 200   È     E GRAVE
	ISO88591C9  Keycode = KeyE | altgrMask | shiftMask         // 201   É     E ACUTE
	ISO88591CA  Keycode = circumflexBits | KeyE | shiftMask    // 202   Ê     E CIRCUMFLEX
	ISO88591CB  Keycode = diaeresisBits | KeyE | shiftMask     // 203   Ë     E DIAERESIS
	ISO88591CC  Keycode = graveAccentBits | KeyI | shiftMask   // 204   Ì     I GRAVE
	ISO88591CD  Keycode = KeyI | altgrMask | shiftMask         // 205   Í     I ACUTE
	ISO88591CE  Keycode = circumflexBits | KeyI | shiftMask    // 206   Î     I CIRCUMFLEX
	ISO88591CF  Keycode = diaeresisBits | KeyI | shiftMask     // 207   Ï     I DIAERESIS
	ISO88591D0  Keycode = KeyD | altgrMask | shiftMask         // 208   Ð     ETH
	ISO88591D1  Keycode = KeyN | altgrMask | shiftMask         // 209   Ñ     N TILDE
	ISO88591D2  Keycode = graveAccentBits | KeyO | shiftMask   // 210   Ò     O GRAVE
	ISO88591D3  Keycode = KeyO | altgrMask | shiftMask         // 211   Ó     O ACUTE
	ISO88591D4  Keycode = circumflexBits | KeyO | shiftMask    // 212   Ô     O CIRCUMFLEX
	ISO88591D5  Keycode = tildeBits | KeyO | shiftMask         // 213   Õ     O TILDE
	ISO88591D6  Keycode = KeyP | altgrMask | shiftMask         // 214   Ö     O DIAERESIS
	ISO88591D7  Keycode = KeyEqual | altgrMask                 // 215   ×     MULTIPLICATION
	ISO88591D8  Keycode = KeyL | altgrMask | shiftMask         // 216   Ø     O STROKE
	ISO88591D9  Keycode = graveAccentBits | KeyU | shiftMask   // 217   Ù     U GRAVE
	ISO88591DA  Keycode = KeyU | altgrMask | shiftMask         // 218   Ú     U ACUTE
	ISO88591DB  Keycode = circumflexBits | KeyU | shiftMask    // 219   Û     U CIRCUMFLEX
	ISO88591DC  Keycode = KeyY | altgrMask | shiftMask         // 220   Ü     U DIAERESIS
	ISO88591DD  Keycode = acuteAccentBits | KeyY | shiftMask   // 221   Ý     Y ACUTE
	ISO88591DE  Keycode = KeyT | altgrMask | shiftMask         // 222   Þ     THORN
	ISO88591DF  Keycode = KeyS | altgrMask                     // 223   ß     SHARP S
	ISO88591E0  Keycode = graveAccentBits | KeyA               // 224   à     a GRAVE
	ISO88591E1  Keycode = KeyA | altgrMask                     // 225   á     a ACUTE
	ISO88591E2  Keycode = circumflexBits | KeyA                // 226   â     a CIRCUMFLEX
	ISO88591E3  Keycode = tildeBits | KeyA                     // 227   ã     a TILDE
	ISO88591E4  Keycode = diaeresisBits | KeyA                 // 228   ä     a DIAERESIS
	ISO88591E5  Keycode = KeyW | altgrMask                     // 229   å     a RING ABOVE
	ISO88591E6  Keycode = KeyZ | altgrMask                     // 230   æ     ae
	ISO88591E7  Keycode = KeyComma | altgrMask                 // 231   ç     c CEDILLA
	ISO88591E8  Keycode = graveAccentBits | KeyE               // 232   è     e GRAVE
	ISO88591E9  Keycode = acuteAccentBits | KeyE               // 233   é     e ACUTE
	ISO88591EA  Keycode = circumflexBits | KeyE                // 234   ê     e CIRCUMFLEX
	ISO88591EB  Keycode = diaeresisBits | KeyE                 // 235   ë     e DIAERESIS
	ISO88591EC  Keycode = graveAccentBits | KeyI               // 236   ì     i GRAVE
	ISO88591ED  Keycode = KeyI | altgrMask                     // 237   í     i ACUTE
	ISO88591EE  Keycode = circumflexBits | KeyI                // 238   î     i CIRCUMFLEX
	ISO88591EF  Keycode = diaeresisBits | KeyI                 // 239   ï     i DIAERESIS
	ISO88591F0  Keycode = KeyD | altgrMask                     // 240   ð     ETH
	ISO88591F1  Keycode = KeyN | altgrMask                     // 241   ñ     n TILDE
	ISO88591F2  Keycode = graveAccentBits | KeyO               // 242   ò     o GRAVE
	ISO88591F3  Keycode = KeyO | altgrMask                     // 243   ó     o ACUTE
	ISO88591F4  Keycode = circumflexBits | KeyO                // 244   ô     o CIRCUMFLEX
	ISO88591F5  Keycode = tildeBits | KeyO                     // 245   õ     o TILDE
	ISO88591F6  Keycode = KeyP | altgrMask                     // 246   ö     o DIAERESIS
	ISO88591F7  Keycode = KeyEqual | altgrMask | shiftMask     // 247   ÷     DIVISION
	ISO88591F8  Keycode = KeyL | altgrMask                     // 248   ø     o STROKE
	ISO88591F9  Keycode = graveAccentBits | KeyU               // 249   ù     u GRAVE
	ISO88591FA  Keycode = KeyU | altgrMask                     // 250   ú     u ACUTE
	ISO88591FB  Keycode = circumflexBits | KeyU                // 251   û     u CIRCUMFLEX
	ISO88591FC  Keycode = KeyY | altgrMask                     // 252   ü     u DIAERESIS
	ISO88591FD  Keycode = acuteAccentBits | KeyY               // 253   ý     y ACUTE
	ISO88591FE  Keycode = KeyT | altgrMask                     // 254   þ     THORN
	ISO88591FF  Keycode = diaeresisBits | KeyY                 // 255   ÿ     y DIAERESIS
	UNICODE20AC Keycode = Key5 | altgrMask                     // 20AC  €     Euro Sign
)

var ascii = [...]Keycode{
	ASCII00.mask(), ASCII01.mask(), ASCII02.mask(), ASCII03.mask(),
	ASCII04.mask(), ASCII05.mask(), ASCII06.mask(), ASCII07.mask(),
	ASCII08.mask(), ASCII09.mask(), ASCII0A.mask(), ASCII0B.mask(),
	ASCII0C.mask(), ASCII0D.mask(), ASCII0E.mask(), ASCII0F.mask(),
	ASCII10.mask(), ASCII11.mask(), ASCII12.mask(), ASCII13.mask(),
	ASCII14.mask(), ASCII15.mask(), ASCII16.mask(), ASCII17.mask(),
	ASCII18.mask(), ASCII19.mask(), ASCII1A.mask(), ASCII1B.mask(),
	ASCII1C.mask(), ASCII1D.mask(), ASCII1E.mask(), ASCII1F.mask(),
	ASCII20.mask(), ASCII21.mask(), ASCII22.mask(), ASCII23.mask(),
	ASCII24.mask(), ASCII25.mask(), ASCII26.mask(), ASCII27.mask(),
	ASCII28.mask(), ASCII29.mask(), ASCII2A.mask(), ASCII2B.mask(),
	ASCII2C.mask(), ASCII2D.mask(), ASCII2E.mask(), ASCII2F.mask(),
	ASCII30.mask(), ASCII31.mask(), ASCII32.mask(), ASCII33.mask(),
	ASCII34.mask(), ASCII35.mask(), ASCII36.mask(), ASCII37.mask(),
	ASCII38.mask(), ASCII39.mask(), ASCII3A.mask(), ASCII3B.mask(),
	ASCII3C.mask(), ASCII3D.mask(), ASCII3E.mask(), ASCII3F.mask(),
	ASCII40.mask(), ASCII41.mask(), ASCII42.mask(), ASCII43.mask(),
	ASCII44.mask(), ASCII45.mask(), ASCII46.mask(), ASCII47.mask(),
	ASCII48.mask(), ASCII49.mask(), ASCII4A.mask(), ASCII4B.mask(),
	ASCII4C.mask(), ASCII4D.mask(), ASCII4E.mask(), ASCII4F.mask(),
	ASCII50.mask(), ASCII51.mask(), ASCII52.mask(), ASCII53.mask(),
	ASCII54.mask(), ASCII55.mask(), ASCII56.mask(), ASCII57.mask(),
	ASCII58.mask(), ASCII59.mask(), ASCII5A.mask(), ASCII5B.mask(),
	ASCII5C.mask(), ASCII5D.mask(), ASCII5E.mask(), ASCII5F.mask(),
	ASCII60.mask(), ASCII61.mask(), ASCII62.mask(), ASCII63.mask(),
	ASCII64.mask(), ASCII65.mask(), ASCII66.mask(), ASCII67.mask(),
	ASCII68.mask(), ASCII69.mask(), ASCII6A.mask(), ASCII6B.mask(),
	ASCII6C.mask(), ASCII6D.mask(), ASCII6E.mask(), ASCII6F.mask(),
	ASCII70.mask(), ASCII71.mask(), ASCII72.mask(), ASCII73.mask(),
	ASCII74.mask(), ASCII75.mask(), ASCII76.mask(), ASCII77.mask(),
	ASCII78.mask(), ASCII79.mask(), ASCII7A.mask(), ASCII7B.mask(),
	ASCII7C.mask(), ASCII7D.mask(), ASCII7E.mask(), ASCII7F.mask(),
}

var iso88591 = [...]Keycode{
	ISO88591A0.mask(), ISO88591A1.mask(), ISO88591A2.mask(), ISO88591A3.mask(),
	ISO88591A4.mask(), ISO88591A5.mask(), ISO88591A6.mask(), ISO88591A7.mask(),
	ISO88591A8.mask(), ISO88591A9.mask(), ISO88591AA.mask(), ISO88591AB.mask(),
	ISO88591AC.mask(), ISO88591AD.mask(), ISO88591AE.mask(), ISO88591AF.mask(),
	ISO88591B0.mask(), ISO88591B1.mask(), ISO88591B2.mask(), ISO88591B3.mask(),
	ISO88591B4.mask(), ISO88591B5.mask(), ISO88591B6.mask(), ISO88591B7.mask(),
	ISO88591B8.mask(), ISO88591B9.mask(), ISO88591BA.mask(), ISO88591BB.mask(),
	ISO88591BC.mask(), ISO88591BD.mask(), ISO88591BE.mask(), ISO88591BF.mask(),
	ISO88591C0.mask(), ISO88591C1.mask(), ISO88591C2.mask(), ISO88591C3.mask(),
	ISO88591C4.mask(), ISO88591C5.mask(), ISO88591C6.mask(), ISO88591C7.mask(),
	ISO88591C8.mask(), ISO88591C9.mask(), ISO88591CA.mask(), ISO88591CB.mask(),
	ISO88591CC.mask(), ISO88591CD.mask(), ISO88591CE.mask(), ISO88591CF.mask(),
	ISO88591D0.mask(), ISO88591D1.mask(), ISO88591D2.mask(), ISO88591D3.mask(),
	ISO88591D4.mask(), ISO88591D5.mask(), ISO88591D6.mask(), ISO88591D7.mask(),
	ISO88591D8.mask(), ISO88591D9.mask(), ISO88591DA.mask(), ISO88591DB.mask(),
	ISO88591DC.mask(), ISO88591DD.mask(), ISO88591DE.mask(), ISO88591DF.mask(),
	ISO88591E0.mask(), ISO88591E1.mask(), ISO88591E2.mask(), ISO88591E3.mask(),
	ISO88591E4.mask(), ISO88591E5.mask(), ISO88591E6.mask(), ISO88591E7.mask(),
	ISO88591E8.mask(), ISO88591E9.mask(), ISO88591EA.mask(), ISO88591EB.mask(),
	ISO88591EC.mask(), ISO88591ED.mask(), ISO88591EE.mask(), ISO88591EF.mask(),
	ISO88591F0.mask(), ISO88591F1.mask(), ISO88591F2.mask(), ISO88591F3.mask(),
	ISO88591F4.mask(), ISO88591F5.mask(), ISO88591F6.mask(), ISO88591F7.mask(),
	ISO88591F8.mask(), ISO88591F9.mask(), ISO88591FA.mask(), ISO88591FB.mask(),
	ISO88591FC.mask(), ISO88591FD.mask(), ISO88591FE.mask(), ISO88591FF.mask(),
}
