text: L.Map.mergeOptions({
  	keyboard: true,
  	keyboardPanOffset: 80,
  	keyboardZoomOffset: 1
  });
  
  L.Map.Keyboard = L.Handler.extend({
  
  	// list of e.keyCode values for particular actions
  	keyCodes: {
  		left:    [37],
  		right:   [39],
  		down:    [40],
  		up:      [38],
  		zoomIn:  [187, 107, 61],
  		zoomOut: [189, 109]
  	},
  
  	initialize: function (map) {
  		this._map = map;
  
  		this._setPanOffset(map.options.keyboardPanOffset);
  		this._setZoomOffset(map.options.keyboardZoomOffset);
  	},
  
  	addHooks: function () {
  		var container = this._map._container;
  
  		// make the container focusable by tabbing
  		if (container.tabIndex === -1) {
  			container.tabIndex = "0";
  		}
  
  		L.DomEvent
  		    .addListener(container, 'focus', this._onFocus, this)
  		    .addListener(container, 'blur', this._onBlur, this)
  		    .addListener(container, 'mousedown', this._onMouseDown, this);
  
  		this._map
  		    .on('focus', this._addHooks, this)
  		    .on('blur', this._removeHooks, this);
  	},
  
  	removeHooks: function () {
  		this._removeHooks();
  
  		var container = this._map._container;
  
  		L.DomEvent
  		    .removeListener(container, 'focus', this._onFocus, this)
  		    .removeListener(container, 'blur', this._onBlur, this)
  		    .removeListener(container, 'mousedown', this._onMouseDown, this);
  
  		this._map
  		    .off('focus', this._addHooks, this)
  		    .off('blur', this._removeHooks, this);
  	},
  
  	_onMouseDown: function () {
  		if (!this._focused) {
  			this._map._container.focus();
  		}
  	},
  
  	_onFocus: function () {
  		this._focused = true;
  		this._map.fire('focus');
  	},
  
  	_onBlur: function () {
  		this._focused = false;
  		this._map.fire('blur');
  	},
  
  	_setPanOffset: function (pan) {
  		var keys = this._panKeys = {},
  		    codes = this.keyCodes,
  		    i, len;
  
  		for (i = 0, len = codes.left.length; i < len; i++) {
  			keys[codes.left[i]] = [-1 * pan, 0];
  		}
  		for (i = 0, len = codes.right.length; i < len; i++) {
  			keys[codes.right[i]] = [pan, 0];
  		}
  		for (i = 0, len = codes.down.length; i < len; i++) {
  			keys[codes.down[i]] = [0, pan];
  		}
  		for (i = 0, len = codes.up.length; i < len; i++) {
  			keys[codes.up[i]] = [0, -1 * pan];
  		}
  	},
  
  	_setZoomOffset: function (zoom) {
  		var keys = this._zoomKeys = {},
  		    codes = this.keyCodes,
  		    i, len;
  
  		for (i = 0, len = codes.zoomIn.length; i < len; i++) {
  			keys[codes.zoomIn[i]] = zoom;
  		}
  		for (i = 0, len = codes.zoomOut.length; i < len; i++) {
  			keys[codes.zoomOut[i]] = -zoom;
  		}
  	},
  
  	_addHooks: function () {
  		L.DomEvent.addListener(document, 'keydown', this._onKeyDown, this);
  	},
  
  	_removeHooks: function () {
  		L.DomEvent.removeListener(document, 'keydown', this._onKeyDown, this);
  	},
  
  	_onKeyDown: function (e) {
  		var key = e.keyCode;
  
  		if (this._panKeys.hasOwnProperty(key)) {
  			this._map.panBy(this._panKeys[key]);
  
  		} else if (this._zoomKeys.hasOwnProperty(key)) {
  			this._map.setZoom(this._map.getZoom() + this._zoomKeys[key]);
  
  		} else {
  			return;
  		}
  
  		L.DomEvent.stop(e);
  	}
  });
  
  L.Map.addInitHook('addHandler', 'keyboard', L.Map.Keyboard);
  