type ZeroTo10 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
type ZeroTo100 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100;
type Minus100ToZero = 0 | -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | -21 | -22 | -23 | -24 | -25 | -26 | -27 | -28 | -29 | -30 | -31 | -32 | -33 | -34 | -35 | -36 | -37 | -38 | -39 | -40 | -41 | -42 | -43 | -44 | -45 | -46 | -47 | -48 | -49 | -50 | -51 | -52 | -53 | -54 | -55 | -56 | -57 | -58 | -59 | -60 | -61 | -62 | -63 | -64 | -65 | -66 | -67 | -68 | -69 | -70 | -71 | -72 | -73 | -74 | -75 | -76 | -77 | -78 | -79 | -80 | -81 | -82 | -83 | -84 | -85 | -86 | -87 | -88 | -89 | -90 | -91 | -92 | -93 | -94 | -95 | -96 | -97 | -98 | -99 | -100;
type Minus100To100 = Minus100ToZero | ZeroTo100;
type PlusOne = {
    '-100': -99;
    '-99': -98;
    '-98': -97;
    '-97': -96;
    '-96': -95;
    '-95': -94;
    '-94': -93;
    '-93': -92;
    '-92': -91;
    '-91': -90;
    '-90': -89;
    '-89': -88;
    '-88': -87;
    '-87': -86;
    '-86': -85;
    '-85': -84;
    '-84': -83;
    '-83': -82;
    '-82': -81;
    '-81': -80;
    '-80': -79;
    '-79': -78;
    '-78': -77;
    '-77': -76;
    '-76': -75;
    '-75': -74;
    '-74': -73;
    '-73': -72;
    '-72': -71;
    '-71': -70;
    '-70': -69;
    '-69': -68;
    '-68': -67;
    '-67': -66;
    '-66': -65;
    '-65': -64;
    '-64': -63;
    '-63': -62;
    '-62': -61;
    '-61': -60;
    '-60': -59;
    '-59': -58;
    '-58': -57;
    '-57': -56;
    '-56': -55;
    '-55': -54;
    '-54': -53;
    '-53': -52;
    '-52': -51;
    '-51': -50;
    '-50': -49;
    '-49': -48;
    '-48': -47;
    '-47': -46;
    '-46': -45;
    '-45': -44;
    '-44': -43;
    '-43': -42;
    '-42': -41;
    '-41': -40;
    '-40': -39;
    '-39': -38;
    '-38': -37;
    '-37': -36;
    '-36': -35;
    '-35': -34;
    '-34': -33;
    '-33': -32;
    '-32': -31;
    '-31': -30;
    '-30': -29;
    '-29': -28;
    '-28': -27;
    '-27': -26;
    '-26': -25;
    '-25': -24;
    '-24': -23;
    '-23': -22;
    '-22': -21;
    '-21': -20;
    '-20': -19;
    '-19': -18;
    '-18': -17;
    '-17': -16;
    '-16': -15;
    '-15': -14;
    '-14': -13;
    '-13': -12;
    '-12': -11;
    '-11': -10;
    '-10': -9;
    '-9': -8;
    '-8': -7;
    '-7': -6;
    '-6': -5;
    '-5': -4;
    '-4': -3;
    '-3': -2;
    '-2': -1;
    '-1': 0;
    '0': 1;
    '1': 2;
    '2': 3;
    '3': 4;
    '4': 5;
    '5': 6;
    '6': 7;
    '7': 8;
    '8': 9;
    '9': 10;
    '10': 11;
    '11': 12;
    '12': 13;
    '13': 14;
    '14': 15;
    '15': 16;
    '16': 17;
    '17': 18;
    '18': 19;
    '19': 20;
    '20': 21;
    '21': 22;
    '22': 23;
    '23': 24;
    '24': 25;
    '25': 26;
    '26': 27;
    '27': 28;
    '28': 29;
    '29': 30;
    '30': 31;
    '31': 32;
    '32': 33;
    '33': 34;
    '34': 35;
    '35': 36;
    '36': 37;
    '37': 38;
    '38': 39;
    '39': 40;
    '40': 41;
    '41': 42;
    '42': 43;
    '43': 44;
    '44': 45;
    '45': 46;
    '46': 47;
    '47': 48;
    '48': 49;
    '49': 50;
    '50': 51;
    '51': 52;
    '52': 53;
    '53': 54;
    '54': 55;
    '55': 56;
    '56': 57;
    '57': 58;
    '58': 59;
    '59': 60;
    '60': 61;
    '61': 62;
    '62': 63;
    '63': 64;
    '64': 65;
    '65': 66;
    '66': 67;
    '67': 68;
    '68': 69;
    '69': 70;
    '70': 71;
    '71': 72;
    '72': 73;
    '73': 74;
    '74': 75;
    '75': 76;
    '76': 77;
    '77': 78;
    '78': 79;
    '79': 80;
    '80': 81;
    '81': 82;
    '82': 83;
    '83': 84;
    '84': 85;
    '85': 86;
    '86': 87;
    '87': 88;
    '88': 89;
    '89': 90;
    '90': 91;
    '91': 92;
    '92': 93;
    '93': 94;
    '94': 95;
    '95': 96;
    '96': 97;
    '97': 98;
    '98': 99;
    '99': 100;
    '100': 101;
};
type MinusOne = {
    '-100': -101;
    '-99': -100;
    '-98': -99;
    '-97': -98;
    '-96': -97;
    '-95': -96;
    '-94': -95;
    '-93': -94;
    '-92': -93;
    '-91': -92;
    '-90': -91;
    '-89': -90;
    '-88': -89;
    '-87': -88;
    '-86': -87;
    '-85': -86;
    '-84': -85;
    '-83': -84;
    '-82': -83;
    '-81': -82;
    '-80': -81;
    '-79': -80;
    '-78': -79;
    '-77': -78;
    '-76': -77;
    '-75': -76;
    '-74': -75;
    '-73': -74;
    '-72': -73;
    '-71': -72;
    '-70': -71;
    '-69': -70;
    '-68': -69;
    '-67': -68;
    '-66': -67;
    '-65': -66;
    '-64': -65;
    '-63': -64;
    '-62': -63;
    '-61': -62;
    '-60': -61;
    '-59': -60;
    '-58': -59;
    '-57': -58;
    '-56': -57;
    '-55': -56;
    '-54': -55;
    '-53': -54;
    '-52': -53;
    '-51': -52;
    '-50': -51;
    '-49': -50;
    '-48': -49;
    '-47': -48;
    '-46': -47;
    '-45': -46;
    '-44': -45;
    '-43': -44;
    '-42': -43;
    '-41': -42;
    '-40': -41;
    '-39': -40;
    '-38': -39;
    '-37': -38;
    '-36': -37;
    '-35': -36;
    '-34': -35;
    '-33': -34;
    '-32': -33;
    '-31': -32;
    '-30': -31;
    '-29': -30;
    '-28': -29;
    '-27': -28;
    '-26': -27;
    '-25': -26;
    '-24': -25;
    '-23': -24;
    '-22': -23;
    '-21': -22;
    '-20': -21;
    '-19': -20;
    '-18': -19;
    '-17': -18;
    '-16': -17;
    '-15': -16;
    '-14': -15;
    '-13': -14;
    '-12': -13;
    '-11': -12;
    '-10': -11;
    '-9': -10;
    '-8': -9;
    '-7': -8;
    '-6': -7;
    '-5': -6;
    '-4': -5;
    '-3': -4;
    '-2': -3;
    '-1': -2;
    '0': -1;
    '1': 0;
    '2': 1;
    '3': 2;
    '4': 3;
    '5': 4;
    '6': 5;
    '7': 6;
    '8': 7;
    '9': 8;
    '10': 9;
    '11': 10;
    '12': 11;
    '13': 12;
    '14': 13;
    '15': 14;
    '16': 15;
    '17': 16;
    '18': 17;
    '19': 18;
    '20': 19;
    '21': 20;
    '22': 21;
    '23': 22;
    '24': 23;
    '25': 24;
    '26': 25;
    '27': 26;
    '28': 27;
    '29': 28;
    '30': 29;
    '31': 30;
    '32': 31;
    '33': 32;
    '34': 33;
    '35': 34;
    '36': 35;
    '37': 36;
    '38': 37;
    '39': 38;
    '40': 39;
    '41': 40;
    '42': 41;
    '43': 42;
    '44': 43;
    '45': 44;
    '46': 45;
    '47': 46;
    '48': 47;
    '49': 48;
    '50': 49;
    '51': 50;
    '52': 51;
    '53': 52;
    '54': 53;
    '55': 54;
    '56': 55;
    '57': 56;
    '58': 57;
    '59': 58;
    '60': 59;
    '61': 60;
    '62': 61;
    '63': 62;
    '64': 63;
    '65': 64;
    '66': 65;
    '67': 66;
    '68': 67;
    '69': 68;
    '70': 69;
    '71': 70;
    '72': 71;
    '73': 72;
    '74': 73;
    '75': 74;
    '76': 75;
    '77': 76;
    '78': 77;
    '79': 78;
    '80': 79;
    '81': 80;
    '82': 81;
    '83': 82;
    '84': 83;
    '85': 84;
    '86': 85;
    '87': 86;
    '88': 87;
    '89': 88;
    '90': 89;
    '91': 90;
    '92': 91;
    '93': 92;
    '94': 93;
    '95': 94;
    '96': 95;
    '97': 96;
    '98': 97;
    '99': 98;
    '100': 99;
};

type Decrement<N extends Minus100To100> = MinusOne[`${N}`];

type Increment<N extends Minus100To100> = PlusOne[`${N}`];

type Range<First extends Minus100To100, Last extends Minus100To100> = First extends Last ? First : Increment<First> extends Last ? First | Last : Increment<Increment<First>> extends Last ? First | Increment<First> | Last : First | Increment<First> | Increment<Increment<First>> | Range<Increment<Increment<Increment<First>>>, Last>;

type Insert<T extends any[] & {
    length: ZeroTo100;
}, Item, Index extends number = T['length']> = Index extends 0 ? [Item, ...T] : T extends [infer A, ...infer Rest] ? [A, ...Insert<Rest, Item, Decrement<Index>>] : [
    ...T,
    Item
];

type Literal = string | number | bigint | symbol;
type Join<T extends Literal[], Separator extends Literal> = T extends [infer Head, ...infer Tail] ? Tail extends [] ? `${Head}` : `${Head}${Separator}${Join<Tail, Separator>}` : '';

type InsertAnywhere<T extends any[] & {
    length: ZeroTo100;
}, X> = Insert<T, X, Range<0, T['length']>>;
type Permutation<T extends any[] & {
    length: ZeroTo10;
}> = T extends [infer A, infer B, infer C, ...infer Rest] ? InsertAnywhere<InsertAnywhere<InsertAnywhere<Permutation<Rest>, A>, B>, C> : T extends [infer A, infer B, ...infer Rest] ? InsertAnywhere<InsertAnywhere<Permutation<Rest>, A>, B> : T extends [infer A, ...infer Rest] ? InsertAnywhere<Permutation<Rest>, A> : [
];

type Slice<T extends any[] & {
    length: ZeroTo100;
}, Start extends ZeroTo100, Count extends ZeroTo100 = 100> = Count extends 0 ? [] : T extends [infer Head, ...infer Tail] ? Start extends 0 ? [Head, ...Slice<Tail, 0, Decrement<Count>>] : Slice<Tail, Decrement<Start>, Count> : [];

type SubArray<T extends any[] & {
    length: ZeroTo100;
}> = Slice<T, Range<0, T['length']>, Range<0, T['length']>>;

type Modifiers = ['ctrl', 'alt', 'meta', 'shift'];
type Modifier = Modifiers[number];
type AliasCharacter = 'space' | 'plus' | 'up' | 'down' | 'left' | 'right' | 'esc';
type Key = Join<NormalizedKey<Character | AliasCharacter>, '+'>;
type NormalizedKey<C extends string = Character> = SubArray<Permutation<Modifiers>> | [...SubArray<Permutation<Modifiers>>, C];
type EncodedKey = number;
type Sequence = Key[];
type NormalizedSequence = NormalizedKey[];
type EncodedSequence = number;
type KeyboardEventType = 'keydown' | 'keyup';
type Callback = (event?: KeyboardEvent) => any;
type KeyboardEventListener = (event: KeyboardEvent) => any;
type State = {
    history: EncodedKey[];
    historySize: number;
    disabledSequenceCodes: Set<EncodedSequence>;
    bindings: Map<EncodedSequence, Set<Callback>>;
};
type Binding = [Key, Callback] | [Key, Key, Callback] | [Key, Key, Key, Callback] | [Key, Key, Key, Key, Callback];
interface HandlerInterface {
    add(...args: Binding): this;
    remove(...args: Binding): this;
    enable(...keys: Sequence): this;
    disable(...keys: Sequence): this;
    handle(event: KeyboardEvent): boolean;
}
type Character = '_' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | ' ' | '`' | "'" | '"' | '~' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '(' | ')' | '.' | '-' | '+' | '=' | '[' | ']' | '{' | '}' | '<' | '>' | ',' | '/' | '?' | ';' | ':' | '\\' | '|' | 'capslock' | 'numlock' | 'enter' | 'tab' | 'arrowdown' | 'arrowleft' | 'arrowright' | 'arrowup' | 'end' | 'home' | 'pagedown' | 'pageup' | 'backspace' | 'delete' | 'insert' | 'escape' | 'f1' | 'f2' | 'f3' | 'f4' | 'f5' | 'f6' | 'f7' | 'f8' | 'f9' | 'f10' | 'f11' | 'f12' | 'f13' | 'f14' | 'f15' | 'f16' | 'f17' | 'f18' | 'f19' | 'f20' | 'f21' | 'f22' | 'f23';

declare class Handler implements HandlerInterface {
    protected state: State;
    constructor(state: State);
    add(...args: Binding): this;
    remove(...args: Binding): this;
    enable(...keys: Sequence): this;
    disable(...keys: Sequence): this;
    handle(event: KeyboardEvent): boolean;
}

declare function keys(): Handler;

export { type AliasCharacter, type Binding, type Callback, type Character, type EncodedKey, type EncodedSequence, type HandlerInterface, type Key, type KeyboardEventListener, type KeyboardEventType, type Modifier, type NormalizedKey, type NormalizedSequence, type Sequence, type State, keys as default, keys };
