/** Host normalizes DOM/native input; only the winning layer consumes an event. */ export type CanvasKeyInput={readonly key:string;readonly composing?:boolean;readonly textEditing?:boolean;readonly overlay?:boolean;readonly defaultPrevented?:boolean;readonly ctrl?:boolean;readonly meta?:boolean;readonly alt?:boolean;readonly shift?:boolean}; export type InputClaim='text'|'overlay'|'gesture'|'tool'|'shortcut'|'unclaimed'; export type KeyHandler=(input:CanvasKeyInput)=>boolean; export function routeCanvasKey(input:CanvasKeyInput,handlers:{gesture?:KeyHandler;tool?:KeyHandler;shortcut?:KeyHandler}):InputClaim{ if(input.defaultPrevented)return 'unclaimed'; if(input.composing||input.textEditing)return 'text'; if(input.overlay)return 'overlay'; for(const layer of ['gesture','tool','shortcut'] as const)if(handlers[layer]?.(input))return layer; return 'unclaimed'; }