{
  "version": 3,
  "sources": ["../../../plugins/keyboard/input.js", "../../../plugins/keyboard/index.js"],
  "sourcesContent": ["/**\r\n * Keyboard Input Command for Pi.js\r\n * \r\n * Provides text input functionality with cursor blinking and validation.\r\n * \r\n * @module plugins/keyboard/input\r\n */\r\n\r\n\"use strict\";\r\n\r\nconst CURSOR_BLINK = 500;\r\n\r\n// Input state\r\nlet m_inputData = null;\r\n\r\n// Store pluginApi reference for use in functions\r\nlet m_pluginApi = null;\r\n\r\n\r\n\r\n/***************************************************************************************************\r\n * Input Command Registration\r\n **************************************************************************************************/\r\n\r\n\r\n/**\r\n * Initialize input command\r\n * \r\n * @param {Object} pluginApi - Plugin API provided by Pi.js\r\n * @returns {void}\r\n */\r\nexport function initInput( pluginApi ) {\r\n\r\n\tm_pluginApi = pluginApi;\r\n\r\n\t// Register screen commands\r\n\tpluginApi.addCommand(\r\n\t\t\"input\", input, true,\r\n\t\t[ \"prompt\", \"fn\", \"cursor\", \"isNumber\", \"isInteger\", \"allowNegative\", \"maxLength\" ]\r\n\t);\r\n\tpluginApi.addCommand( \"cancelInput\", cancelInput, true, [] );\r\n}\r\n\r\n\r\n/***************************************************************************************************\r\n * External API Commands\r\n **************************************************************************************************/\r\n\r\n\r\n/**\r\n * Input command - Get text input from user\r\n * \r\n * @param {Object} screenData - Screen data object\r\n * @param {Object} options - Input options\r\n * @param {string} options.prompt - Prompt text to display\r\n * @param {Function} [options.fn] - Callback function called with result\r\n * @param {string} [options.cursor] - Cursor character (default: block character)\r\n * @param {boolean} [options.isNumber] - If true, only allow numeric input\r\n * @param {boolean} [options.isInteger] - If true, only allow integer input\r\n * @param {boolean} [options.allowNegative] - If true, allow negative numbers\r\n * @param {number} [options.maxLength] - Maximum length of input string\r\n * @returns {Promise} Promise that resolves with input value or rejects on cancel\r\n */\r\nfunction input( screenData, options ) {\r\n\tconst prompt = options.prompt;\r\n\tconst fn = options.fn;\r\n\tconst cursor = options.cursor ? options.cursor : String.fromCharCode( 219 );\r\n\tconst isNumber = !!options.isNumber;\r\n\tconst isInteger = !!options.isInteger;\r\n\tconst allowNegative = !!options.allowNegative;\r\n\tconst maxLength = options.maxLength;\r\n\r\n\tif( typeof prompt !== \"string\" ) {\r\n\t\tconst error = new TypeError( \"input: prompt must be a string\" );\r\n\t\terror.code = \"INVALID_PARAMETERS\";\r\n\t\tthrow error;\r\n\t}\r\n\r\n\tif( fn && typeof fn !== \"function\" ) {\r\n\t\tconst error = new TypeError( \"input: fn must be a function.\" );\r\n\t\terror.code = \"INVALID_PARAMETERS\";\r\n\t\tthrow error;\r\n\t}\r\n\r\n\tif( typeof cursor !== \"string\" ) {\r\n\t\tconst error = new TypeError( \"input: cursor must be a string\" );\r\n\t\terror.code = \"INVALID_PARAMETERS\";\r\n\t\tthrow error;\r\n\t}\r\n\r\n\tif(\r\n\t\tmaxLength !== null &&\r\n\t\t( typeof maxLength !== \"number\" || maxLength < 0 || !Number.isInteger( maxLength ) )\r\n\t) {\r\n\t\tconst error = new TypeError( \"input: maxLength must be a non-negative integer\" );\r\n\t\terror.code = \"INVALID_PARAMETERS\";\r\n\t\tthrow error;\r\n\t}\r\n\r\n\t// Create promise for async/await support\r\n\tlet resolvePromise, rejectPromise;\r\n\tconst promise = new Promise( ( resolve, reject ) => {\r\n\t\tresolvePromise = resolve;\r\n\t\trejectPromise = reject;\r\n\t} );\r\n\r\n\tif( m_inputData ) {\r\n\t\tfinishInput( true );\r\n\t}\r\n\r\n\tm_inputData = {\r\n\t\t\"screenData\": screenData,\r\n\t\t\"prompt\": prompt,\r\n\t\t\"cursor\": cursor,\r\n\t\t\"lastCursorBlink\": Date.now(),\r\n\t\t\"showCursor\": true,\r\n\t\t\"isNumber\": isNumber,\r\n\t\t\"isInteger\": isInteger,\r\n\t\t\"allowNegative\": allowNegative,\r\n\t\t\"maxLength\": maxLength,\r\n\t\t\"val\": \"\",\r\n\t\t\"fn\": fn,\r\n\t\t\"resolve\": resolvePromise,\r\n\t\t\"reject\": rejectPromise,\r\n\t\t\"backgroundImageName\": null,\r\n\t\t\"backgroundImage\": null,\r\n\t\t\"captureX\": null,\r\n\t\t\"captureY\": null\r\n\t};\r\n\r\n\tstartInput();\r\n\r\n\treturn promise;\r\n}\r\n\r\n/**\r\n * Cancel input command - Cancel current input\r\n * \r\n * @param {Object} screenData - Screen data object\r\n * @returns {void}\r\n */\r\nfunction cancelInput( screenData ) {\r\n\tif( m_inputData && m_inputData.screenData === screenData ) {\r\n\t\tfinishInput( true );\r\n\t}\r\n}\r\n\r\n\r\n/***************************************************************************************************\r\n * Internal Helper Functions\r\n **************************************************************************************************/\r\n\r\n\r\nfunction startInput() {\r\n\tconst api = m_pluginApi.getApi();\r\n\r\n\t// Create unique image name for background\r\n\tconst key = `${Date.now()}_${Math.random().toString( 36 ).substring( 2, 9 )}`;\r\n\tm_inputData.backgroundImageName = `__input_bg_${key}`;\r\n\r\n\t// Capture the background image\r\n\tcaptureBackground();\r\n\r\n\t// Add input event listener\r\n\tapi.onkey( \"any\", \"down\", onInputKeyDown, false, true );\r\n\r\n\t// Add interval for blinking cursor\r\n\tm_inputData.interval = setInterval( showPrompt, 100 );\r\n}\r\n\r\nfunction captureBackground() {\r\n\tconst screenData = m_inputData.screenData;\r\n\r\n\t// Check if need to scroll first\r\n\tlet pos = screenData.api.getPos();\r\n\tif( pos.row >= screenData.api.getRows() ) {\r\n\t\tscreenData.api.print( \"\" );\r\n\t\tscreenData.api.setPos( pos.col, pos.row - 1 );\r\n\t}\r\n\t\r\n\t// Get current position to capture background region\r\n\tconst posPx = screenData.api.getPosPx();\r\n\tconst font = screenData.font;\r\n\tconst width = screenData.width;\r\n\tconst height = font.height;\r\n\r\n\t// Capture background region using createImageFromScreen\r\n\t// Capture from the pixel position until the end the screen\r\n\tconst captureWidth = width - posPx.x;\r\n\tconst captureHeight = height;\r\n\t\r\n\tscreenData.api.createImageFromScreen( {\r\n\t\t\"name\": m_inputData.backgroundImageName ,\r\n\t\t\"x1\": posPx.x,\r\n\t\t\"y1\": posPx.y,\r\n\t\t\"x2\": posPx.x + captureWidth - 1,\r\n\t\t\"y2\": posPx.y + captureHeight - 1\r\n\t} );\r\n\tm_inputData.backgroundImage = m_pluginApi.getApi().getImage( m_inputData.backgroundImageName  );\r\n\tm_inputData.captureX = posPx.x;\r\n\tm_inputData.captureY = posPx.y;\r\n\tm_inputData.captureWidth = captureWidth;\r\n\tm_inputData.captureHeight = captureHeight;\r\n}\r\n\r\nfunction onInputKeyDown( keyData ) {\r\n\r\n\t// Handle Enter Key - Complete Input\r\n\tif( keyData.key === \"Enter\" ) {\r\n\t\tfinishInput();\r\n\t\treturn;\r\n\t\r\n\t// Handle Escape - Cancel Input\r\n\t} else if( keyData.key === \"Escape\" ) {\r\n\t\tfinishInput( true );\r\n\t\treturn;\r\n\t\r\n\t// Handle Backspace - Erase last character\r\n\t} else if( keyData.key === \"Backspace\" ) {\r\n\t\tif( m_inputData.val.length > 0 ) {\r\n\t\t\tm_inputData.val = m_inputData.val.substring( 0, m_inputData.val.length - 1 );\r\n\t\t}\r\n\t\r\n\t// Handle single length keys\r\n\t} else if( keyData.key && keyData.key.length === 1 ) {\r\n\r\n\t\tlet inputHandled = false;\r\n\r\n\t\t// Handle +/- numbers\r\n\t\tif( m_inputData.isNumber && m_inputData.allowNegative ) {\r\n\r\n\t\t\t// If user enters a \"-\" then insert \"-\" at the start\r\n\t\t\tif( keyData.key === \"-\" ) {\r\n\t\t\t\tif( m_inputData.val.charAt( 0 ) !== \"-\" ) {\r\n\t\t\t\t\tm_inputData.val = \"-\" + m_inputData.val;\r\n\t\t\t\t}\r\n\t\t\t\tinputHandled = true;\r\n\t\t\t\r\n\t\t\t// Any time the user enters a \"+\" key then replace the minus symbol\r\n\t\t\t} else if(\r\n\t\t\t\t( keyData.key === \"+\" || keyData.code === \"Equal\" ) &&\r\n\t\t\t\tm_inputData.val.charAt( 0 ) === \"-\"\r\n\t\t\t) {\r\n\t\t\t\tm_inputData.val = m_inputData.val.substring( 1 );\r\n\t\t\t\tinputHandled = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Don't allow decimal points for integer number\r\n\t\tif( m_inputData.isInteger && keyData.code === \"Period\" ) {\r\n\t\t\tinputHandled = true;\r\n\t\t}\r\n\r\n\t\t// If the input is valid append the next character and validate\r\n\t\tif( !inputHandled ) {\r\n\t\t\t\r\n\t\t\t// Check maxLength before appending\r\n\t\t\tif(\r\n\t\t\t\tm_inputData.maxLength !== null && m_inputData.val.length >= m_inputData.maxLength\r\n\t\t\t) {\r\n\t\t\t\tinputHandled = true;\r\n\t\t\t} else {\r\n\t\t\t\tm_inputData.val += keyData.key;\r\n\r\n\t\t\t\t// Make sure it's a valid number or valid integer\r\n\t\t\t\tif(\r\n\t\t\t\t\t( m_inputData.isNumber && isNaN( Number( m_inputData.val ) ) ) ||\r\n\t\t\t\t\t( m_inputData.isInteger && !Number.isInteger( Number( m_inputData.val ) ) )\r\n\t\t\t\t) {\r\n\t\t\t\t\tm_inputData.val = m_inputData.val.substring( 0, m_inputData.val.length - 1 );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tshowPrompt();\r\n}\r\n\r\nfunction showPrompt( hideCursorOverride ) {\r\n\tconst screenData = m_inputData.screenData;\r\n\tlet msg = m_inputData.prompt + m_inputData.val;\r\n\r\n\t// Blink cursor after every blink duration\r\n\tif( !hideCursorOverride ) {\r\n\t\tconst now = Date.now();\r\n\t\tif( now - m_inputData.lastCursorBlink > CURSOR_BLINK ) {\r\n\t\t\tm_inputData.lastCursorBlink = now;\r\n\t\t\tm_inputData.showCursor = !m_inputData.showCursor;\r\n\t\t}\r\n\r\n\t\t// Show cursor if not hidden\r\n\t\tif( m_inputData.showCursor ) {\r\n\t\t\tmsg += m_inputData.cursor;\r\n\t\t}\r\n\t}\r\n\r\n\t// Restore the background image over the prompt area\r\n\tscreenData.api.blitImage( \r\n\t\tm_inputData.backgroundImage,\r\n\t\tm_inputData.captureX,\r\n\t\tm_inputData.captureY\r\n\t);\r\n\t\r\n\t// Get cursor position\r\n\tconst posPx = $.getPosPx();\r\n\r\n\t// Print the prompt + input + cursor\r\n\t$.setPosPx( m_inputData.captureX, m_inputData.captureY );\r\n\tscreenData.api.print( msg, true );\r\n\r\n\t// Restore the cursor\r\n\tscreenData.api.setPosPx( posPx );\r\n}\r\n\r\nfunction finishInput( isCancel ) {\r\n\tconst screenData = m_inputData.screenData;\r\n\tconst api = m_pluginApi.getApi();\r\n\r\n\t// Remove input key handler\r\n\tapi.offkey( \"any\", \"down\", onInputKeyDown, false, true );\r\n\r\n\t// Show prompt on complete, without the cursor\r\n\tshowPrompt( true );\r\n\r\n\t// Move cursor down one line\r\n\tscreenData.printCursor.y += screenData.font.height;\r\n\r\n\t// Clear the interval\r\n\tclearInterval( m_inputData.interval );\r\n\r\n\t// Process Input Value\r\n\tlet val = m_inputData.val;\r\n\tif( m_inputData.isNumber ) {\r\n\t\tif( val === \"\" || val === \"-\" ) {\r\n\t\t\tval = 0;\r\n\t\t} else {\r\n\t\t\tval = Number( val );\r\n\t\t\tif( m_inputData.isInteger ) {\r\n\t\t\t\tval = Math.floor( val );\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Clean up background image texture\r\n\tapi.removeImage( m_inputData.backgroundImageName );\r\n\t\r\n\t// Clear out the inputData\r\n\tconst tempInputData = m_inputData;\r\n\tm_inputData = null;\r\n\r\n\t// Handle cancel input\r\n\tif( isCancel ) {\r\n\t\ttempInputData.resolve( null );\r\n\r\n\t\t// Callback function\r\n\t\tif( tempInputData.fn ) {\r\n\t\t\ttempInputData.fn( null );\r\n\t\t}\r\n\t\r\n\t// Handle successful input\r\n\t} else {\r\n\t\ttempInputData.resolve( val );\r\n\r\n\t\t// Callback function\r\n\t\tif( tempInputData.fn ) {\r\n\t\t\ttempInputData.fn( val );\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Cancel all active input prompts\r\n * Called by clearKeyboardEvents\r\n * \r\n * @param {Object} [screenData] - Optional screen data to cancel input for specific screen only\r\n * @returns {void}\r\n */\r\nexport function cancelAllInputs( screenData ) {\r\n\tif( m_inputData ) {\r\n\t\tif( screenData === null || screenData === undefined ) {\r\n\r\n\t\t\t// Cancel all inputs (there can only be one active at a time)\r\n\t\t\tfinishInput( true );\r\n\t\t} else if( m_inputData.screenData === screenData ) {\r\n\r\n\t\t\t// Cancel input for specific screen\r\n\t\t\tfinishInput( true );\r\n\t\t}\r\n\t}\r\n}\r\n", "/**\n * Keyboard Plugin for Pi.js\n * \n * Provides keyboard input handling including key state tracking, event handlers,\n * and action key management.\n * \n * @module plugins/keyboard\n * @version 1.0.0\n */\n\n\"use strict\";\n\nimport { initInput, cancelAllInputs } from \"./input.js\";\n\n// Input tags that we don't want to capture\nconst INPUT_TAGS = new Set( [ \"INPUT\", \"TEXTAREA\", \"SELECT\", \"BUTTON\" ] );\n\n// Key information containers\nconst m_inCodes = {};\nconst m_inKeys = {};\nconst m_actionKeys = new Set();\nconst m_onKeyHandlers = {};\n\n// Status variables\nlet m_isKeyboardActive = false;\n\n\n/***************************************************************************************************\n * Plugin Initialization\n **************************************************************************************************/\n\n\nexport default function keyboardPlugin( pluginApi ) {\n\n\t// Initialize keyboard on plugin load\n\tstartKeyboard();\n\twindow.addEventListener( \"blur\", clearInKeys );\n\n\t// Add screen cleanup function to clear keyboard events when screen is removed\n\tpluginApi.addScreenCleanupFunction( () => {\n\t\t// Keyboard events are global, so we don't need screen-specific cleanup\n\t\t// But we can use this hook if needed in the future\n\t} );\n\n\t// Register global commands\n\tpluginApi.addCommand( \"startKeyboard\", startKeyboard, false, [] );\n\tpluginApi.addCommand( \"stopKeyboard\", stopKeyboard, false, [] );\n\tpluginApi.addCommand( \"inkey\", inkey, false, [ \"key\" ] );\n\tpluginApi.addCommand( \"setActionKeys\", setActionKeys, false, [ \"keys\" ] );\n\tpluginApi.addCommand( \"removeActionKeys\", removeActionKeys, false, [ \"keys\" ] );\n\tpluginApi.addCommand( \"onkey\", onkey, false, [ \"key\", \"mode\", \"fn\", \"once\", \"allowRepeat\" ] );\n\tpluginApi.addCommand( \"offkey\", offkey, false, [ \"key\", \"mode\", \"fn\", \"once\", \"allowRepeat\" ] );\n\n\t// Initialize input command\n\tinitInput( pluginApi );\n\n\t// Register clearEvents handler\n\tpluginApi.registerClearEvents( \"keyboard\", clearKeyboardEvents );\n}\n\n\n/***************************************************************************************************\n * External API Commands\n **************************************************************************************************/\n\n\nfunction startKeyboard() {\n\tif( m_isKeyboardActive ) {\n\t\treturn;\n\t}\n\twindow.addEventListener( \"keydown\", onKeyDown, { \"capture\": true } );\n\twindow.addEventListener( \"keyup\", onKeyUp, { \"capture\": true } );\n\tm_isKeyboardActive = true;\n\tif( document.activeElement ) {\n\t\tdocument.activeElement.blur();\n\t}\n}\n\nfunction stopKeyboard() {\n\tif( !m_isKeyboardActive ) {\n\t\treturn;\n\t}\n\twindow.removeEventListener( \"keydown\", onKeyDown, { \"capture\": true } );\n\twindow.removeEventListener( \"keyup\", onKeyUp, { \"capture\": true } );\n\tm_isKeyboardActive = false;\n\n\t// Clear keys to prevent any after effects\n\tclearInKeys();\n}\n\nfunction inkey( options ) {\n\tconst key = options.key;\n\n\tif( key ) {\n\n\t\tif( typeof key !== \"string\" ) {\n\t\t\tconst error = new TypeError( \"inkey: key must be a string.\" );\n\t\t\terror.code = \"INVALID_PARAMETERS\";\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Get key by code property\n\t\tif( m_inCodes[ key ] ) {\n\t\t\treturn m_inCodes[ key ];\n\t\t}\n\n\t\t// Get key by key property\n\t\tif( m_inKeys[ key ] ) {\n\t\t\treturn m_inKeys[ key ];\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// If inkey is blank return all key codes\n\tconst keyCodes = [];\n\tfor( const code in m_inCodes ) {\n\t\tif( m_inCodes[ code ] ) {\n\t\t\tkeyCodes.push( m_inCodes[ code ] );\n\t\t}\n\t}\n\n\treturn keyCodes;\n}\n\nfunction setActionKeys( options ) {\n\tconst keys = options.keys;\n\n\tif( !Array.isArray( keys ) ) {\n\t\tconst error = new TypeError( \"setActionKeys: keys must be an array.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\tfor( const key of keys ) {\n\t\tm_actionKeys.add( key );\n\t}\n}\n\nfunction removeActionKeys( options ) {\n\tconst keys = options.keys;\n\n\tif( !Array.isArray( keys ) ) {\n\t\tconst error = new TypeError( \"removeActionKeys: keys must be an array.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\tfor( const key of keys ) {\n\t\tm_actionKeys.delete( key );\n\t}\n}\n\nfunction onkey( options ) {\n\tconst key = options.key;\n\tconst mode = options.mode;\n\tconst fn = options.fn;\n\tconst once = !!options.once;\n\tconst allowRepeat = !!options.allowRepeat;\n\t\n\tif( !key || ( typeof key !== \"string\" && !Array.isArray( key ) ) ) {\n\t\tconst error = new TypeError( \"onkey: key must be a string or an array of strings.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\n\tif( !mode || ( typeof mode !== \"string\" ) ) {\n\t\tconst error = new TypeError( \"onkey: mode must be a string with value of up or down.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\n\tif( typeof fn !== \"function\" ) {\n\t\tconst error = new TypeError( \"onkey: fn must be a function.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\n\t// Normalize key into an array for easier processing\n\tconst combo = typeof key === \"string\" ? [ key ] : key;\n\n\tconst handler = {\n\t\t\"comboKey\": combo.sort().join( \"\" ),\n\t\t\"combo\": combo,\n\t\t\"mode\": mode,\n\t\t\"fn\": fn,\n\t\t\"once\": once,\n\t\t\"allowRepeat\": allowRepeat,\n\t\t\"isRemoved\": false\n\t};\n\t\n\t// Add a on key handler for each of the key codes - in combo all must be pressed\n\tfor( const key of combo ) {\n\t\tif( !m_onKeyHandlers[ key ] ) {\n\t\t\tm_onKeyHandlers[ key ] = [];\n\t\t}\n\t\tm_onKeyHandlers[ key ].push( handler );\n\t}\n}\n\nfunction offkey( options ) {\n\tconst key = options.key;\n\tconst mode = options.mode;\n\tconst fn = options.fn;\n\tconst once = !!options.once;\n\tconst allowRepeat = !!options.allowRepeat;\n\n\tif( !key || ( typeof key !== \"string\" && !Array.isArray( key ) ) ) {\n\t\tconst error = new TypeError( \"offkey: key must be a string or an array of strings.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\n\tif( typeof fn !== \"function\" ) {\n\t\tconst error = new TypeError( \"offkey: callback must be a function.\" );\n\t\terror.code = \"INVALID_PARAMETERS\";\n\t\tthrow error;\n\t}\n\n\t// Normalize key into an array for easier processing\n\tconst combo = typeof key === \"string\" ? [ key ] : key;\n\tconst comboKey = combo.sort().join( \"\" );\n\n\t// Find the handlers and remove them\n\tfor( const key of combo ) {\n\t\tconst handlers = m_onKeyHandlers[ key ];\n\t\tif( !handlers ) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst toRemove = [];\n\t\tfor( let i = 0; i < handlers.length; i += 1 ) {\n\t\t\tconst handler = handlers[ i ];\n\t\t\tif(\n\t\t\t\thandler.comboKey === comboKey &&\n\t\t\t\thandler.mode === mode &&\n\t\t\t\thandler.fn === fn &&\n\t\t\t\thandler.once === once &&\n\t\t\t\thandler.allowRepeat === allowRepeat\n\t\t\t) {\n\t\t\t\ttoRemove.push( i );\n\t\t\t\thandler.isRemoved = true;\n\t\t\t}\n\t\t}\n\t\tfor( let i = toRemove.length - 1; i >= 0; i -= 1 ) {\n\t\t\thandlers.splice( toRemove[ i ], 1 );\n\t\t}\n\t\tif( handlers.length === 0 ) {\n\t\t\tdelete m_onKeyHandlers[ key ];\n\t\t}\n\t}\n}\n\n\n/***************************************************************************************************\n * Internal Helper Functions\n **************************************************************************************************/\n\n\nfunction onKeyDown( event ) {\n\n\t// Ignore typing when focus is inside an editable\n\tif( isFromEditableTarget( event ) ) {\n\t\tclearInKeys();\n\t\treturn;\n\t}\n\tconst keyData = {\n\t\t\"code\": event.code,\n\t\t\"key\": event.key,\n\t\t\"location\": event.location,\n\t\t\"altKey\": event.altKey,\n\t\t\"ctrlKey\": event.ctrlKey,\n\t\t\"metaKey\": event.metaKey,\n\t\t\"shiftKey\": event.shiftKey,\n\t\t\"repeat\": event.repeat\n\t};\n\tm_inCodes[ event.code ] = keyData;\n\tm_inKeys[ event.key ] = keyData;\n\n\ttriggerKeyEventHandlers( event, \"down\", event.code );\n\tif( event.code !== event.key ) {\n\t\ttriggerKeyEventHandlers( event, \"down\", event.key );\n\t}\n\ttriggerKeyEventHandlers( event, \"down\", \"any\" );\n\tif( m_actionKeys.has( event.code ) || m_actionKeys.has( event.key ) ) {\n\t\tevent.preventDefault();\n\t}\n}\n\nfunction onKeyUp( event ) {\n\t\n\t// Ignore typing when focus is inside an editable\n\tif( isFromEditableTarget( event ) ) {\n\t\tclearInKeys();\n\t\treturn;\n\t}\n\ttriggerKeyEventHandlers( event, \"up\", event.code );\n\n\tif( event.code !== event.key ) {\n\t\ttriggerKeyEventHandlers( event, \"up\", event.key );\n\t}\n\ttriggerKeyEventHandlers( event, \"up\", \"any\" );\n\n\tdelete m_inCodes[ event.code ];\n\tdelete m_inKeys[ event.key ];\n\n\tif( m_actionKeys.has( event.code ) || m_actionKeys.has( event.key ) ) {\n\t\tevent.preventDefault();\n\t}\n}\n\nfunction triggerKeyEventHandlers( event, mode, keyOrCode ) {\n\tconst handlers = m_onKeyHandlers[ keyOrCode ];\n\tif( !handlers ) {\n\t\treturn;\n\t}\n\n\tconst isAnyKey = keyOrCode === \"any\";\n\tconst handlersCopy = handlers.slice();\n\tconst toRemove = new Set();\n\n\tfor( let i = 0; i < handlersCopy.length; i += 1 ) {\n\t\tconst handler = handlersCopy[ i ];\n\n\t\tif( handler.mode !== mode ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif( event.repeat && !handler.allowRepeat ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Need to check if handler has been removed in case a previous handler includes an offkey\n\t\tif( handler.isRemoved ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// For \"any\" key handlers, pass the current key data\n\t\tif( isAnyKey ) {\n\t\t\tlet keyData = m_inCodes[ event.code ];\n\t\t\tif( !keyData ) {\n\t\t\t\tkeyData = m_inKeys[ event.key ];\n\t\t\t}\n\n\t\t\t// In case stopKeyboard gets called in another key event handler keyData will be blank\n\t\t\tif( keyData !== undefined ) {\n\t\t\t\thandler.fn( keyData );\n\t\t\t}\n\n\t\t\tif( handler.once ) {\n\t\t\t\ttoRemove.add( handler );\n\t\t\t\thandler.isRemoved = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// For specific key handlers, check combo and pass combo data\n\t\tconst isAllKeysPressed = handler.combo.every( key => m_inKeys[ key ] || m_inCodes[ key ] );\n\n\t\tif( isAllKeysPressed ) {\n\t\t\tconst comboData = handler.combo.map( key => {\n\t\t\t\tif( m_inKeys[ key ] ) {\n\t\t\t\t\treturn m_inKeys[ key ];\n\t\t\t\t}\n\t\t\t\treturn m_inCodes[ key ];\n\t\t\t} );\n\n\t\t\tif( comboData.length === 1 ) {\n\t\t\t\thandler.fn( comboData[ 0 ] );\n\t\t\t} else {\n\t\t\t\thandler.fn( comboData );\n\t\t\t}\n\n\t\t\tif( handler.once ) {\n\t\t\t\ttoRemove.add( handler );\n\t\t\t\thandler.isRemoved = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove the handlers that are one time only calls\n\tif( toRemove.size > 0 ) {\n\t\tm_onKeyHandlers[ keyOrCode ] = handlers.filter( h => !toRemove.has( h ) );\n\t\t\n\t\t// Delete the array if empty\n\t\tif( m_onKeyHandlers[ keyOrCode ].length === 0 ) {\n\t\t\tdelete m_onKeyHandlers[ keyOrCode ];\n\t\t}\n\t}\n}\n\nfunction isFromEditableTarget ( event ) {\n\tconst element = event.target;\n\tif( !element ) {\n\t\treturn false;\n\t}\n\n\t// Standard form controls\n\tif( INPUT_TAGS.has( element.tagName ) ) {\n\t\treturn true;\n\t}\n\n\t// Contenteditable\n\tif( element.isContentEditable ) {\n\t\treturn true;\n\t}\n\n\t// Inputs inside shadow roots\n\tconst role = element.getAttribute && element.getAttribute( \"role\" );\n\tif( role === \"textbox\" || role === \"searchbox\" ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nfunction clearInKeys() {\n\n\t// Clear all key states\n\tfor( const code in m_inCodes ) {\n\t\tdelete m_inCodes[ code ];\n\t}\n\tfor( const key in m_inKeys ) {\n\t\tdelete m_inKeys[ key ];\n\t}\n}\n\n\n/***************************************************************************************************\n * Module Exports for Other Modules\n **************************************************************************************************/\n\n\n/**\n * Clear all keyboard event handlers\n * Called by clearEvents command and exported for use by other modules\n * \n * @param {Object} [screenData] - Screen data to clear events for specific screen\n * @returns {void}\n */\nexport function clearKeyboardEvents( screenData ) {\n\t\n\t// Clear all keyboard event handlers\n\tfor( const mode in m_onKeyHandlers ) {\n\t\tdelete m_onKeyHandlers[ mode ];\n\t}\n\t\n\t// Cancel all active input prompts\n\tcancelAllInputs( screenData );\n}\n\n\n// Auto-register in IIFE mode (when loaded via <script> tag)\nif( typeof window !== \"undefined\" && window.pi ) {\n\twindow.pi.registerPlugin( {\n\t\t\"name\": \"keyboard\",\n\t\t\"version\": \"1.0.0\",\n\t\t\"description\": \"Keyboard input handling for Pi.js\",\n\t\t\"init\": keyboardPlugin\n\t} );\n}\n\n"],
  "mappings": "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",
  "names": ["m_inputData", "m_pluginApi", "initInput", "pluginApi", "input", "cancelInput", "screenData", "options", "prompt", "fn", "cursor", "isNumber", "isInteger", "allowNegative", "maxLength", "error", "resolvePromise", "rejectPromise", "promise", "resolve", "reject", "finishInput", "startInput", "api", "key", "captureBackground", "onInputKeyDown", "showPrompt", "pos", "posPx", "font", "width", "height", "captureWidth", "captureHeight", "keyData", "inputHandled", "hideCursorOverride", "msg", "now", "isCancel", "val", "tempInputData", "cancelAllInputs", "INPUT_TAGS", "m_inCodes", "m_inKeys", "m_actionKeys", "m_onKeyHandlers", "m_isKeyboardActive", "keyboardPlugin", "pluginApi", "startKeyboard", "clearInKeys", "stopKeyboard", "inkey", "setActionKeys", "removeActionKeys", "onkey", "offkey", "initInput", "clearKeyboardEvents", "onKeyDown", "onKeyUp", "options", "key", "error", "keyCodes", "code", "keys", "mode", "fn", "once", "allowRepeat", "combo", "handler", "comboKey", "handlers", "toRemove", "i", "event", "isFromEditableTarget", "keyData", "triggerKeyEventHandlers", "keyOrCode", "isAnyKey", "handlersCopy", "comboData", "h", "element", "role", "screenData", "cancelAllInputs"]
}
