2018-02-12 16:01:20 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
|
|
* @copyright 2018 Photon Storm Ltd.
|
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
var Class = require('../../utils/Class');
|
2018-01-12 17:09:09 +00:00
|
|
|
var EventEmitter = require('eventemitter3');
|
2017-02-21 16:05:36 +00:00
|
|
|
var Key = require('./keys/Key');
|
2017-06-30 14:47:51 +00:00
|
|
|
var KeyCodes = require('./keys/KeyCodes');
|
2017-02-21 16:52:40 +00:00
|
|
|
var KeyCombo = require('./combo/KeyCombo');
|
2018-01-23 14:37:23 +00:00
|
|
|
var KeyMap = require('./keys/KeyMap');
|
2017-02-21 16:05:36 +00:00
|
|
|
var ProcessKeyDown = require('./keys/ProcessKeyDown');
|
|
|
|
var ProcessKeyUp = require('./keys/ProcessKeyUp');
|
|
|
|
|
2018-02-07 15:27:21 +00:00
|
|
|
/**
|
|
|
|
* @classdesc
|
|
|
|
* The Keyboard class monitors keyboard input and dispatches keyboard events.
|
|
|
|
*
|
|
|
|
* _Note_: many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting.
|
|
|
|
* See http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/ for more details.
|
|
|
|
*
|
|
|
|
* Also please be aware that certain browser extensions can disable or override Phaser keyboard handling.
|
|
|
|
* For example the Chrome extension vimium is known to disable Phaser from using the D key. And there are others.
|
|
|
|
* So please check your extensions before opening Phaser issues.
|
|
|
|
*
|
|
|
|
* @class KeyboardManager
|
2018-02-13 01:13:12 +00:00
|
|
|
* @extends EventEmitter
|
2018-02-07 15:27:21 +00:00
|
|
|
* @memberOf Phaser.Input.Keyboard
|
|
|
|
* @constructor
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @param {Phaser.Input.InputManager} inputManager - [description]
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
var KeyboardManager = new Class({
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2018-01-12 17:09:09 +00:00
|
|
|
Extends: EventEmitter,
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
initialize:
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
function KeyboardManager (inputManager)
|
|
|
|
{
|
2018-01-12 17:09:09 +00:00
|
|
|
EventEmitter.call(this);
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#manager
|
|
|
|
* @type {Phaser.Input.InputManager}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-01-12 17:09:09 +00:00
|
|
|
this.manager = inputManager;
|
2017-09-27 16:04:39 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#enabled
|
|
|
|
* @type {boolean}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @default false
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.enabled = false;
|
2017-02-21 16:52:40 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#target
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {?object}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.target;
|
2017-02-24 01:45:15 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#keys
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {Phaser.Input.Keyboard.Key[]}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.keys = [];
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#combos
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {Phaser.Input.Keyboard.KeyCombo[]}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.combos = [];
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#captures
|
|
|
|
* @type {array}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.captures = [];
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#queue
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {KeyboardEvent[]}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.queue = [];
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.Keyboard.KeyboardManager#handler
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {?function}
|
2018-01-26 12:43:34 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.handler;
|
|
|
|
},
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
/**
|
2018-01-26 12:43:34 +00:00
|
|
|
* The Boot handler is called by Phaser.Game when it first starts up.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#boot
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-02-21 01:04:11 +00:00
|
|
|
boot: function ()
|
|
|
|
{
|
2017-06-30 14:47:51 +00:00
|
|
|
var config = this.manager.config;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
this.enabled = config.inputKeyboard;
|
|
|
|
this.target = config.inputKeyboardEventTarget;
|
|
|
|
|
|
|
|
if (this.enabled)
|
|
|
|
{
|
|
|
|
this.startListeners();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#startListeners
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-02-21 01:04:11 +00:00
|
|
|
startListeners: function ()
|
|
|
|
{
|
|
|
|
var queue = this.queue;
|
2017-02-24 01:45:15 +00:00
|
|
|
var captures = this.captures;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-14 00:20:01 +00:00
|
|
|
var handler = function (event)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2018-01-03 16:30:51 +00:00
|
|
|
if (event.defaultPrevented)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
|
|
|
// Do nothing if event already handled
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
queue.push(event);
|
2017-02-24 01:45:15 +00:00
|
|
|
|
|
|
|
if (captures[event.keyCode])
|
|
|
|
{
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
2017-02-21 01:04:11 +00:00
|
|
|
};
|
|
|
|
|
2017-06-14 00:20:01 +00:00
|
|
|
this.handler = handler;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-14 00:20:01 +00:00
|
|
|
this.target.addEventListener('keydown', handler, false);
|
|
|
|
this.target.addEventListener('keyup', handler, false);
|
2017-02-21 01:04:11 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#stopListeners
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-02-21 01:04:11 +00:00
|
|
|
stopListeners: function ()
|
|
|
|
{
|
2017-06-14 00:20:01 +00:00
|
|
|
this.target.removeEventListener('keydown', this.handler);
|
|
|
|
this.target.removeEventListener('keyup', this.handler);
|
2017-02-21 01:04:11 +00:00
|
|
|
},
|
|
|
|
|
2017-02-21 16:05:36 +00:00
|
|
|
/**
|
2018-01-26 12:43:34 +00:00
|
|
|
* Creates and returns an object containing 4 hotkeys for Up, Down, Left and Right, and also space and shift.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#createCursorKeys
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @return {object} [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-21 16:05:36 +00:00
|
|
|
createCursorKeys: function ()
|
|
|
|
{
|
|
|
|
return this.addKeys({
|
|
|
|
up: KeyCodes.UP,
|
|
|
|
down: KeyCodes.DOWN,
|
|
|
|
left: KeyCodes.LEFT,
|
2017-09-16 02:08:09 +00:00
|
|
|
right: KeyCodes.RIGHT,
|
|
|
|
space: KeyCodes.SPACE,
|
|
|
|
shift: KeyCodes.SHIFT
|
2017-02-21 16:05:36 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-01-26 12:43:34 +00:00
|
|
|
* A practical way to create an object containing user selected hotkeys.
|
|
|
|
*
|
|
|
|
* For example,
|
|
|
|
*
|
|
|
|
* addKeys( { 'up': Phaser.KeyCode.W, 'down': Phaser.KeyCode.S, 'left': Phaser.KeyCode.A, 'right': Phaser.KeyCode.D } );
|
|
|
|
*
|
|
|
|
* would return an object containing properties (`up`, `down`, `left` and `right`) referring to {@link Phaser.Key} object.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#addKeys
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @param {object} keys - [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @return {object} [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-21 16:05:36 +00:00
|
|
|
addKeys: function (keys)
|
|
|
|
{
|
|
|
|
var output = {};
|
|
|
|
|
|
|
|
for (var key in keys)
|
|
|
|
{
|
|
|
|
output[key] = this.addKey(keys[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
},
|
|
|
|
|
2017-02-21 01:04:11 +00:00
|
|
|
/**
|
2018-01-26 12:43:34 +00:00
|
|
|
* If you need more fine-grained control over a Key you can create a new Phaser.Key object via this method.
|
|
|
|
* The Key object can then be polled, have events attached to it, etc.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#addKey
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @param {string|integer} keyCode - [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @return {Phaser.Input.Keyboard.Key} [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-21 16:52:40 +00:00
|
|
|
addKey: function (keyCode)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-21 16:52:40 +00:00
|
|
|
var keys = this.keys;
|
|
|
|
|
|
|
|
if (!keys[keyCode])
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-21 16:52:40 +00:00
|
|
|
keys[keyCode] = new Key(keyCode);
|
2017-02-24 01:45:15 +00:00
|
|
|
this.captures[keyCode] = true;
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 16:52:40 +00:00
|
|
|
return keys[keyCode];
|
2017-02-21 01:04:11 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-01-26 12:43:34 +00:00
|
|
|
* Removes a Key object from the Keyboard manager.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#removeKey
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @param {string|integer} keyCode - [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-24 01:45:15 +00:00
|
|
|
removeKey: function (keyCode)
|
|
|
|
{
|
|
|
|
if (this.keys[keyCode])
|
|
|
|
{
|
|
|
|
this.keys[keyCode] = undefined;
|
|
|
|
this.captures[keyCode] = false;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#addKeyCapture
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @param {string|integer|string[]|integer[]} keyCodes - [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-24 01:45:15 +00:00
|
|
|
addKeyCapture: function (keyCodes)
|
|
|
|
{
|
|
|
|
if (!Array.isArray(keyCodes))
|
|
|
|
{
|
|
|
|
keyCodes = [ keyCodes ];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < keyCodes.length; i++)
|
|
|
|
{
|
|
|
|
this.captures[keyCodes[i]] = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#removeKeyCapture
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @param {string|integer|string[]|integer[]} keyCodes - [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-24 01:45:15 +00:00
|
|
|
removeKeyCapture: function (keyCodes)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-24 01:45:15 +00:00
|
|
|
if (!Array.isArray(keyCodes))
|
|
|
|
{
|
|
|
|
keyCodes = [ keyCodes ];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < keyCodes.length; i++)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-24 01:45:15 +00:00
|
|
|
this.captures[keyCodes[i]] = false;
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#createCombo
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @param {string|integer[]|object[]} keys - [description]
|
|
|
|
* @param {object} config - [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*
|
2018-03-19 12:43:19 +00:00
|
|
|
* @return {Phaser.Input.Keyboard.KeyCombo} [description]
|
2018-01-26 12:43:34 +00:00
|
|
|
*/
|
2017-02-21 23:01:05 +00:00
|
|
|
createCombo: function (keys, config)
|
2017-02-21 16:52:40 +00:00
|
|
|
{
|
2017-02-21 23:01:05 +00:00
|
|
|
return new KeyCombo(this, keys, config);
|
2017-02-21 16:52:40 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#update
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-02-21 01:04:11 +00:00
|
|
|
update: function ()
|
|
|
|
{
|
2017-06-12 23:38:48 +00:00
|
|
|
var len = this.queue.length;
|
|
|
|
|
|
|
|
if (!this.enabled || len === 0)
|
2017-02-21 16:05:36 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clears the queue array, and also means we don't work on array data that could potentially
|
|
|
|
// be modified during the processing phase
|
2017-06-12 23:38:48 +00:00
|
|
|
var queue = this.queue.splice(0, len);
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
var keys = this.keys;
|
|
|
|
|
2017-02-21 16:05:36 +00:00
|
|
|
// Process the event queue, dispatching all of the events that have stored up
|
2017-06-12 23:38:48 +00:00
|
|
|
for (var i = 0; i < len; i++)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
|
|
|
var event = queue[i];
|
2018-01-23 14:37:23 +00:00
|
|
|
var code = event.keyCode;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
if (event.type === 'keydown')
|
|
|
|
{
|
2018-02-25 13:16:05 +00:00
|
|
|
if (KeyMap[code] && (keys[code] === undefined || keys[code].isDown === false))
|
2018-01-23 14:37:23 +00:00
|
|
|
{
|
2018-02-24 10:20:36 +00:00
|
|
|
// Will emit a keyboard or keyup event
|
|
|
|
this.emit(event.type, event);
|
|
|
|
|
2018-01-23 14:37:23 +00:00
|
|
|
this.emit('keydown_' + KeyMap[code], event);
|
|
|
|
}
|
2017-02-21 16:05:36 +00:00
|
|
|
|
2018-02-25 13:03:58 +00:00
|
|
|
if (keys[code])
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2018-01-23 14:37:23 +00:00
|
|
|
ProcessKeyDown(keys[code], event);
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-24 10:20:36 +00:00
|
|
|
// Will emit a keyboard or keyup event
|
|
|
|
this.emit(event.type, event);
|
|
|
|
|
2018-01-23 14:37:23 +00:00
|
|
|
this.emit('keyup_' + KeyMap[code], event);
|
2017-02-21 16:05:36 +00:00
|
|
|
|
2018-01-23 14:37:23 +00:00
|
|
|
if (keys[code])
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2018-01-23 14:37:23 +00:00
|
|
|
ProcessKeyUp(keys[code], event);
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-12 17:09:09 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#shutdown
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-01-12 17:09:09 +00:00
|
|
|
shutdown: function ()
|
|
|
|
{
|
|
|
|
this.removeAllListeners();
|
|
|
|
},
|
|
|
|
|
2018-01-26 12:43:34 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.Keyboard.KeyboardManager#destroy
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-01-12 17:09:09 +00:00
|
|
|
destroy: function ()
|
|
|
|
{
|
|
|
|
this.stopListeners();
|
|
|
|
|
|
|
|
this.removeAllListeners();
|
|
|
|
|
|
|
|
this.keys = [];
|
|
|
|
this.combos = [];
|
|
|
|
this.captures = [];
|
|
|
|
this.queue = [];
|
|
|
|
this.handler = undefined;
|
2018-01-31 03:38:10 +00:00
|
|
|
|
|
|
|
this.manager = null;
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
});
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
module.exports = KeyboardManager;
|